28 return cv1._pos <
cv2._pos;
51 std::sort(_cvData.begin(), _cvData.end(), cvLessThan);
54 CV &end = *(_cvData.end() - 1);
55 CV &begin = *(_cvData.begin());
56 auto realCVs = _cvData.size() - 2;
59 begin.
_val = _cvData[1]._val;
74 for (
unsigned int i = 1;
i < _cvData.size() - 1;
i++) {
75 _cvData[
i]._deriv = (_cvData[
i + 1]._val - _cvData[
i - 1]._val) / (_cvData[
i + 1]._pos - _cvData[
i - 1]._pos);
79 for (
unsigned int i = 0;
i < _cvData.size() - 1;
i++) {
80 if (_cvData[
i]._interp == kMonotoneSpline) {
81 double h = _cvData[
i + 1]._pos - _cvData[
i]._pos;
83 _cvData[
i]._deriv = _cvData[
i + 1]._deriv =
T();
85 T delta = (_cvData[
i + 1]._val - _cvData[
i]._val) /
h;
86 clampCurveSegment(
delta, _cvData[
i]._deriv, _cvData[
i + 1]._deriv);
98 const int numPoints =
static_cast<int>(_cvData.size());
101 index = std::max(1, std::min(index,
numPoints - 1));
103 const auto t0 = _cvData[index - 1]._pos;
104 const T k0 = _cvData[index - 1]._val;
106 const auto t1 = _cvData[index]._pos;
107 const T k1 = _cvData[index]._val;
114 return k0 + u * (
k1 -
k0);
118 return k0 * (u - 1) * (u - 1) * (2 * u + 1) +
k1 * u * u * (3 - 2 * u);
121 case kMonotoneSpline: {
122 double x =
param - _cvData[index - 1]._pos;
123 double h = _cvData[index]._pos - _cvData[index - 1]._pos;
124 T y = _cvData[index - 1]._val;
125 T delta = _cvData[index]._val - _cvData[index - 1]._val;
126 T d1 = _cvData[index - 1]._deriv;
127 T d2 = _cvData[index]._deriv;
143 const int numPoints =
static_cast<int>(_cvData.size());
146 index = std::max(1, std::min(index,
numPoints - 1));
148 const auto t0 = _cvData[index - 1]._pos;
149 const double k0 = comp(_cvData[index - 1]._val,
channel);
151 const auto t1 = _cvData[index]._pos;
152 const double k1 = comp(_cvData[index]._val,
channel);
159 return k0 + u * (
k1 -
k0);
165 return k0 * (u - 1) * (u - 1) * (2 * u + 1) +
k1 * u * u * (3 - 2 * u);
169 case kMonotoneSpline: {
170 double x =
param - _cvData[index - 1]._pos;
171 double h = _cvData[index]._pos - _cvData[index - 1]._pos;
172 double y = comp(_cvData[index - 1]._val,
channel);
173 double delta = comp(_cvData[index]._val,
channel) - comp(_cvData[index - 1]._val,
channel);
174 double d1 = comp(_cvData[index - 1]._deriv,
channel);
175 double d2 = comp(_cvData[index]._deriv,
channel);
190 int numPoints =
static_cast<int>(_cvData.size());
192 index = std::max(1, std::min(index,
numPoints - 1));
194 return _cvData[index - 1];
195 return _cvData[index];
215 for (
int i = 0;
i < 3;
i++) {
InterpType
Supported interpolation types.
void preparePoints()
Prepares points for evaluation (sorts and computes boundaries, clamps extrema)
T getValue(double param) const
Evaluates curve and returns full value.
static bool cvLessThan(const CV &cv1, const CV &cv2)
CV Parameter ordering (cv1._pos < cv2._pos)
void addPoint(double position, const T &val, InterpType type)
Adds a point to the curve.
std::vector< CV > _cvData
static double comp(const T &val, int i)
Returns a component of the given value.
double getChannelValue(double param, int channel) const
CV getLowerBoundCV(double param) const
static bool interpTypeValid(InterpType interp)
Returns whether the given interpolation type is supported.
void clampCurveSegment(const T &delta, T &d1, T &d2)
Performs hermite derivative clamping in canonical space.
Vec()
Empty constructor (this is invalid for a reference type)
static_if< ref, T *, std::array< T, d > >::TYPE x
internal data (either an explicit arary or a pointer to raw data)
double clamp(double x, double lo, double hi)