[apps/shared] Create a class Range1D

This commit is contained in:
Émilie Feral
2019-09-03 15:14:02 +02:00
parent a3b59a585c
commit fc2f3d79b5
3 changed files with 80 additions and 0 deletions

View File

@@ -52,6 +52,7 @@ app_shared_src = $(addprefix apps/shared/,\
parameter_text_field_delegate.cpp \
post_and_hardware_tests.cpp \
range_parameter_controller.cpp \
range_1D.cpp \
regular_table_view_data_source.cpp \
round_cursor_view.cpp \
scrollable_exact_approximate_expressions_cell.cpp \

48
apps/shared/range_1D.cpp Normal file
View File

@@ -0,0 +1,48 @@
#include "range_1D.h"
#include <assert.h>
#include <ion.h>
namespace Shared {
static inline float minFloat(float x, float y) { return x < y ? x : y; }
static inline float maxFloat(float x, float y) { return x > y ? x : y; }
void Range1D::setMin(float min, float lowerMaxFloat, float upperMaxFloat) {
min = clipped(min, false, lowerMaxFloat, upperMaxFloat);
if (std::isnan(min)) {
return;
}
m_min = min;
if (m_min >= m_max) {
m_max = min + defaultRangeLengthFor(min);
}
if (m_max - min < k_minFloat) {
m_max = clipped(min + k_minFloat, true, lowerMaxFloat, upperMaxFloat);
}
}
void Range1D::setMax(float max, float lowerMaxFloat, float upperMaxFloat) {
max = clipped(max, true, lowerMaxFloat, upperMaxFloat);
if (std::isnan(max)) {
return;
}
m_max = max;
if (m_min >= m_max) {
m_min = max - defaultRangeLengthFor(max);
}
if (max-m_min < k_minFloat) {
m_min = clipped(max - k_minFloat, false, lowerMaxFloat, upperMaxFloat);
}
}
float Range1D::defaultRangeLengthFor(float position) {
return std::pow(10.0f, std::floor(std::log10(std::fabs(position)))-1.0f);
}
float Range1D::clipped(float x, bool isMax, float lowerMaxFloat, float upperMaxFloat) {
float maxF = isMax ? upperMaxFloat : lowerMaxFloat;
float minF = isMax ? -lowerMaxFloat : -upperMaxFloat;
return maxFloat(minF, minFloat(x, maxF));
}
}

31
apps/shared/range_1D.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef SHARED_RANGE_1D_H
#define SHARED_RANGE_1D_H
#include <cmath>
#include <float.h>
namespace Shared {
class Range1D {
public:
constexpr static float k_minFloat = 1E-4f;
Range1D(float min = -10.0f, float max = 10.0f) :
m_min(min),
m_max(max)
{}
float min() const { return m_min; }
float max() const { return m_max; }
void setMin(float f, float lowerMaxFloat = INFINITY, float upperMaxFloat = INFINITY);
void setMax(float f, float lowerMaxFloat = INFINITY, float upperMaxFloat = INFINITY);
static float clipped(float x, bool isMax, float lowerMaxFloat, float upperMaxFloat);
static float defaultRangeLengthFor(float position);
private:
float m_min;
float m_max;
};
static_assert(Range1D::k_minFloat >= FLT_EPSILON, "InteractiveCurveViewRange's minimal float range is lower than float precision, it might draw uglily curves such as cos(x)^2+sin(x)^2");
}
#endif