Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
curves.h
Go to the documentation of this file.
1
5#ifndef UTILS_CURVES_H
6#define UTILS_CURVES_H
7
9
10#include <algorithm>
11#include <cmath>
12#include <vector>
13
14namespace lampda {
15namespace utils {
17namespace curves {
18
24template<typename T, typename U> struct Point
25{
26 T x;
27 U y;
28};
29
35template<typename T, typename U> class LinearCurve
36{
37public:
40
42 LinearCurve(const std::vector<point_t>& points)
43 {
44 // first fail fast
45 assert(points.size() >= 2 && "Linear curve must have more than 1 points");
46
47 pts = points;
48
49 for (const auto& p: pts)
50 {
51 // check A
52 assert(not std::isnan(p.x) && "invalid value in curve parameters");
53 assert(std::isfinite(p.x) && "invalid value in curve parameters");
54 assert(not std::isnan(p.y) && "invalid value in curve parameters");
55 assert(std::isfinite(p.y) && "invalid value in curve parameters");
56 }
57
58 // sort the vector by the x coordinate
59 auto lbd = [](const point_t& a, const point_t& b) {
60 return a.x < b.x;
61 };
62 std::sort(pts.begin(), pts.end(), lbd);
63
64 // remove duplicates (after sorting)
65 std::vector<point_t> nPoints;
66 nPoints.reserve(pts.size());
67
68 point_t lastPt = pts[0];
69 nPoints.emplace_back(lastPt);
70 for (size_t i = 1; i < pts.size(); i++)
71 {
72 const auto& p = pts[i];
73 if (lastPt.x != p.x and lastPt.y != p.y)
74 nPoints.emplace_back(p);
75 lastPt = p;
76 }
77 // last check
78 pts = nPoints;
79 assert(pts.size() >= 2 && "Linear curve must have more than 1 points");
80 }
81
83 U sample(const T x) const
84 {
85 point_t lastPt = pts[0];
86 // bounds failure
87 if (std::isnan(x))
88 return lastPt.y;
89 if (x <= lastPt.x)
90 return lastPt.y;
91 if (x >= pts.back().x)
92 return pts.back().y;
93
94 for (size_t i = 1; i < pts.size(); ++i)
95 {
96 const point_t& pt = pts[i];
97 // in this segment bound
98 if (x >= lastPt.x and x <= pt.x)
99 {
100 return lmpd_map<U>(x, lastPt.x, pt.x, lastPt.y, pt.y);
101 }
102 // update last point
103 lastPt = pt;
104 }
105
106 // highest bound failure
107 return lastPt.y;
108 }
109
110private:
112 std::vector<point_t> pts;
113};
114
120template<typename T, typename U> class ExponentialCurve
121{
122public:
125
133 ExponentialCurve(const point_t& pointA, const point_t& pointB, const double exponent = 15.0) :
134 lowerBound(pointA.y),
135 upperBound(pointB.y)
136 {
137 const double div = pointA.y / static_cast<double>(pointB.y);
138 if (div <= -1.0)
139 {
140 // Error: linear approx...
141 _exp = 1;
142 _a = 0;
143 _b = 1;
144 return;
145 }
146 const double A = exp(log(div) / exponent);
147 _exp = exponent;
148 _a = (static_cast<double>(pointA.x) - static_cast<double>(pointB.x) * A) / (A - 1);
149 _b = static_cast<double>(pointA.y) / pow(static_cast<double>(pointA.x + _a), exponent);
150 }
151
157 float sample(const T x) const
158 {
159 const float res = pow(static_cast<double>(x) + _a, _exp) * _b;
160 return lmpd_constrain<float>(res, lowerBound, upperBound);
161 }
162
163private:
165 const T lowerBound;
167 const T upperBound;
168
170 double _exp;
172 double _a;
174 double _b;
175};
176
177} // namespace curves
178} // namespace utils
179} // namespace lampda
180
181#endif
Given two points and an exponent, fit an exponential function.
Definition: curves.h:121
ExponentialCurve(const point_t &pointA, const point_t &pointB, const double exponent=15.0)
Exponential curve fitting to two points.
Definition: curves.h:133
float sample(const T x) const
Sample the exponential curve. Be aware that the result is always casted from a floating point !...
Definition: curves.h:157
Given a set of points, will fit multiple linear segments to it.
Definition: curves.h:36
LinearCurve(const std::vector< point_t > &points)
Build a curve from a set of points.
Definition: curves.h:42
U sample(const T x) const
Sample a point Y from a given x.
Definition: curves.h:83
Program scope.
Definition: control_fixed_modes.hpp:12
Define a 2D point.
Definition: curves.h:25
T x
X coordinate of the point.
Definition: curves.h:26
U y
Y coordinate of the point.
Definition: curves.h:27
Define useful functions.