Welcome to mirror list, hosted at ThFree Co, Russian Federation.

screenbase.hpp « geometry - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c0d462a90f566656400d3abbad027acec0dfabc6 (plain)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#pragma once

#include "geometry/point2d.hpp"
#include "geometry/rect2d.hpp"
#include "geometry/any_rect2d.hpp"

#include "base/matrix.hpp"


class ScreenBase
{
public:
  using MatrixT = math::Matrix<double, 3, 3>;
  using Matrix3dT = math::Matrix<double, 4, 4>;
  using Vector3dT = math::Matrix<double, 1, 4>;

private:
  m2::RectD m_ViewportRect;
  m2::RectD m_PixelRect;

  double m_Scale;
  ang::AngleD m_Angle;
  m2::PointD m_Org;

  double m_3dFOV;
  double m_3dNearZ;
  double m_3dFarZ;
  double m_3dAngleX;
  double m_3dMaxAngleX;
  double m_3dScale;
  bool m_isPerspective;
  bool m_isAutoPerspective;

protected:
  /// @group Dependent parameters
  /// Global to Pixel conversion matrix.
  ///             |a11 a12 0|
  /// |x, y, 1| * |a21 a22 0| = |x', y', 1|
  ///             |a31 a32 1|
  /// @{
  MatrixT m_GtoP;

  /// Pixel to Global conversion matrix. Inverted GtoP matrix.
  MatrixT m_PtoG;

  /// Global Rect
  m2::AnyRectD m_GlobalRect;

  /// X-axis aligned global rect used for clipping
  m2::RectD m_ClipRect;

  /// @}

  Matrix3dT m_Pto3d;
  Matrix3dT m_3dtoP;

  // 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);
  ScreenBase(ScreenBase const & s,
             m2::PointD const & org, double scale, double angle);

  void SetFromRect(m2::AnyRectD const & rect);

  void SetFromParams(m2::PointD const & org, double angle, double scale);
  void SetFromRects(m2::AnyRectD const & glbRect, m2::RectD const & pxRect);
  void SetOrg(m2::PointD const & p);

  void Move(double dx, double dy);
  void MoveG(m2::PointD const & p);

  /// scale global rect
  void Scale(double scale);
  void Rotate(double angle);

  void OnSize(m2::RectI const & r);
  void OnSize(int x0, int y0, int w, int h);

  double GetScale() const { return m_Scale; }
  void SetScale(double scale);

  double GetAngle() const { return m_Angle.val(); }
  void SetAngle(double angle);

  m2::PointD const & GetOrg() const { return m_Org; }

  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;

  void MatchGandP(m2::PointD const & g, m2::PointD const & p);
  void MatchGandP3d(m2::PointD const & g, m2::PointD const & p3d);

  void GetTouchRect(m2::PointD const & pixPoint, double pixRadius, m2::AnyRectD & glbRect) const;
  void GetTouchRect(m2::PointD const & pixPoint, double const pxWidth,
                    double const pxHeight, m2::AnyRectD & glbRect) const;

  MatrixT const & GtoPMatrix() const { return m_GtoP; }
  MatrixT const & PtoGMatrix() const { return m_PtoG; }

  m2::RectD const & PixelRect() const { return m_PixelRect; }
  m2::AnyRectD const & GlobalRect() const { return m_GlobalRect; }
  m2::RectD const & ClipRect() const { return m_ClipRect; }

  void ApplyPerspective(double currentRotationAngle, double maxRotationAngle, double angleFOV);
  void ResetPerspective();

  void SetRotationAngle(double rotationAngle);
  double GetRotationAngle() const { return m_3dAngleX; }
  double GetMaxRotationAngle() const { return m_3dMaxAngleX; }
  double GetAngleFOV() const { return m_3dFOV; }
  double GetScale3d() const { return m_3dScale; }
  double GetZScale() const;

  double GetDepth3d() const { return m_3dFarZ - m_3dNearZ; }

  m2::PointD P3dtoP(m2::PointD const & pt) const;

  Matrix3dT const & Pto3dMatrix() const { return m_Pto3d; }
  bool isPerspective() const { return m_isPerspective; }
  bool isAutoPerspective() const { return m_isAutoPerspective; }
  void SetAutoPerspective(bool isAutoPerspective);

  bool IsReverseProjection3d(m2::PointD const & pt) const;

  m2::PointD PtoP3d(m2::PointD const & pt) const;
  m2::PointD PtoP3d(m2::PointD const & pt, double ptZ) const;

  m2::RectD const & PixelRectIn3d() const
  {
    return m_ViewportRect;
  }

  double CalculateScale3d(double rotationAngle) const;
  m2::RectD CalculatePixelRect(double scale) const;
  double CalculatePerspectiveAngle(double scale) const;

  Matrix3dT GetModelView() const;
  Matrix3dT GetModelView(m2::PointD const & pivot, double scalar) const;

  static double CalculateAutoPerspectiveAngle(double scale);

  /// Compute arbitrary pixel transformation, that translates the (oldPt1, oldPt2) -> (newPt1, newPt2)
  static MatrixT const CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2,
                                     m2::PointD const & newPt1, m2::PointD const & newPt2,
                                     bool allowRotate);


  /// Setting GtoP matrix extracts the Angle and m_Org parameters, leaving PixelRect intact
  void SetGtoPMatrix(MatrixT const & m);

  /// Extracting parameters from matrix, that is supposed to represent GtoP transformation
  static void ExtractGtoPParams(MatrixT 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);