From 98a877082ce603df1582c45d72f725d643aba38d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 15 Jun 2017 17:19:06 +0200 Subject: [PATCH] [apps/shared] Factorize regression and function did change range method Change-Id: Ie4ddefe883a4a0c40f50b5b2afe3d6eb7aa78e0e --- apps/regression/store.cpp | 58 ++++++----- apps/regression/store.h | 4 +- apps/shared/Makefile | 1 + apps/shared/function_graph_controller.cpp | 97 +++++++------------ apps/shared/function_graph_controller.h | 4 +- .../interactive_curve_view_range_delegate.cpp | 51 ++++++++++ .../interactive_curve_view_range_delegate.h | 10 +- 7 files changed, 129 insertions(+), 96 deletions(-) create mode 100644 apps/shared/interactive_curve_view_range_delegate.cpp diff --git a/apps/regression/store.cpp b/apps/regression/store.cpp index 2bbcecb9a..b88effbd8 100644 --- a/apps/regression/store.cpp +++ b/apps/regression/store.cpp @@ -14,30 +14,6 @@ Store::Store() : { } -bool Store::didChangeRange(InteractiveCurveViewRange * interactiveCurveViewRange) { - if (!m_yAuto) { - return false; - } - float min = m_yMin; - float max = m_yMax; - for (int k = 0; k < m_numberOfPairs; k++) { - if (m_xMin <= m_data[0][k] && m_data[0][k] <= m_xMax) { - if (m_data[1][k] < min) { - min = m_data[1][k]; - } - if (m_data[1][k] > max) { - max = m_data[1][k]; - } - } - } - if (min == m_yMin && max == m_yMax) { - return false; - } - setYMin(min); - setYMax(max); - return true; -} - /* Dots */ int Store::closestVerticalDot(int direction, float x) { @@ -136,13 +112,9 @@ void Store::setDefault() { float min = minValueOfColumn(0); float max = maxValueOfColumn(0); float range = max - min; - InteractiveCurveViewRange::setXMin(min - k_displayLeftMarginRatio*range); - InteractiveCurveViewRange::setXMax(max + k_displayRightMarginRatio*range); - min = minValueOfColumn(1); - max = maxValueOfColumn(1); - range = max - min; - setYMin(min - k_displayBottomMarginRatio*range); - setYMax(max + k_displayTopMarginRatio*range); + setXMin(min - k_displayLeftMarginRatio*range); + setXMax(max + k_displayRightMarginRatio*range); + setYAuto(true); } /* Calculations */ @@ -242,4 +214,28 @@ float Store::squaredCorrelationCoefficient() { return cov*cov/(v0*v1); } +InteractiveCurveViewRangeDelegate::Range Store::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) { + float min = FLT_MAX; + float max = -FLT_MAX; + for (int k = 0; k < m_numberOfPairs; k++) { + if (m_xMin <= m_data[0][k] && m_data[0][k] <= m_xMax) { + if (m_data[1][k] < min) { + min = m_data[1][k]; + } + if (m_data[1][k] > max) { + max = m_data[1][k]; + } + } + } + InteractiveCurveViewRangeDelegate::Range range; + range.min = min; + range.max = max; + return range; +} + +float Store::addMargin(float x, float range, bool isMin) { + float ratio = isMin ? -k_displayBottomMarginRatio : k_displayTopMarginRatio; + return x+ratio*range; +} + } diff --git a/apps/regression/store.h b/apps/regression/store.h index df83a6a6a..f14b9484c 100644 --- a/apps/regression/store.h +++ b/apps/regression/store.h @@ -9,8 +9,6 @@ namespace Regression { class Store : public Shared::InteractiveCurveViewRange, public Shared::FloatPairStore, public Shared::InteractiveCurveViewRangeDelegate { public: Store(); - bool didChangeRange(Shared::InteractiveCurveViewRange * interactiveCurveViewRange) override; - // Dots /* Return the closest dot to x above the regression curve if direction > 0, * below otherwise*/ @@ -41,6 +39,8 @@ private: constexpr static float k_displayRightMarginRatio = 0.05f; constexpr static float k_displayBottomMarginRatio = 0.5f; constexpr static float k_displayLeftMarginRatio = 0.05f; + InteractiveCurveViewRangeDelegate::Range computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) override; + float addMargin(float x, float range, bool isMin) override; float maxValueOfColumn(int i); float minValueOfColumn(int i); }; diff --git a/apps/shared/Makefile b/apps/shared/Makefile index 06469b147..d50e647c5 100644 --- a/apps/shared/Makefile +++ b/apps/shared/Makefile @@ -21,6 +21,7 @@ app_objs += $(addprefix apps/shared/,\ initialisation_parameter_controller.o\ interactive_curve_view_controller.o\ interactive_curve_view_range.o\ + interactive_curve_view_range_delegate.o\ interval.o\ interval_parameter_controller.o\ list_controller.o\ diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index 5ca07391a..fc010f088 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -39,67 +39,6 @@ void FunctionGraphController::viewWillAppear() { InteractiveCurveViewController::viewWillAppear(); } -bool FunctionGraphController::didChangeRange(InteractiveCurveViewRange * interactiveCurveViewRange) { - if (!interactiveCurveViewRange->yAuto()) { - return false; - } - TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); - if (functionStore()->numberOfActiveFunctions() <= 0) { - return false; - } - float min = FLT_MAX; - float max = -FLT_MAX; - float xMin = interactiveCurveViewRange->xMin(); - float xMax = interactiveCurveViewRange->xMax(); - float step = (xMax - xMin)/curveView()->resolution(); - for (int i=0; inumberOfActiveFunctions(); i++) { - Function * f = functionStore()->activeFunctionAtIndex(i); - float y = 0.0f; - for (int i = 0; i <= curveView()->resolution(); i++) { - float x = xMin + i*step; - y = f->evaluateAtAbscissa(x, myApp->localContext()); - if (!isnan(y) && !isinf(y)) { - min = min < y ? min : y; - max = max > y ? max : y; - } - } - } - float range = max - min; - if (max < min) { - range = 0.0f; - } - if (interactiveCurveViewRange->yMin() == min-k_displayBottomMarginRatio*range - && interactiveCurveViewRange->yMax() == max+k_displayTopMarginRatio*range) { - return false; - } - if (min == max) { - float step = max != 0.0f ? interactiveCurveViewRange->computeGridUnit(CurveViewRange::Axis::Y, 0.0f, max) : 1.0f; - min = min - step; - max = max + step; - } - if (min == FLT_MAX && max == -FLT_MAX) { - min = -1.0f; - max = 1.0f; - } - if (min == FLT_MAX) { - float step = max != 0.0f ? interactiveCurveViewRange->computeGridUnit(CurveViewRange::Axis::Y, 0.0f, fabsf(max)) : 1.0f; - min = max-step; - } - if (max == -FLT_MAX) { - float step = min != 0.0f ? interactiveCurveViewRange->computeGridUnit(CurveViewRange::Axis::Y, 0.0f, fabsf(min)) : 1.0f; - max = min+step; - } - interactiveCurveViewRange->setYMin(min-k_displayBottomMarginRatio*range); - interactiveCurveViewRange->setYMax(max+k_displayTopMarginRatio*range); - if (isinf(interactiveCurveViewRange->xMin())) { - interactiveCurveViewRange->setYMin(-FLT_MAX); - } - if (isinf(interactiveCurveViewRange->xMax())) { - interactiveCurveViewRange->setYMax(FLT_MAX); - } - return true; -} - bool FunctionGraphController::handleEnter() { Function * f = functionStore()->activeFunctionAtIndex(m_indexFunctionSelectedByCursor); curveParameterController()->setFunction(f); @@ -141,6 +80,42 @@ void FunctionGraphController::reloadBannerView() { bannerView()->setLegendAtIndex(buffer, 1); } +InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) { + TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); + float min = FLT_MAX; + float max = -FLT_MAX; + float xMin = interactiveCurveViewRange->xMin(); + float xMax = interactiveCurveViewRange->xMax(); + float step = (xMax - xMin)/curveView()->resolution(); + if (functionStore()->numberOfActiveFunctions() <= 0) { + InteractiveCurveViewRangeDelegate::Range range; + range.min = xMin; + range.max = xMax; + return range; + } + for (int i=0; inumberOfActiveFunctions(); i++) { + Function * f = functionStore()->activeFunctionAtIndex(i); + float y = 0.0f; + for (int i = 0; i <= curveView()->resolution(); i++) { + float x = xMin + i*step; + y = f->evaluateAtAbscissa(x, myApp->localContext()); + if (!isnan(y) && !isinf(y)) { + min = min < y ? min : y; + max = max > y ? max : y; + } + } + } + InteractiveCurveViewRangeDelegate::Range range; + range.min = min; + range.max = max; + return range; +} + +float FunctionGraphController::addMargin(float x, float range, bool isMin) { + float ratio = isMin ? -k_displayBottomMarginRatio : k_displayTopMarginRatio; + return x+ratio*range; +} + void FunctionGraphController::initRangeParameters() { interactiveCurveViewRange()->setDefault(); initCursorParameters(); diff --git a/apps/shared/function_graph_controller.h b/apps/shared/function_graph_controller.h index 43c99a360..64bd4f7ed 100644 --- a/apps/shared/function_graph_controller.h +++ b/apps/shared/function_graph_controller.h @@ -16,7 +16,6 @@ public: bool isEmpty() const override; ViewController * initialisationParameterController() override; void viewWillAppear() override; - bool didChangeRange(Shared::InteractiveCurveViewRange * interactiveCurveViewRange) override; protected: constexpr static float k_cursorTopMarginRatio = 0.068f; // (cursorHeight/2)/graphViewHeight constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth @@ -32,6 +31,9 @@ private: constexpr static float k_displayTopMarginRatio = 0.09f; constexpr static float k_displayBottomMarginRatio = 0.2f; + InteractiveCurveViewRangeDelegate::Range computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) override; + float addMargin(float x, float range, bool isMin) override; + void initRangeParameters() override; bool moveCursorVertically(int direction) override; CurveView * curveView() override; diff --git a/apps/shared/interactive_curve_view_range_delegate.cpp b/apps/shared/interactive_curve_view_range_delegate.cpp new file mode 100644 index 000000000..482367d9b --- /dev/null +++ b/apps/shared/interactive_curve_view_range_delegate.cpp @@ -0,0 +1,51 @@ +#include "interactive_curve_view_range_delegate.h" +#include "interactive_curve_view_range.h" +#include +#include + +namespace Shared { + + +bool InteractiveCurveViewRangeDelegate::didChangeRange(InteractiveCurveViewRange * interactiveCurveViewRange) { + if (!interactiveCurveViewRange->yAuto()) { + return false; + } + Range yRange = computeYRange(interactiveCurveViewRange); + float max = yRange.max; + float min = yRange.min; + float range = max - min; + if (max < min) { + range = 0.0f; + } + if (interactiveCurveViewRange->yMin() == addMargin(min, range, true) && interactiveCurveViewRange->yMax() == addMargin(max, range, false)) { + return false; + } + if (min == max) { + float step = max != 0.0f ? interactiveCurveViewRange->computeGridUnit(CurveViewRange::Axis::Y, 0.0f, max) : 1.0f; + min = min - step; + max = max + step; + } + if (min == FLT_MAX && max == -FLT_MAX) { + min = -1.0f; + max = 1.0f; + } + if (min == FLT_MAX) { + float step = max != 0.0f ? interactiveCurveViewRange->computeGridUnit(CurveViewRange::Axis::Y, 0.0f, fabsf(max)) : 1.0f; + min = max-step; + } + if (max == -FLT_MAX) { + float step = min != 0.0f ? interactiveCurveViewRange->computeGridUnit(CurveViewRange::Axis::Y, 0.0f, fabsf(min)) : 1.0f; + max = min+step; + } + interactiveCurveViewRange->setYMin(addMargin(min, range, true)); + interactiveCurveViewRange->setYMax(addMargin(max, range, false)); + if (isinf(interactiveCurveViewRange->xMin())) { + interactiveCurveViewRange->setYMin(-FLT_MAX); + } + if (isinf(interactiveCurveViewRange->xMax())) { + interactiveCurveViewRange->setYMax(FLT_MAX); + } + return true; +} + +} diff --git a/apps/shared/interactive_curve_view_range_delegate.h b/apps/shared/interactive_curve_view_range_delegate.h index 758980885..67b28a30e 100644 --- a/apps/shared/interactive_curve_view_range_delegate.h +++ b/apps/shared/interactive_curve_view_range_delegate.h @@ -7,7 +7,15 @@ class InteractiveCurveViewRange; class InteractiveCurveViewRangeDelegate { public: - virtual bool didChangeRange(InteractiveCurveViewRange * interactiveCurveViewRange) = 0; + bool didChangeRange(InteractiveCurveViewRange * interactiveCurveViewRange); +protected: + struct Range { + float min; + float max; + }; +private: + virtual Range computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) = 0; + virtual float addMargin(float x, float range, bool isMin) = 0; }; }