void Navigator::SetOrg(m2::PointD const & org) { ScreenBase tmp = m_Screen; tmp.SetOrg(org); if (CheckBorders(tmp)) m_Screen = tmp; }
ScreenBase const ScaleInto(ScreenBase const & screen, m2::RectD boundRect) { ReduceRectHack(boundRect); ScreenBase res = screen; double scale = 1; m2::RectD clipRect = res.ClipRect(); ASSERT(boundRect.IsPointInside(clipRect.Center()), ("center point should be inside boundRect")); if (clipRect.minX() < boundRect.minX()) { double k = (boundRect.minX() - clipRect.Center().x) / (clipRect.minX() - clipRect.Center().x); scale /= k; clipRect.Scale(k); } if (clipRect.maxX() > boundRect.maxX()) { double k = (boundRect.maxX() - clipRect.Center().x) / (clipRect.maxX() - clipRect.Center().x); scale /= k; clipRect.Scale(k); } if (clipRect.minY() < boundRect.minY()) { double k = (boundRect.minY() - clipRect.Center().y) / (clipRect.minY() - clipRect.Center().y); scale /= k; clipRect.Scale(k); } if (clipRect.maxY() > boundRect.maxY()) { double k = (boundRect.maxY() - clipRect.Center().y) / (clipRect.maxY() - clipRect.Center().y); scale /= k; clipRect.Scale(k); } res.Scale(scale); res.SetOrg(clipRect.Center()); return res; }
ScreenBase const ShrinkInto(ScreenBase const & screen, m2::RectD boundRect) { ReduceRectHack(boundRect); ScreenBase res = screen; m2::RectD clipRect = res.ClipRect(); if (clipRect.minX() < boundRect.minX()) clipRect.Offset(boundRect.minX() - clipRect.minX(), 0); if (clipRect.maxX() > boundRect.maxX()) clipRect.Offset(boundRect.maxX() - clipRect.maxX(), 0); if (clipRect.minY() < boundRect.minY()) clipRect.Offset(0, boundRect.minY() - clipRect.minY()); if (clipRect.maxY() > boundRect.maxY()) clipRect.Offset(0, boundRect.maxY() - clipRect.maxY()); res.SetOrg(clipRect.Center()); // This assert fails near x = 180 (Philipines). //ASSERT ( boundRect.IsRectInside(res.ClipRect()), (clipRect, res.ClipRect()) ); return res; }
ScreenBase const ShrinkAndScaleInto(ScreenBase const & screen, m2::RectD boundRect) { ReduceRectHack(boundRect); ScreenBase res = screen; m2::RectD globalRect = res.ClipRect(); m2::PointD newOrg = res.GetOrg(); double scale = 1; double offs = 0; if (globalRect.minX() < boundRect.minX()) { offs = boundRect.minX() - globalRect.minX(); globalRect.Offset(offs, 0); newOrg.x += offs; if (globalRect.maxX() > boundRect.maxX()) { double k = boundRect.SizeX() / globalRect.SizeX(); scale /= k; /// scaling always occur pinpointed to the rect center... globalRect.Scale(k); /// ...so we should shift a rect after scale globalRect.Offset(boundRect.minX() - globalRect.minX(), 0); } } if (globalRect.maxX() > boundRect.maxX()) { offs = boundRect.maxX() - globalRect.maxX(); globalRect.Offset(offs, 0); newOrg.x += offs; if (globalRect.minX() < boundRect.minX()) { double k = boundRect.SizeX() / globalRect.SizeX(); scale /= k; globalRect.Scale(k); globalRect.Offset(boundRect.maxX() - globalRect.maxX(), 0); } } if (globalRect.minY() < boundRect.minY()) { offs = boundRect.minY() - globalRect.minY(); globalRect.Offset(0, offs); newOrg.y += offs; if (globalRect.maxY() > boundRect.maxY()) { double k = boundRect.SizeY() / globalRect.SizeY(); scale /= k; globalRect.Scale(k); globalRect.Offset(0, boundRect.minY() - globalRect.minY()); } } if (globalRect.maxY() > boundRect.maxY()) { offs = boundRect.maxY() - globalRect.maxY(); globalRect.Offset(0, offs); newOrg.y += offs; if (globalRect.minY() < boundRect.minY()) { double k = boundRect.SizeY() / globalRect.SizeY(); scale /= k; globalRect.Scale(k); globalRect.Offset(0, boundRect.maxY() - globalRect.maxY()); } } res.SetOrg(globalRect.Center()); res.Scale(scale); return res; }