diff --git a/poincare/include/poincare/zoom.h b/poincare/include/poincare/zoom.h index 079f9a38e..132071d20 100644 --- a/poincare/include/poincare/zoom.h +++ b/poincare/include/poincare/zoom.h @@ -24,6 +24,7 @@ public: static void FullRange(ValueAtAbscissa evaluation, float tMin, float tMax, float tStep, float * fMin, float * fMax, Context * context, const void * auxiliary); static void CombineRanges(int length, const float * mins, const float * maxs, float * minRes, float * maxRes); + static void SanitizeRange(float * xMin, float * xMax, float * yMin, float * yMax, float normalRatio); /* 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.*/ diff --git a/poincare/src/zoom.cpp b/poincare/src/zoom.cpp index d03cb5ff0..e18c0ebfb 100644 --- a/poincare/src/zoom.cpp +++ b/poincare/src/zoom.cpp @@ -237,6 +237,40 @@ void Zoom::CombineRanges(int length, const float * mins, const float * maxs, flo } } +void Zoom::SanitizeRange(float * xMin, float * xMax, float * yMin, float * yMax, float normalRatio) { + /* Axes of the window can be : + * - well-formed + * - empty (min = max) + * - ill-formed (min > max, or either bound is not finite) + * + * The general strategy to sanitize a window is as follow : + * - for all ill-formed axes, set both bounds to 0 + * - if both axes are empty, set the X axis to default bounds + * - if one axis is empty, normalize the window + * - do nothing if both axes are well-formed. */ + + if (!std::isfinite(*xMin) || !std::isfinite(*xMax) || *xMax < *xMin) { + *xMin = 0; + *xMax = 0; + } + if (!std::isfinite(*yMin) || !std::isfinite(*yMax) || *yMax < *yMin) { + *yMin = 0; + *yMax = 0; + } + + float xRange = *xMax - *xMin; + float yRange = *yMax - *yMin; + if (xRange < k_minimalRangeLength && yRange < k_minimalRangeLength) { + *xMax = *xMin + k_defaultHalfRange; + *xMin -= k_defaultHalfRange; + xRange = 2 * k_defaultHalfRange; + } + + if (xRange < k_minimalRangeLength || yRange < k_minimalRangeLength) { + SetToRatio(normalRatio, xMin, xMax, yMin, yMax, false); + } +} + void Zoom::SetToRatio(float yxRatio, float * xMin, float * xMax, float * yMin, float * yMax, bool shrink) { float currentRatio = (*yMax - *yMin) / (*xMax - *xMin);