1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#pragma once
#include "point2d.hpp"
#include "rect2d.hpp"
#include "any_rect2d.hpp"
#include "../base/math.hpp"
#include "../base/start_mem_debug.hpp"
enum EOrientation
{
EOrientation0,
EOrientation90,
EOrientation180,
EOrientation270
};
class ScreenBase
{
m2::RectD m_PixelRect;
double m_Scale;
ang::AngleD m_Angle;
m2::PointD m_Org;
protected:
/// @group Dependent parameters
/// Global to Pixel conversion matrix.
/// |a11 a12 0|
/// |x, y, 1| * |a21 a22 0| = |x', y', 1|
/// |a31 a32 1|
/// @{
math::Matrix<double, 3, 3> m_GtoP;
/// Pixel to Global conversion matrix. Inverted GtoP matrix.
math::Matrix<double, 3, 3> m_PtoG;
/// Global Rect
m2::AnyRectD m_GlobalRect;
/// X-axis aligned global rect used for clipping
m2::RectD m_ClipRect;
/// @}
// Update dependent parameters from base parameters.
// Must be called when base parameters changed.
void UpdateDependentParameters();
public:
ScreenBase();
ScreenBase(m2::RectI const & pxRect, m2::AnyRectD const & glbRect);
void SetFromRect(m2::AnyRectD const & rect);
void SetOrg(m2::PointD const & p);
void Move(double dx, double dy);
void MoveG(m2::PointD const & p);
void Scale(double scale);
void Rotate(double angle);
void OnSize(m2::RectI const & r);
void OnSize(int x0, int y0, int w, int h);
public:
double GetScale() const;
double GetAngle() const;
int GetWidth() const;
int GetHeight() const;
inline m2::PointD GtoP(m2::PointD const & pt) const
{
return pt * m_GtoP;
}
inline m2::PointD PtoG(m2::PointD const & pt) const
{
return pt * m_PtoG;
}
inline void GtoP(double & x, double & y) const
{
double tempX = x;
x = tempX * m_GtoP(0, 0) + y * m_GtoP(1, 0) + m_GtoP(2, 0);
y = tempX * m_GtoP(1, 0) + y * m_GtoP(1, 1) + m_GtoP(2, 1);
}
inline void PtoG(double & x, double & y) const
{
double tempX = x;
x = tempX * m_PtoG(0, 0) + y * m_PtoG(1, 0) + m_PtoG(2, 0);
y = tempX * m_PtoG(0, 1) + y * m_PtoG(1, 1) + m_PtoG(2, 1);
}
void GtoP(m2::RectD const & gr, m2::RectD & sr) const;
void PtoG(m2::RectD const & pr, m2::RectD & gr) const;
math::Matrix<double, 3, 3> const & GtoPMatrix() const;
math::Matrix<double, 3, 3> const & PtoGMatrix() const;
m2::RectD const & PixelRect() const;
m2::AnyRectD const & GlobalRect() const;
m2::RectD const & ClipRect() const;
/// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1, newPt2)
static math::Matrix<double, 3, 3> const CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2,
m2::PointD const & newPt1, m2::PointD const & newPt2);
/// Setting GtoP matrix extracts the Angle and m_Org parameters, leaving PixelRect intact
void SetGtoPMatrix(math::Matrix<double, 3, 3> const & m);
/// Extracting parameters from matrix, that is supposed to represent GtoP transformation
static void ExtractGtoPParams(math::Matrix<double, 3, 3> const & m, double & a, double & s, double & dx, double & dy);
bool operator != (ScreenBase const & src) const
{
return !(*this == src);
}
bool operator == (ScreenBase const & src) const
{
return (m_GtoP == src.m_GtoP) && (m_PtoG == src.m_PtoG);
}
};
/// checking whether the s1 transforms into s2 without scaling, only with shift and rotation
bool IsPanningAndRotate(ScreenBase const & s1, ScreenBase const & s2);
#include "../base/stop_mem_debug.hpp"
|