diff options
author | rachytski <siarhei.rachytski@gmail.com> | 2011-10-03 14:31:37 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:25:21 +0300 |
commit | fd3a3a6d0fc3aeab9e7b0c4724d614dc587cb0ee (patch) | |
tree | 0c872119ff85927af83ec5919beea786832ba961 /geometry/screenbase.cpp | |
parent | 31279661079d1426c2dac1971fb5bce6d086be32 (diff) |
refactored ScreenBase to support GUI rotation.
Diffstat (limited to 'geometry/screenbase.cpp')
-rw-r--r-- | geometry/screenbase.cpp | 143 |
1 files changed, 98 insertions, 45 deletions
diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index acabce0e17..bdbaa65c44 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -10,16 +10,17 @@ ScreenBase::ScreenBase() : m_PixelRect(0, 0, 640, 480), - m_GlobalRect(0, 0, 640, 480), m_Scale(1), - m_Angle(0.0) + m_Angle(0.0), + m_Org(320, 240), + m_GlobalRect(m2::RectD(0, 0, 640, 480)) { m_GtoP = math::Identity<double, 3>(); m_PtoG = math::Identity<double, 3>(); // UpdateDependentParameters(); } -ScreenBase::ScreenBase(m2::RectI const & pxRect, m2::RectD const & glbRect) +ScreenBase::ScreenBase(m2::RectI const & pxRect, m2::AARectD const & glbRect) { OnSize(pxRect); SetFromRect(glbRect); @@ -41,71 +42,119 @@ void ScreenBase::UpdateDependentParameters() m_Scale, m_Scale ), - GetAngle() + m_Angle.cos(), + m_Angle.sin() ), - m_GlobalRect.Center() + m_Org ); m_GtoP = math::Inverse(m_PtoG); - PtoG(m_PixelRect, m_ClipRect); - PtoG(m_PixelRect, m_GlobalRect); + double HalfSizeX = PtoG(m2::PointD(m_PixelRect.maxX(), m_PixelRect.Center().y)).Length(PtoG(m2::PointD(m_PixelRect.Center()))); + double HalfSizeY = PtoG(m2::PointD(m_PixelRect.Center().x, m_PixelRect.minY())).Length(PtoG(m2::PointD(m_PixelRect.Center()))); + + m_GlobalRect = m2::AARectD(m_Org, m_Angle, m2::RectD(-HalfSizeX, -HalfSizeY, HalfSizeX, HalfSizeY)); + m_ClipRect = m_GlobalRect.GetGlobalRect(); } -void ScreenBase::SetFromRect(m2::RectD const & GlobalRect) +void ScreenBase::SetFromRect(m2::AARectD const & GlobalRect) { - double hScale = GlobalRect.SizeX() / m_PixelRect.SizeX(); - double vScale = GlobalRect.SizeY() / m_PixelRect.SizeY(); + double hScale = GlobalRect.GetLocalRect().SizeX() / m_PixelRect.SizeX(); + double vScale = GlobalRect.GetLocalRect().SizeY() / m_PixelRect.SizeY(); m_Scale = max(hScale, vScale); - m_Angle = 0; - - /// Fit the global rect into pixel rect - - m2::PointD HalfSize(m_Scale * m_PixelRect.SizeX() / 2, - m_Scale * m_PixelRect.SizeY() / 2); - - m_GlobalRect = m2::RectD( - GlobalRect.Center() - HalfSize, - GlobalRect.Center() + HalfSize - ); + m_Angle = GlobalRect.angle(); + m_Org = GlobalRect.GlobalCenter(); UpdateDependentParameters(); } void ScreenBase::SetOrg(m2::PointD const & p) { - m_GlobalRect.Offset(p - m_GlobalRect.Center()); + m_Org = p; UpdateDependentParameters(); } void ScreenBase::Move(double dx, double dy) { - m_GlobalRect.Offset(m_GlobalRect.Center() - PtoG(m_PixelRect.Center() + m2::PointD(dx, dy))); - + m_Org = PtoG(GtoP(m_Org) - m2::PointD(dx, dy)); UpdateDependentParameters(); } -void ScreenBase::MoveG(m2::PointD const & delta) +void ScreenBase::MoveG(m2::PointD const & p) { - m_GlobalRect.Offset(delta); - + m_Org -= p; UpdateDependentParameters(); } void ScreenBase::Scale(double scale) { - m_GlobalRect.Scale( 1 / scale); m_Scale /= scale; UpdateDependentParameters(); } void ScreenBase::Rotate(double angle) { - m_Angle -= angle; + m_Angle = ang::AngleD(m_Angle.val() + angle); UpdateDependentParameters(); } +void ScreenBase::OnSize(m2::RectI const & r) +{ + m_PixelRect = m2::RectD(r); + UpdateDependentParameters(); +} + +void ScreenBase::OnSize(int x0, int y0, int w, int h) +{ + OnSize(m2::RectI(x0, y0, x0 + w, y0 + h)); +} + +math::Matrix<double, 3, 3> const & ScreenBase::GtoPMatrix() const +{ + return m_GtoP; +} + +math::Matrix<double, 3, 3> const & ScreenBase::PtoGMatrix() const +{ + return m_PtoG; +} + +m2::RectD const & ScreenBase::PixelRect() const +{ + return m_PixelRect; +} + +m2::AARectD const & ScreenBase::GlobalRect() const +{ + return m_GlobalRect; +} + +m2::RectD const & ScreenBase::ClipRect() const +{ + return m_ClipRect; +} + +double ScreenBase::GetScale() const +{ + return m_Scale; +} + +double ScreenBase::GetAngle() const +{ + return m_Angle.val(); +} + +int ScreenBase::GetWidth() const +{ + return my::rounds(m_PixelRect.SizeX()); +} + +int ScreenBase::GetHeight() const +{ + return my::rounds(m_PixelRect.SizeY()); +} + math::Matrix<double, 3, 3> const ScreenBase::CalcTransform(m2::PointD const & oldPt1, m2::PointD const & oldPt2, m2::PointD const & newPt1, m2::PointD const & newPt2) { @@ -136,34 +185,38 @@ void ScreenBase::SetGtoPMatrix(math::Matrix<double, 3, 3> const & m) /// Extracting transformation params, assuming that the matrix /// somehow represent a valid screen transformation /// into m_PixelRectangle - double dx, dy; - ExtractGtoPParams(m, m_Angle, m_Scale, dx, dy); - m_Scale = 1 / m_Scale; - - m_GlobalRect = m_PixelRect; - m_GlobalRect.Scale(m_Scale); + double dx, dy, a, s; + ExtractGtoPParams(m, a, s, dx, dy); + m_Angle = ang::AngleD(-a); + m_Scale = 1 / s; + m_Org = PtoG(m_PixelRect.Center()); - m_GlobalRect.Offset(m_PixelRect.Center() * m_PtoG - m_GlobalRect.Center()); + UpdateDependentParameters(); } -void ScreenBase::GtoP(m2::RectD const & gr, m2::RectD & sr) const +void ScreenBase::GtoP(m2::RectD const & glbRect, m2::RectD & pxRect) const { - sr = m2::RectD(GtoP(gr.LeftTop()), GtoP(gr.RightBottom())); + pxRect = m2::RectD(GtoP(glbRect.LeftTop()), GtoP(glbRect.RightBottom())); } -void ScreenBase::PtoG(m2::RectD const & sr, m2::RectD & gr) const +void ScreenBase::PtoG(m2::RectD const & pxRect, m2::RectD & glbRect) const { - gr = m2::RectD(PtoG(sr.LeftTop()), PtoG(sr.RightBottom())); + glbRect = m2::RectD(PtoG(pxRect.LeftTop()), PtoG(pxRect.RightBottom())); } -bool IsPanning(ScreenBase const & s1, ScreenBase const & s2) +bool IsPanningAndRotate(ScreenBase const & s1, ScreenBase const & s2) { - m2::PointD globPt(s1.GlobalRect().Center().x - s1.GlobalRect().minX(), - s1.GlobalRect().Center().y - s1.GlobalRect().minY()); + m2::RectD r1 = s1.GlobalRect().GetLocalRect(); + m2::RectD r2 = s2.GlobalRect().GetLocalRect(); + + m2::PointD c1 = r1.Center(); + m2::PointD c2 = r2.Center(); - m2::PointD p1 = s1.GtoP(s1.GlobalRect().Center()) - s1.GtoP(s1.GlobalRect().Center() + globPt); + m2::PointD globPt(c1.x - r1.minX(), + c1.y - r1.minY()); - m2::PointD p2 = s2.GtoP(s2.GlobalRect().Center()) - s2.GtoP(s2.GlobalRect().Center() + globPt); + m2::PointD p1 = s1.GtoP(s1.GlobalRect().ConvertFrom(c1)) - s1.GtoP(s1.GlobalRect().ConvertFrom(c1 + globPt)); + m2::PointD p2 = s2.GtoP(s2.GlobalRect().ConvertFrom(c2)) - s2.GtoP(s2.GlobalRect().ConvertFrom(c2 + globPt)); return p1.EqualDxDy(p2, 0.00001); } |