131 lines
3.6 KiB
C++
131 lines
3.6 KiB
C++
/*
|
||
* © Copyright 2014 – Urheberrechtshinweis
|
||
* Alle Rechte vorbehalten / All Rights Reserved
|
||
*
|
||
* Programmcode ist urheberrechtlich geschuetzt.
|
||
* Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner.
|
||
* Keine Verwendung ohne explizite Genehmigung.
|
||
* (vgl. § 106 ff UrhG / § 97 UrhG)
|
||
*/
|
||
|
||
#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;}
|
||
/** x,y screen->map */
|
||
Point2 sm(const Point2 p) const {return Point2(xsm(p.x), ysm(p.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:
|
||
|
||
float majorGridLineStep() const {return 1.0f * getLODstep();}
|
||
float minorGridLineStep() const {return majorGridLineStep() / 5.0f;}
|
||
|
||
/** snap everything to minor grid lines */
|
||
float snap(const float v) const { return snap(v, minorGridLineStep()); }
|
||
|
||
Point2 snap(const Point2 p) const { return Point2(snap(p.x), snap(p.y)); }
|
||
Point3 snap(const Point3 p) const { return Point3(snap(p.x), snap(p.y), snap(p.z)); }
|
||
|
||
|
||
private:
|
||
|
||
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)); }
|
||
//tatic 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
|
||
|
||
|