diff --git a/apps/shared/interactive_curve_view_range.cpp b/apps/shared/interactive_curve_view_range.cpp index 86953bc04..d7181f66d 100644 --- a/apps/shared/interactive_curve_view_range.cpp +++ b/apps/shared/interactive_curve_view_range.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include using namespace Poincare; @@ -88,27 +89,19 @@ void InteractiveCurveViewRange::normalize() { /* We center the ranges on the current range center, and put each axis so that * 1cm = 2 current units. */ - float xRange = xMax() - xMin(); - float yRange = yMax() - yMin(); - float xyRatio = xRange/yRange; + float newXMin = xMin(), newXMax = xMax(), newYMin = yMin(), newYMax = yMax(); const float unit = std::max(xGridUnit(), yGridUnit()); const float newXHalfRange = NormalizedXHalfRange(unit); const float newYHalfRange = NormalizedYHalfRange(unit); - float normalizedXYRatio = newXHalfRange/newYHalfRange; - if (xyRatio < normalizedXYRatio) { - float newXRange = normalizedXYRatio * yRange; - assert(newXRange >= xRange); - float delta = (newXRange - xRange) / 2.0f; - m_xRange.setMin(xMin() - delta, k_lowerMaxFloat, k_upperMaxFloat); - MemoizedCurveViewRange::protectedSetXMax(xMax()+delta, k_lowerMaxFloat, k_upperMaxFloat); - } else if (xyRatio > normalizedXYRatio) { - float newYRange = newYHalfRange/newXHalfRange * xRange; - assert(newYRange >= yRange); - float delta = (newYRange - yRange) / 2.0f; - m_yRange.setMin(yMin() - delta, k_lowerMaxFloat, k_upperMaxFloat); - MemoizedCurveViewRange::protectedSetYMax(yMax()+delta, k_lowerMaxFloat, k_upperMaxFloat); - } + float normalizedYXRatio = newYHalfRange/newXHalfRange; + + Zoom::SetToRatio(normalizedYXRatio, &newXMin, &newXMax, &newYMin, &newYMax); + + m_xRange.setMin(newXMin, k_lowerMaxFloat, k_upperMaxFloat); + MemoizedCurveViewRange::protectedSetXMax(newXMax, k_lowerMaxFloat, k_upperMaxFloat); + m_yRange.setMin(newYMin, k_lowerMaxFloat, k_upperMaxFloat); + MemoizedCurveViewRange::protectedSetYMax(newYMax, k_lowerMaxFloat, k_upperMaxFloat); } void InteractiveCurveViewRange::setDefault() { diff --git a/poincare/include/poincare/zoom.h b/poincare/include/poincare/zoom.h index 4b3dfd42c..1adb1d425 100644 --- a/poincare/include/poincare/zoom.h +++ b/poincare/include/poincare/zoom.h @@ -15,6 +15,10 @@ public: static void InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin, float * xMax, float * yMin, float * yMax, float tMin, float tMax, Context * context, const void * auxiliary); static void RefinedYRangeForDisplay(ValueAtAbscissa evaluation, float xMin, float xMax, float * yMin, float * yMax, Context * context, const void * auxiliary, bool boundByMagnitude = false); + /* 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); + private: static constexpr int k_peakNumberOfPointsOfInterest = 3; static constexpr int k_sampleSize = Ion::Display::Width / 4; diff --git a/poincare/src/zoom.cpp b/poincare/src/zoom.cpp index ac4ed1956..2c93223fa 100644 --- a/poincare/src/zoom.cpp +++ b/poincare/src/zoom.cpp @@ -199,6 +199,29 @@ void Zoom::RefinedYRangeForDisplay(ValueAtAbscissa evaluation, float xMin, float } } +void Zoom::SetToRatio(float yxRatio, float * xMin, float * xMax, float * yMin, float * yMax, bool shrink) { + float currentRatio = (*yMax - *yMin) / (*xMax - *xMin); + + float * tMin; + float * tMax; + float newRange; + if ((currentRatio < yxRatio) == shrink) { + /* Y axis too small and shrink, or Y axis too large and do not shrink + * --> we change the X axis*/ + tMin = xMin; + tMax = xMax; + newRange = (*yMax - *yMin) / yxRatio; + } else { + tMin = yMin; + tMax = yMax; + newRange = (*xMax - *xMin) * yxRatio; + } + + float center = (*tMax + *tMin) / 2.f; + *tMax = center + newRange / 2.f; + *tMin = center - newRange / 2.f; +} + 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;