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/2D/Scaler.h
2018-10-25 12:23:40 +02:00

131 lines
3.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* © 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