This repository has been archived on 2020-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
Files
IndoorMap/mapview/Scaler.h
2016-05-24 16:55:19 +02:00

105 lines
2.8 KiB
C++

#ifndef SCALER_H
#define SCALER_H
#include <Indoor/geo/Point3.h>
#include <QRectF>
struct Rect {
float x0;
float y0;
float x1;
float y1;
};
/**
* - scale between map- and screen-space.
* - inverts y-axis (for openGL)
*/
class Scaler {
private:
int w;
int h;
float _scale = 50;
float _snap = 0.1;
Point3 _offset;
public:
/** map->screen (no offset) */
float ms(const float m) const {return m*_scale;}
/** x map->screen */
float xms(const float x) const {return w/2+(x+_offset.x)*_scale;}
/** x map->screen */
float yms(const float y) const {return h/2-(y-_offset.y)*_scale;}
/** screen->map (no offset) */
float sm(const float s) const {return (s/_scale);}
/** x screen->map */
float xsm(const float x) const {return ((x-w/2)/_scale)-_offset.x;}
/** y screen->map */
float ysm(const float y) const {return ((h/2-y)/_scale)+_offset.y;}
void setScale(const float s) {_scale = s;}
float getScale() const {return _scale;}
void setOffset(Point3 p) {_offset = p;}
Point3 getOffset() const {return _offset;}
void addOffset(int px, int py) {_offset.x += sm(px); _offset.y += sm(py);}
float getLODstep() const {
float step = 0.01;
if (_scale <= 1000) {step = 0.1;}
if (_scale <= 500) {step = 0.5;}
if (_scale <= 100) {step = 1.0;}
if (_scale <= 50) {step = 5.0;}
if (_scale <= 10) {step = 10.0;}
if (_scale <= 1) {step = 100.0;}
return step;
}
/** get the currently visible map-region given the provided screen-size */
Rect getMapVisible(const int screenW, const int screenH) const {
Rect r;
r.x0 = xsm(0);
r.x1 = xsm(screenW);
r.y0 = ysm(screenH);
r.y1 = ysm(0);
return r;
}
/** get the currently visible map-region given the provided screen-size, SNAPED to the given grid-size */
Rect getMapVisible(const int screenW, const int screenH, const float mapGridSize) const {
Rect r = getMapVisible(screenW, screenH);
r.x0 = snapFloor(r.x0, mapGridSize);
r.y0 = snapFloor(r.y0, mapGridSize);
r.x1 = snapCeil(r.x1, mapGridSize);
r.y1 = snapCeil(r.y1, mapGridSize);
return r;
}
//Point2 getOffset() const {return _offset.xy();}
Point2 getCenter() const {return Point2(-_offset.x, _offset.y);}
void setScreenSize(const int w, const int h) {this->w = w; this->h = h;}
public:
static float snap(const float v, const float grid) { return std::round(v/grid)*grid; }
static Point2 snap(const Point2 p, const float grid) { return Point2(snap(p.x, grid), snap(p.y, grid)); }
static Point3 snap(const Point3 p, const float grid) { return Point3(snap(p.x, grid), snap(p.y, grid), snap(p.z, grid)); }
static float snapCeil(const float v, const float grid) { return std::ceil(v/grid) * grid; }
static float snapFloor(const float v, const float grid) { return std::floor(v/grid) * grid; }
//float snap(const float v) const { return v; }
};
#endif // SCALER_H