43 _cvData.push_back(
CV(position, val, type));
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;
62 auto lastIndex = _cvData.size() - 1;
63 end.
_val = _cvData[lastIndex - 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());
99 const CV *cvDataBegin = &_cvData[0];
100 int index =
static_cast<int>(std::upper_bound(cvDataBegin, cvDataBegin + numPoints,
CV(param, T(), kLinear), cvLessThan) - cvDataBegin);
103 const auto t0 = _cvData[index - 1]._pos;
104 const T k0 = _cvData[index - 1]._val;
105 const InterpType interp = _cvData[index - 1]._interp;
106 const auto t1 = _cvData[index]._pos;
107 const T k1 = _cvData[index]._val;
113 double u = (param - t0) / (t1 - t0);
114 return k0 + u * (k1 - k0);
117 double u = (param - t0) / (t1 - t0);
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;
128 return (x * (delta * (3 * h - 2 * x) * x + h * (-h + x) * (-(d1 * h) + (d1 + d2) * x))) / (h * h * h) + y;
143 const int numPoints =
static_cast<int>(_cvData.size());
144 const CV *cvDataBegin = &_cvData[0];
145 int index =
static_cast<int>(std::upper_bound(cvDataBegin, cvDataBegin + numPoints,
CV(param, T(), kLinear), cvLessThan) - cvDataBegin);
148 const auto t0 = _cvData[index - 1]._pos;
149 const double k0 = comp(_cvData[index - 1]._val, channel);
150 const InterpType interp = _cvData[index - 1]._interp;
151 const auto t1 = _cvData[index]._pos;
152 const double k1 = comp(_cvData[index]._val, channel);
158 double u = (param - t0) / (t1 - t0);
159 return k0 + u * (k1 - k0);
164 double u = (param - t0) / (t1 - t0);
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);
177 return (x * (delta * (3 * h - 2 * x) * x + h * (-h + x) * (-(d1 * h) + (d1 + d2) * x))) / (h * h * h) + y;
189 const CV *cvDataBegin = &_cvData[0];
190 int numPoints =
static_cast<int>(_cvData.size());
191 int index =
static_cast<int>(std::upper_bound(cvDataBegin, cvDataBegin + numPoints,
CV(param, T(), kLinear), cvLessThan) - cvDataBegin);
194 return _cvData[index - 1];
195 return _cvData[index];
200 return interp == kNone || interp == kLinear || interp == kSmooth || interp == kSpline || interp == kMonotoneSpline;
215 for (
int i = 0; i < 3; i++) {
Interpolation curve class for double->double and double->Vec3D.
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.
double max(double x, double y)
double min(double x, double y)
double clamp(double x, double lo, double hi)