From 901cce9e67a504cfe99023306ee6ae74ce7cd4c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 9 Sep 2019 10:44:30 +0200 Subject: [PATCH] [apps/graph] Move nextRootFrom from the controller to the model CartesianFunction and take into account function domain --- apps/graph/graph/root_graph_controller.cpp | 6 +----- apps/shared/cartesian_function.cpp | 17 +++++++++++++++++ apps/shared/cartesian_function.h | 3 +++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/apps/graph/graph/root_graph_controller.cpp b/apps/graph/graph/root_graph_controller.cpp index dd41713d4..413a5155c 100644 --- a/apps/graph/graph/root_graph_controller.cpp +++ b/apps/graph/graph/root_graph_controller.cpp @@ -17,11 +17,7 @@ const char * RootGraphController::title() { } Coordinate2D RootGraphController::computeNewPointOfInterest(double start, double step, double max, Context * context) { - // TODO The following three lines should be factored. - constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; - char unknownX[bufferSize]; - Poincare::SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX); - return Coordinate2D(Shared::PoincareHelpers::NextRoot(functionStore()->modelForRecord(m_record)->expressionReduced(context), unknownX, start, step, max, context), 0.0); + return functionStore()->modelForRecord(m_record)->nextRootFrom(start, step, max, context); } } diff --git a/apps/shared/cartesian_function.cpp b/apps/shared/cartesian_function.cpp index e4b3beca0..bf3ebcf54 100644 --- a/apps/shared/cartesian_function.cpp +++ b/apps/shared/cartesian_function.cpp @@ -274,6 +274,10 @@ Coordinate2D CartesianFunction::templatedApproximateAtParameter(T t, Poincare PoincareHelpers::ApproximateWithValueForSymbol(e.childAtIndex(1), unknown, t, context)); } +Coordinate2D CartesianFunction::nextRootFrom(double start, double step, double max, Context * context) const { + return nextPointOfInterestFrom(start, step, max, context, [](Expression e, char * symbol, double start, double step, double max, Context * context) { return Coordinate2D(PoincareHelpers::NextRoot(e, symbol, start, step, max, context), 0.0); }); +} + Coordinate2D CartesianFunction::nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, CartesianFunction * f) const { assert(plotType() == PlotType::Cartesian); constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; @@ -291,6 +295,19 @@ Coordinate2D CartesianFunction::nextIntersectionFrom(double start, doubl return PoincareHelpers::NextIntersection(expressionReduced(context), unknownX, start, step, max, context, f->expressionReduced(context)); } +Coordinate2D CartesianFunction::nextPointOfInterestFrom(double start, double step, double max, Context * context, ComputePointOfInterest compute) const { + constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; + char unknownX[bufferSize]; + SerializationHelper::CodePoint(unknownX, bufferSize, UCodePointUnknownX); + if (step > 0.0f) { + start = maxDouble(start, tMin()); + max = minDouble(max, tMax()); + } else { + start = minDouble(start, tMax()); + max = maxDouble(max, tMin()); + } + return compute(expressionReduced(context), unknownX, start, step, max, context); +} template Coordinate2D CartesianFunction::templatedApproximateAtParameter(float, Poincare::Context *) const; template Coordinate2D CartesianFunction::templatedApproximateAtParameter(double, Poincare::Context *) const; diff --git a/apps/shared/cartesian_function.h b/apps/shared/cartesian_function.h index 6f8b90a6e..2b3e36b50 100644 --- a/apps/shared/cartesian_function.h +++ b/apps/shared/cartesian_function.h @@ -59,8 +59,11 @@ public: // Cartesian calculation Poincare::Coordinate2D nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, CartesianFunction * f) const; + Poincare::Coordinate2D nextRootFrom(double start, double step, double max, Poincare::Context * context) const; private: constexpr static float k_polarParamRangeSearchNumberOfPoints = 100.0f; // This is ad hoc, no special justification + typedef Poincare::Coordinate2D (*ComputePointOfInterest)(Poincare::Expression e, char * symbol, double start, double step, double max, Poincare::Context * context); + Poincare::Coordinate2D nextPointOfInterestFrom(double start, double step, double max, Poincare::Context * context, ComputePointOfInterest compute) const; template Poincare::Coordinate2D privateEvaluateXYAtParameter(T t, Poincare::Context * context) const; /* CartesianFunctionRecordDataBuffer is the layout of the data buffer of Record * representing a CartesianFunction. See comment on