From 89c201a7f7866b497d748b0d77eeedd32f6127da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 22 Jan 2018 14:26:56 +0100 Subject: [PATCH] [apps] Graph: create an IntersectionGraphController --- apps/graph/Makefile | 1 + .../graph/calculation_graph_controller.h | 2 +- .../calculation_parameter_controller.cpp | 13 ++--- .../graph/calculation_parameter_controller.h | 4 +- .../graph/curve_parameter_controller.cpp | 4 +- apps/graph/graph/curve_parameter_controller.h | 2 +- apps/graph/graph/graph_controller.cpp | 2 +- .../graph/intersection_graph_controller.cpp | 54 +++++++++++++++++++ .../graph/intersection_graph_controller.h | 21 ++++++++ apps/shared/function_banner_delegate.h | 2 +- 10 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 apps/graph/graph/intersection_graph_controller.cpp create mode 100644 apps/graph/graph/intersection_graph_controller.h diff --git a/apps/graph/Makefile b/apps/graph/Makefile index fbda46dbd..04edd7eb8 100644 --- a/apps/graph/Makefile +++ b/apps/graph/Makefile @@ -15,6 +15,7 @@ app_objs += $(addprefix apps/graph/,\ graph/graph_controller_helper.o\ graph/graph_view.o\ graph/integral_graph_controller.o\ + graph/intersection_graph_controller.o\ graph/tangent_graph_controller.o\ graph/root_graph_controller.o\ list/list_controller.o\ diff --git a/apps/graph/graph/calculation_graph_controller.h b/apps/graph/graph/calculation_graph_controller.h index 45338cb62..b277faffe 100644 --- a/apps/graph/graph/calculation_graph_controller.h +++ b/apps/graph/graph/calculation_graph_controller.h @@ -21,7 +21,7 @@ protected: constexpr static float k_cursorTopMarginRatio = 0.07f; // (cursorHeight/2)/graphViewHeight constexpr static float k_cursorBottomMarginRatio = 0.15f; // (cursorHeight/2+bannerHeigh)/graphViewHeight BannerView * bannerView() override { return m_bannerView; } - void reloadBannerView(); + virtual void reloadBannerView(); bool moveCursor(int direction); CartesianFunction::Point computeNewPointOfInteresetFromAbscissa(double start, int direction); virtual CartesianFunction::Point computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) = 0; diff --git a/apps/graph/graph/calculation_parameter_controller.cpp b/apps/graph/graph/calculation_parameter_controller.cpp index 2d1bed7d3..537ed3907 100644 --- a/apps/graph/graph/calculation_parameter_controller.cpp +++ b/apps/graph/graph/calculation_parameter_controller.cpp @@ -7,7 +7,7 @@ using namespace Shared; namespace Graph { -CalculationParameterController::CalculationParameterController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, InteractiveCurveViewRange * range, CurveViewCursor * cursor) : +CalculationParameterController::CalculationParameterController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, InteractiveCurveViewRange * range, CurveViewCursor * cursor, CartesianFunctionStore * functionStore) : ViewController(parentResponder), m_selectableTableView(this, this, 0, 1, Metric::CommonTopMargin, Metric::CommonRightMargin, Metric::CommonBottomMargin, Metric::CommonLeftMargin, this), @@ -16,7 +16,8 @@ CalculationParameterController::CalculationParameterController(Responder * paren m_integralGraphController(nullptr, graphView, range, cursor), m_minimumGraphController(nullptr, graphView, bannerView, range, cursor), m_maximumGraphController(nullptr, graphView, bannerView, range, cursor), - m_rootGraphController(nullptr, graphView, bannerView, range, cursor) + m_rootGraphController(nullptr, graphView, bannerView, range, cursor), + m_intersectionGraphController(nullptr, graphView, bannerView, range, cursor, functionStore) { } @@ -37,6 +38,10 @@ bool CalculationParameterController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE) { ViewController * controller = nullptr; switch(selectedRow()) { + case 0: + m_intersectionGraphController.setFunction(m_function); + controller = &m_intersectionGraphController; + break; case 1: m_maximumGraphController.setFunction(m_function); controller = &m_maximumGraphController; @@ -60,10 +65,6 @@ bool CalculationParameterController::handleEvent(Ion::Events::Event event) { default: return false; } - // This is temporary (until the end of development of calculation menu) - if (controller == nullptr) { - return false; - } StackViewController * stack = static_cast(parentResponder()); stack->pop(); stack->pop(); diff --git a/apps/graph/graph/calculation_parameter_controller.h b/apps/graph/graph/calculation_parameter_controller.h index 7a3a41bba..84a395e0a 100644 --- a/apps/graph/graph/calculation_parameter_controller.h +++ b/apps/graph/graph/calculation_parameter_controller.h @@ -6,6 +6,7 @@ #include "tangent_graph_controller.h" #include "extremum_graph_controller.h" #include "integral_graph_controller.h" +#include "intersection_graph_controller.h" #include "root_graph_controller.h" #include "graph_view.h" #include "banner_view.h" @@ -15,7 +16,7 @@ namespace Graph { class CalculationParameterController : public ViewController, public SimpleListViewDataSource, public SelectableTableViewDataSource { public: - CalculationParameterController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * range, Shared::CurveViewCursor * cursor); + CalculationParameterController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * range, Shared::CurveViewCursor * cursor, CartesianFunctionStore * functionStore); View * view() override; const char * title() override; bool handleEvent(Ion::Events::Event event) override; @@ -36,6 +37,7 @@ private: MinimumGraphController m_minimumGraphController; MaximumGraphController m_maximumGraphController; RootGraphController m_rootGraphController; + IntersectionGraphController m_intersectionGraphController; }; } diff --git a/apps/graph/graph/curve_parameter_controller.cpp b/apps/graph/graph/curve_parameter_controller.cpp index a9310556f..f953fe2b1 100644 --- a/apps/graph/graph/curve_parameter_controller.cpp +++ b/apps/graph/graph/curve_parameter_controller.cpp @@ -7,13 +7,13 @@ using namespace Shared; namespace Graph { -CurveParameterController::CurveParameterController(InteractiveCurveViewRange * graphRange, BannerView * bannerView, CurveViewCursor * cursor, GraphView * graphView, GraphController * graphController) : +CurveParameterController::CurveParameterController(InteractiveCurveViewRange * graphRange, BannerView * bannerView, CurveViewCursor * cursor, GraphView * graphView, GraphController * graphController, CartesianFunctionStore * functionStore) : FunctionCurveParameterController(graphRange, cursor), m_goToParameterController(this, graphRange, cursor, I18n::Message::X), m_graphController(graphController), m_calculationCell(I18n::Message::Compute), m_derivativeCell(I18n::Message::DerivateNumber), - m_calculationParameterController(this, graphView, bannerView, graphRange, cursor) + m_calculationParameterController(this, graphView, bannerView, graphRange, cursor, functionStore) { } diff --git a/apps/graph/graph/curve_parameter_controller.h b/apps/graph/graph/curve_parameter_controller.h index 717502693..eeedc80c1 100644 --- a/apps/graph/graph/curve_parameter_controller.h +++ b/apps/graph/graph/curve_parameter_controller.h @@ -11,7 +11,7 @@ class GraphController; class CurveParameterController : public Shared::FunctionCurveParameterController { public: - CurveParameterController(Shared::InteractiveCurveViewRange * graphRange, BannerView * bannerView, Shared::CurveViewCursor * cursor, GraphView * graphView, GraphController * graphController); + CurveParameterController(Shared::InteractiveCurveViewRange * graphRange, BannerView * bannerView, Shared::CurveViewCursor * cursor, GraphView * graphView, GraphController * graphController, CartesianFunctionStore * functionStore); const char * title() override; bool handleEvent(Ion::Events::Event event) override; int numberOfRows() override; diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index f85439481..7013a8f5b 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -11,7 +11,7 @@ GraphController::GraphController(Responder * parentResponder, CartesianFunctionS m_bannerView(), m_view(functionStore, curveViewRange, m_cursor, &m_bannerView, &m_cursorView), m_graphRange(curveViewRange), - m_curveParameterController(curveViewRange, &m_bannerView, m_cursor, &m_view, this), + m_curveParameterController(curveViewRange, &m_bannerView, m_cursor, &m_view, this, functionStore), m_functionStore(functionStore), m_displayDerivativeInBanner(false) { diff --git a/apps/graph/graph/intersection_graph_controller.cpp b/apps/graph/graph/intersection_graph_controller.cpp new file mode 100644 index 000000000..2d9a9421a --- /dev/null +++ b/apps/graph/graph/intersection_graph_controller.cpp @@ -0,0 +1,54 @@ +#include "intersection_graph_controller.h" +#include "../app.h" + +using namespace Shared; +using namespace Poincare; + +namespace Graph { + +IntersectionGraphController::IntersectionGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, CartesianFunctionStore * store) : + CalculationGraphController(parentResponder, graphView, bannerView, curveViewRange, cursor, I18n::Message::NoIntersectionFound), + m_intersectedFunction(nullptr), + m_functionStore(store) +{ +} + +const char * IntersectionGraphController::title() { + return I18n::translate(I18n::Message::Intersection); +} + +void IntersectionGraphController::reloadBannerView() { + m_bannerView->setNumberOfSubviews(2); + reloadBannerViewForCursorOnFunction(m_cursor, m_function, 'x'); + char buffer[FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; + const char * space = " "; + int spaceLength = strlen(space); + const char * legend = "0(x)=0(x)="; + int legendLength = strlen(legend); + int numberOfChar = 0; + strlcpy(buffer, legend, legendLength+1); + numberOfChar += legendLength; + buffer[0] = m_function->name()[0]; + buffer[5] = m_intersectedFunction->name()[0]; + numberOfChar += Complex::convertFloatToText(m_cursor->y(), buffer+legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + strlcpy(buffer+numberOfChar, space, spaceLength+1); + buffer[FunctionBannerDelegate::k_maxDigitLegendLength+5] = 0; + bannerView()->setLegendAtIndex(buffer, 1); +} + +CartesianFunction::Point IntersectionGraphController::computeNewPointOfInterest(double start, double step, double max, Context * context) { + CartesianFunction::Point result = {.abscissa = NAN, .value = NAN}; + for (int i = 0; i < m_functionStore->numberOfActiveFunctions(); i++) { + Function * f = m_functionStore->activeFunctionAtIndex(i); + if (f != m_function) { + CartesianFunction::Point intersection = m_function->nextIntersectionFrom(start, step, max, context, f); + if ((std::isnan(result.abscissa) || std::fabs(intersection.abscissa-start) < std::fabs(result.abscissa-start)) && !std::isnan(intersection.abscissa)) { + m_intersectedFunction = f; + result = (std::isnan(result.abscissa) || std::fabs(intersection.abscissa-start) < std::fabs(result.abscissa-start)) ? intersection : result; + } + } + } + return result; +} + +} diff --git a/apps/graph/graph/intersection_graph_controller.h b/apps/graph/graph/intersection_graph_controller.h new file mode 100644 index 000000000..097de1377 --- /dev/null +++ b/apps/graph/graph/intersection_graph_controller.h @@ -0,0 +1,21 @@ +#ifndef GRAPH_INTERSECTION_GRAPH_CONTROLLER_H +#define GRAPH_INTERSECTION_GRAPH_CONTROLLER_H + +#include "calculation_graph_controller.h" + +namespace Graph { + +class IntersectionGraphController : public CalculationGraphController { +public: + IntersectionGraphController(Responder * parentResponder, GraphView * graphView, BannerView * bannerView, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, CartesianFunctionStore * functionStore); + const char * title() override; +private: + void reloadBannerView() override; + CartesianFunction::Point computeNewPointOfInterest(double start, double step, double max, Poincare::Context * context) override; + Shared::Function * m_intersectedFunction; + CartesianFunctionStore * m_functionStore; +}; + +} + +#endif diff --git a/apps/shared/function_banner_delegate.h b/apps/shared/function_banner_delegate.h index be824cf3f..0d690eaea 100644 --- a/apps/shared/function_banner_delegate.h +++ b/apps/shared/function_banner_delegate.h @@ -10,8 +10,8 @@ namespace Shared { class FunctionBannerDelegate { public: constexpr static int k_maxNumberOfCharacters = 50; -protected: constexpr static int k_maxDigitLegendLength = 11; +protected: void reloadBannerViewForCursorOnFunction(CurveViewCursor * cursor, Function * function, char symbol); virtual BannerView * bannerView() = 0; };