From 20cbefad41e3e2f2701e297798958d28a91a7b4c Mon Sep 17 00:00:00 2001 From: Gabriel Ozouf Date: Thu, 15 Oct 2020 10:48:25 +0200 Subject: [PATCH] [function_graph_controller] Fix y for first move Method yForCursorFirstMove is supposed to expand the window so that the first move of the cursor won't cause it to pan. It now filters extreme values to prevent the original window to be totally squashed, such as with the drawing of e^x and (x-100)(x+10) at the same time. Change-Id: Icd6c26b01475a112c4231f293e03ab31d80d5e51 --- apps/shared/function_graph_controller.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index 267b45d73..adeba5bd4 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -174,16 +174,27 @@ void FunctionGraphController::yRangeForCursorFirstMove(InteractiveCurveViewRange int functionsCount = functionStore()->numberOfActiveFunctions(); float cursorStep = range->xGridUnit() / k_numberOfCursorStepsInGradUnit; - float yN, yP; + float y[2]; // Left and Right bool normalized = range->isOrthonormal(); + constexpr float maximalExpansion = 10.f; + float yRange = range->yMax() - range->yMin(); + for (int i = 0; i < functionsCount; i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); - yN = f->evaluateXYAtParameter(range->xCenter() - cursorStep, context).x2(); - yP = f->evaluateXYAtParameter(range->xCenter() + cursorStep, context).x2(); - range->setYMin(std::min(range->yMin(), std::min(yN, yP))); - range->setYMax(std::max(range->yMax(), std::max(yN, yP))); + for (int i = 0; i < 2; i++) { + float step = cursorStep * (i == 0 ? -1 : 1); + y[i] = f->evaluateXYAtParameter(range->xCenter() + step, context).x2(); + if (std::isfinite(y[i])) { + if (y[i] < range->yMin() && (range->yMax() - y[i]) < maximalExpansion * yRange) { + range->setYMin(y[i]); + } + if (y[i] > range->yMax() && (y[i] - range->yMin()) < maximalExpansion * yRange) { + range->setYMax(y[i]); + } + } + } } if (normalized) {