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