diff --git a/poincare/include/poincare/zoom.h b/poincare/include/poincare/zoom.h index 6bd08ca88..4bd5c0165 100644 --- a/poincare/include/poincare/zoom.h +++ b/poincare/include/poincare/zoom.h @@ -37,6 +37,7 @@ public: /* If shrink is false, the range will be set to ratio by increasing the size * of the smallest axis. If it is true, the longest axis will be reduced.*/ static void SetToRatio(float yxRatio, float * xMin, float * xMax, float * yMin, float * yMax, bool shrink = false); + static void SetZoom(float ratio, float xCenter, float yCenter, float * xMin, float * xMax, float * yMin, float * yMax); private: static constexpr int k_peakNumberOfPointsOfInterest = 3; diff --git a/poincare/src/zoom.cpp b/poincare/src/zoom.cpp index ab278aaa5..7cb7b46a6 100644 --- a/poincare/src/zoom.cpp +++ b/poincare/src/zoom.cpp @@ -421,6 +421,14 @@ void Zoom::SetToRatio(float yxRatio, float * xMin, float * xMax, float * yMin, f *tMin = center - newRange / 2.f; } +void Zoom::SetZoom(float ratio, float xCenter, float yCenter, float * xMin, float * xMax, float * yMin, float * yMax) { + float oneMinusRatio = 1.f - ratio; + *xMin = oneMinusRatio * xCenter + ratio * *xMin; + *xMax = oneMinusRatio * xCenter + ratio * *xMax; + *yMin = oneMinusRatio * yCenter + ratio * *yMin; + *yMax = oneMinusRatio * yCenter + ratio * *yMax; +} + bool Zoom::IsConvexAroundExtremum(ValueAtAbscissa evaluation, float x1, float x2, float x3, float y1, float y2, float y3, Context * context, const void * auxiliary, int iterations) { if (iterations <= 0) { return false; diff --git a/poincare/test/zoom.cpp b/poincare/test/zoom.cpp index 2f43edfb7..3fee10f16 100644 --- a/poincare/test/zoom.cpp +++ b/poincare/test/zoom.cpp @@ -198,6 +198,12 @@ void assert_expands_to(float yxRatio, float xMin, float xMax, float yMin, float assert_ratio_is_set_to(yxRatio, xMin, xMax, yMin, yMax, false, targetXMin, targetXMax, targetYMin, targetYMax); } +void assert_zooms_to(float ratio, float xCenter, float yCenter, float xMin, float xMax, float yMin, float yMax, float targetXMin, float targetXMax, float targetYMin, float targetYMax) { + float tempXMin = xMin, tempXMax = xMax, tempYMin = yMin, tempYMax = yMax; + Zoom::SetZoom(ratio, xCenter, yCenter, &tempXMin, &tempXMax, &tempYMin, &tempYMax); + quiz_assert(ranges_match(tempXMin, tempXMax, tempYMin, tempYMax, targetXMin, targetXMax, targetYMin, targetYMax)); +} + QUIZ_CASE(poincare_zoom_utility) { // Ranges combinations { @@ -261,5 +267,22 @@ QUIZ_CASE(poincare_zoom_utility) { assert_expands_to(1.33f, -10, 10, -10, 10, -10, 10, -13.3, 13.3); + + // Zoom + assert_zooms_to(1.f, 0, 0, + -10, 10, -10, 10, + -10, 10, -10, 10); + assert_zooms_to(0.5f, 0, 0, + -10, 10, -5, 5, + -5, 5, -2.5, 2.5); + assert_zooms_to(3.f, 0, 0, + -10, 10, -5, 5, + -30, 30, -15, 15); + assert_zooms_to(1.5f, 10, 5, + -10, 10, -5, 5, + -20, 10, -10, 5); + assert_zooms_to(0.25f, 2, -2, + -10, 10, -5, 5, + -1, 4, -2.75, -0.25); }