Ocean
Loading...
Searching...
No Matches
Interpolation.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_MATH_INTERPOLATION_H
9#define META_OCEAN_MATH_INTERPOLATION_H
10
11#include "ocean/math/Math.h"
13#include "ocean/math/Numeric.h"
14#include "ocean/math/Pose.h"
16#include "ocean/math/Rotation.h"
17
18#include <map>
19
20namespace Ocean
21{
22
23/**
24 * This class implements data interpolation functions.
25 * An interpolation value of 0 provides the first value, 1 provides the second value.<br>
26 * @ingroup math
27 */
29{
30 protected:
31
32 /**
33 * This class implements a helper linear interpolation helper class allowing to overload the interpolation function for specific data types.
34 * @tparam T Data type of the values to be interpolated
35 */
36 template <typename T>
38 {
39 public:
40
41 /**
42 * Performs a linear interpolation between two values.
43 * @param v0 First value
44 * @param v1 Second value
45 * @param t Interpolation factor, with range [0, 1]
46 * @return Resulting interpolation value
47 * @tparam TFactor Data type of the interpolation value
48 */
49 template <typename TFactor>
50 static inline T interpolate(const T& v0, const T& v1, const TFactor& t);
51 };
52
53 public:
54
55 /**
56 * Performs a linear interpolation between two values.
57 * @param v0 First value corresponding to the interpolation factor t = 0
58 * @param v1 Second value corresponding to the interpolation factor t = 1
59 * @param t Interpolation factor, with range [0, 1]
60 * @return Resulting interpolation value
61 * @tparam T Data type of the values to be interpolated
62 * @tparam TFactor Data type of the interpolation value
63 */
64 template <typename T, typename TFactor>
65 static inline T linear(const T& v0, const T& v1, const TFactor& t);
66
67 /**
68 * Performs a bi-linear interpolation between four values within a 2x2 neighborhood.
69 * The layout of the four values are defined as follows:<br>
70 * <pre>
71 * v00 v01
72 * v10 v11
73 * </pre>
74 * @param v00 Top left value
75 * @param v01 Top right value
76 * @param v10 Bottom left value
77 * @param v11 Bottom right value
78 * @param tx Horizontal (left - right) interpolation factor, with range [0, 1]
79 * @param ty Vertical (top - bottom) interpolation factor, with range [0, 1]
80 * @return Resulting interpolation value
81 * @tparam T Data type of the values to be interpolated
82 * @tparam TFactor Data type of the interpolation value
83 */
84 template <typename T, typename TFactor>
85 static inline T bilinear(const T& v00, const T& v01, const T& v10, const T& v11, const TFactor& tx, const TFactor& ty);
86
87 /**
88 * Performs a bi-linear interpolation between at most four values within a 2x2 neighborhood.
89 * This function allows the interpolation between a subset of the given four values.<br>
90 * Thus, boolean statements for each individual value define whether the corresponding value is applied for interpolation or not.<br>
91 * If only one value is provided, than the 'interpolation' result is the value itself without investigating the interpolation factors.<br>
92 * The layout of the four values are defined as follows:<br>
93 * <pre>
94 * v00 v01
95 * v10 v11
96 * </pre>
97 * @param v00 Top left value
98 * @param v01 Top right value
99 * @param v10 Bottom left value
100 * @param v11 Bottom right value
101 * @param valid00 True, if the value v00 is valid and has to be applied for interpolation
102 * @param valid01 True, if the value v01 is valid and has to be applied for interpolation
103 * @param valid10 True, if the value v10 is valid and has to be applied for interpolation
104 * @param valid11 True, if the value v11 is valid and has to be applied for interpolation
105 * @param tx Horizontal (left - right) interpolation factor, with range [0, 1]
106 * @param ty Vertical (top - bottom) interpolation factor, with range [0, 1]
107 * @return Resulting interpolation value
108 * @tparam T Data type of the values to be interpolated
109 * @tparam TFactor Data type of the interpolation value
110 */
111 template <typename T, typename TFactor>
112 static inline T bilinear(const T& v00, const T& v01, const T& v10, const T& v11, const bool valid00, const bool valid01, const bool valid10, const bool valid11, const TFactor& tx, const TFactor& ty);
113
114 /**
115 * Performs a cubic (Catmull-Rom) interpolation between mainly two values while two further supporting points are requested.
116 * @param v0 Supporting value in front of the first value
117 * @param v1 First value
118 * @param v2 Second value
119 * @param v3 Supporting value behind the second value
120 * @param t Interpolation factor, with range [0, 1]
121 * @return Resulting interpolation value
122 * @tparam T Data type of the values to be interpolated
123 * @tparam TFactor Data type of the interpolation value
124 */
125 template <typename T, typename TFactor>
126 static inline T cubic(const T& v0, const T& v1, const T& v2, const T& v3, const TFactor& t);
127
128 /**
129 * Performs a spherical linear interpolation (SLERP) between two unit vectors.
130 * The interpolation follows the great circle path on the unit sphere, maintaining unit length throughout.
131 * This is the proper way to interpolate directional vectors (e.g., gravity, normals, orientations).
132 * @param v0 First unit vector corresponding to the interpolation factor t = 0
133 * @param v1 Second unit vector corresponding to the interpolation factor t = 1
134 * @param t Interpolation factor, with range [0, 1]
135 * @return Resulting interpolated unit vector
136 * @tparam T Data type of the vector elements (float or double)
137 * @tparam TFactor Data type of the interpolation value
138 */
139 template <typename T, typename TFactor>
140 static VectorT3<T> spherical(const VectorT3<T>& v0, const VectorT3<T>& v1, const TFactor& t);
141
142 /**
143 * Performs a Lagrange interpolation for a polynomial with degree 2.
144 * @param x0 Position of the first supporting value, must not be identical with x1
145 * @param y0 First supporting value
146 * @param x1 Position of the second supporting value, must not be identical with x0
147 * @param y1 Second supporting value
148 * @param x Position for that the interpolation value is requested
149 * @return Resulting Lagrange interpolation value
150 * @tparam T Data type of the supporting values
151 * @tparam TKey Data type of the positions of the supporting values
152 */
153 template <typename T, typename TKey>
154 static T lagrange2(const TKey& x0, const T& y0, const TKey& x1, const T& y1, const TKey& x);
155
156 /**
157 * Performs a Lagrange interpolation for a polynomial with degree 3.
158 * @param x0 Position of the first supporting value, must not be identical with x1 or x2
159 * @param y0 First supporting value
160 * @param x1 Position of the second supporting value, must not be identical with x0 or x2
161 * @param y1 Second supporting value
162 * @param x2 Position of the third supporting value, must not be identical with x0 or x1
163 * @param y2 Third supporting value
164 * @param x Position for that the interpolation value is requested
165 * @return Resulting Lagrange interpolation value
166 * @tparam T Data type of the supporting values
167 * @tparam TKey Data type of the positions of the supporting values
168 */
169 template <typename T, typename TKey>
170 static T lagrange3(const TKey& x0, const T& y0, const TKey& x1, const T& y1, const TKey& x2, const T& y2, const TKey& x);
171};
172
173/**
174 * This class implements an interpolation map allowing to determine an interpolated value between several individual key values.
175 * @tparam TKey The data type of the stored keys
176 * @tparam TValue The data type of the stored values
177 * @tparam TFactor The data type of the interpolation factor
178 * @ingroup math
179 */
180template <typename TKey, typename TValue, typename TFactor>
182{
183 public:
184
185 /**
186 * Definition of a map mapping keys to values.
187 */
188 using ValueMap = std::map<TKey, TValue>;
189
190 /**
191 * Definition of a function pointer for a function providing a linear interpolation.
192 * The first parameter defines the first interpolation value.<br>
193 * The second parameter defines the second interpolation value.<br>
194 * The third parameter defines the interpolation factor, with range [0, 1].<br>
195 */
196 using LinearInterpolationFunction = TValue (*)(const TValue&, const TValue&, const TFactor&);
197
198 public:
199
200 /**
201 * Default constructor.
202 */
203 inline InterpolationMap();
204
205 /**
206 * Copy constructor for interpolation maps.
207 * @param interpolationMap The interpolation map to copy
208 */
210
211 /**
212 * Move constructor for interpolation maps.
213 * @param interpolationMap The interpolation map to move
214 */
216
217 /**
218 * Creates a new interpolation map object by a given value map.
219 * @param valueMap The value map that will be stored in this object
220 */
221 inline InterpolationMap(const ValueMap& valueMap);
222
223 /**
224 * Creates a new interpolation map object by a given value map.
225 * @param valueMap The value map that will be moved to this object
226 */
227 inline InterpolationMap(ValueMap&& valueMap);
228
229 /**
230 * Returns the number of elements (pairs of keys and values) of this interpolation map.
231 * @return The number of stored elements
232 */
233 inline size_t size() const;
234
235 /**
236 * Returns whether this interpolation map object is empty.
237 * @return True, if so
238 */
239 inline bool isEmpty() const;
240
241 /**
242 * Clears all elements (pairs of keys and values) of this interpolation map object.
243 */
244 inline void clear();
245
246 /**
247 * Returns the entire internal interpolation map.
248 * @return Interpolation map of this object
249 */
250 inline const ValueMap& interpolationMap() const;
251
252 /**
253 * Sets or changes the entire internal interpolation map.
254 * @param interpolationMap The interpolation map that will replace the current one
255 */
257
258 /**
259 * Sets or changes the entire internal interpolation map.
260 * @param interpolationMap The interpolation map that will be moved to this object
261 */
263
264 /**
265 * Returns whether this interpolation map object holds a value for a specified key.
266 * @param key Key which is checked
267 * @return True, if so
268 */
269 inline bool hasValue(const TKey& key) const;
270
271 /**
272 * Returns the value of this interpolation map object defined by a corresponding key.
273 * If no value exists for this key, the pair of key and value is inserted and the default value is returned.<br>
274 * @param key Key for that the value is returned
275 * @return Value that corresponds to the specified key
276 * @see hasValue().
277 */
278 inline TValue& value(const TKey& key);
279
280 /**
281 * Removes an elements (pair of key and value) from this interpolation map object.
282 * @param key The key of the element to be removed
283 * @return True, if the element existed
284 */
285 inline bool remove(const TKey& key);
286
287 /**
288 * Inserts a new pair of key and value to this map object.
289 * @param key New key to be inserted
290 * @param value Corresponding value to be inserted
291 * @param forceOverwrite True, if an already existing pair with same key will be overwritten by the given pair
292 * @return True, if the given pair has been inserted
293 */
294 inline bool insert(const TKey& key, const TValue& value, const bool forceOverwrite = false);
295
296 /**
297 * Inserts a new pair of key and value to this map object.
298 * @param key New key to be inserted
299 * @param value Corresponding value to be moved
300 * @param forceOverwrite True, if an already existing pair with same key will be overwritten by the given pair
301 * @return True, if the given pair has been inserted
302 */
303 inline bool insert(const TKey& key, TValue&& value, const bool forceOverwrite = false);
304
305 /**
306 * Returns the linear interpolation of the stored values for a given key.
307 * @param key The key of the value that will be (interpolated and) returned
308 * @return Resulting interpolated value
309 */
310 inline TValue linear(const TKey& key) const;
311
312 /**
313 * Returns the linear interpolation of the stored values for a given key and a given interpolation function.
314 * @param key The key of the value that will be (interpolated and) returned
315 * @param interpolationFunction An explicit interpolation function that is applied
316 * @return Resulting interpolated value
317 */
318 inline TValue linear(const TKey& key, const LinearInterpolationFunction interpolationFunction) const;
319
320 /**
321 * Returns the linear interpolation of given values for a given key.
322 * @param valueMap The map of values that are used for interpolation
323 * @param key The key of the value that will be (interpolated and) returned
324 * @return Resulting interpolated value
325 */
326 static TValue linear(const ValueMap& valueMap, const TKey& key);
327
328 /**
329 * Returns the linear interpolation of given values for a given key and a given interpolation function.
330 * @param valueMap The map of values that are used for interpolation
331 * @param key The key of the value that will be (interpolated and) returned
332 * @param interpolationFunction An explicit interpolation function that is applied
333 * @return Resulting interpolated value
334 */
335 static TValue linear(const ValueMap& valueMap, const TKey& key, const LinearInterpolationFunction interpolationFunction);
336
337 /**
338 * Assign operator.
339 * @param object The interpolation map object which will be assigned to this object
340 * @return Reference to this object
341 */
343
344 /**
345 * Move operator.
346 * @param object The interpolation map object which will be moved to this object
347 * @return Reference to this object
348 */
350
351 /**
352 * Returns whether two interpolation objects are equal.
353 * @param object Second interpolation object
354 * @return True, if so
355 */
356 inline bool operator==(const InterpolationMap<TKey, TValue, TFactor>& object) const;
357
358 /**
359 * Returns whether two interpolation objects are not equal.
360 * @param object Second interpolation object
361 * @return True, if so
362 */
363 inline bool operator!=(const InterpolationMap<TKey, TValue, TFactor>& object) const;
364
365 /**
366 * Returns the value of this interpolation map object defined by a corresponding key.
367 * If no value exists for this key, the pair of key and value is inserted and the default value is returned.<br>
368 * @param key Key for that the value is returned
369 * @return Value that corresponds to the specified key
370 * @see value(), hasValue().
371 */
372 inline TValue& operator[](const TKey& key);
373
374 protected:
375
376 /// Map mapping keys to values.
378};
379
380template <typename T>
381template <typename TFactor>
382inline T Interpolation::LinearInterpolation<T>::interpolate(const T& v0, const T& v1, const TFactor& t)
383{
384 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
385
386 return v0 * (TFactor(1) - t) + v1 * t;
387}
388
389template <>
390template <>
391inline float Interpolation::LinearInterpolation<float>::interpolate(const float& v0, const float& v1, const double& t)
392{
393 ocean_assert(NumericT<double>::isInsideRange(0.0, t, 1.0));
394
395 return float(v0 * (1.0 - t)) + float(v1 * t);
396}
397
398template <>
399template <typename TFactor>
401{
402 ocean_assert(v0.isValid() && v1.isValid());
403 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
404
405 VectorT3<float> translation0(0, 0, 0), translation1(0, 0, 0);
406 VectorT3<float> scale0(0, 0, 0), scale1(0, 0, 0);
407 VectorT3<float> shear0(0, 0, 0), shear1(0, 0, 0);
408
409 QuaternionT<float> rotation0, rotation1;
410
411 v0.decompose(translation0, rotation0, scale0, shear0);
412 v1.decompose(translation1, rotation1, scale1, shear1);
413
414 return HomogenousMatrixT4<float>(linear(translation0, translation1, t), linear(rotation0, rotation1, t), linear(scale0, scale1, t), linear(shear0, shear1, t));
415}
416
417template <>
418template <typename TFactor>
420{
421 ocean_assert(v0.isValid() && v1.isValid());
422 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
423
424 VectorT3<double> translation0(0, 0, 0), translation1(0, 0, 0);
425 VectorT3<double> scale0(0, 0, 0), scale1(0, 0, 0);
426 VectorT3<double> shear0(0, 0, 0), shear1(0, 0, 0);
427
428 QuaternionT<double> rotation0, rotation1;
429
430 v0.decompose(translation0, rotation0, scale0, shear0);
431 v1.decompose(translation1, rotation1, scale1, shear1);
432
433 return HomogenousMatrixT4<double>(linear(translation0, translation1, t), linear(rotation0, rotation1, t), linear(scale0, scale1, t), linear(shear0, shear1, t));
434}
435
436template <>
437template <typename TFactor>
438inline std::pair<VectorT3<float>, QuaternionT<float>> Interpolation::LinearInterpolation< std::pair<VectorT3<float>, QuaternionT<float>> >::interpolate(const std::pair<VectorT3<float>, QuaternionT<float>>& v0, const std::pair<VectorT3<float>, QuaternionT<float>>& v1, const TFactor& t)
439{
440 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
441
442 return std::make_pair(linear(v0.first, v1.first, t), linear(v0.second, v1.second, t));
443}
444
445template <>
446template <typename TFactor>
447inline std::pair<VectorT3<double>, QuaternionT<double>> Interpolation::LinearInterpolation< std::pair<VectorT3<double>, QuaternionT<double>> >::interpolate(const std::pair<VectorT3<double>, QuaternionT<double>>& v0, const std::pair<VectorT3<double>, QuaternionT<double>>& v1, const TFactor& t)
448{
449 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
450
451 return std::make_pair(linear(v0.first, v1.first, t), linear(v0.second, v1.second, t));
452}
453
454template <>
455template <typename TFactor>
456inline std::pair<VectorT3<float>, RotationT<float>> Interpolation::LinearInterpolation< std::pair<VectorT3<float>, RotationT<float>> >::interpolate(const std::pair<VectorT3<float>, RotationT<float>>& v0, const std::pair<VectorT3<float>, RotationT<float>>& v1, const TFactor& t)
457{
458 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
459
460 return std::make_pair(linear(v0.first, v1.first, t), linear(v0.second, v1.second, t));
461}
462
463template <>
464template <typename TFactor>
465inline std::pair<VectorT3<double>, RotationT<double>> Interpolation::LinearInterpolation< std::pair<VectorT3<double>, RotationT<double>> >::interpolate(const std::pair<VectorT3<double>, RotationT<double>>& v0, const std::pair<VectorT3<double>, RotationT<double>>& v1, const TFactor& t)
466{
467 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
468
469 return std::make_pair(linear(v0.first, v1.first, t), linear(v0.second, v1.second, t));
470}
471
472template <>
473template <typename TFactor>
474inline Pose Interpolation::LinearInterpolation<Pose>::interpolate(const Pose& v0, const Pose& v1, const TFactor& t)
475{
476 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
477
478 return Pose(v0.translation() * (TFactor(1) - t) + v1.translation() * t, v0.orientation().slerp(v1.orientation(), t));
479}
480
481template <>
482template <typename TFactor>
484{
485 ocean_assert(v0.isValid() && v1.isValid());
486 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
487
488 return v0.slerp(v1, float(t));
489}
490
491template <>
492template <typename TFactor>
494{
495 ocean_assert(v0.isValid() && v1.isValid());
496 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
497
498 return v0.slerp(v1, double(t));
499}
500
501template <>
502template <typename TFactor>
504{
505 ocean_assert(v0.isValid() && v1.isValid());
506 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
507
509}
510
511template <>
512template <typename TFactor>
514{
515 ocean_assert(v0.isValid() && v1.isValid());
516 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
517
519}
520
521template <typename T, typename TFactor>
522inline T Interpolation::linear(const T& v0, const T& v1, const TFactor& t)
523{
524 ocean_assert(t >= TFactor(0) && t <= TFactor(1));
525
526 if (t <= TFactor(0))
527 {
528 return v0;
529 }
530 if (t >= TFactor(1))
531 {
532 return v1;
533 }
534
535 return LinearInterpolation<T>::template interpolate<TFactor>(v0, v1, t);
536}
537
538template <typename T, typename TFactor>
539inline T Interpolation::bilinear(const T& v00, const T& v01, const T& v10, const T& v11, const TFactor& tx, const TFactor& ty)
540{
541 return linear(linear(v00, v01, tx), linear(v10, v11, tx), ty);
542}
543
544template <typename T, typename TFactor>
545inline T Interpolation::bilinear(const T& v00, const T& v01, const T& v10, const T& v11, const bool valid00, const bool valid01, const bool valid10, const bool valid11, const TFactor& tx, const TFactor& ty)
546{
547 ocean_assert(valid00 || valid01 || valid10 || valid11);
548
549 ocean_assert(valid00 == 1 || valid00 == 0);
550 ocean_assert(valid01 == 1 || valid01 == 0);
551 ocean_assert(valid10 == 1 || valid10 == 0);
552 ocean_assert(valid11 == 1 || valid11 == 0);
553
554 const unsigned int state = (unsigned int)(valid00) | ((unsigned int)(valid01) << 8) | ((unsigned int)(valid10) << 16) | ((unsigned int)(valid11) << 24);
555
556 switch (state)
557 {
558 // 1 1
559 // 1 1
560 case 0x01010101:
561 return bilinear(v00, v01, v10, v11, tx, ty);
562
563 // 0 1
564 // 1 1
565 case 0x01010100:
566 return linear(v01, linear(v10, v11, tx), ty);
567
568 // 1 0
569 // 1 1
570 case 0x01010001:
571 return linear(v00, linear(v10, v11, tx), ty);
572
573 // 1 1
574 // 0 1
575 case 0x01000101:
576 return linear(linear(v00, v01, tx), v11, ty);
577
578 // 1 1
579 // 1 0
580 case 0x00010101:
581 return linear(linear(v00, v01, tx), v10, ty);
582
583 // 0 0
584 // 1 1
585 case 0x01010000:
586 return linear(v10, v11, tx);
587
588 // 1 0
589 // 1 0
590 case 0x00010001:
591 return linear(v00, v10, ty);
592
593 // 1 1
594 // 0 0
595 case 0x00000101:
596 return linear(v00, v01, tx);
597
598 // 0 1
599 // 0 1
600 case 0x01000100:
601 return linear(v01, v11, ty);
602
603 // 0 1
604 // 1 0
605 case 0x00010100:
606 // position on the diagonal
607 return linear(v10, v01, VectorT2<TFactor>(tx, TFactor(1) - ty).length() * TFactor(0.70710678118654752440084436210485));
608
609 // 1 0
610 // 0 1
611 case 0x01000001:
612 // position on the diagonal
613 return linear(v00, v11, VectorT2<TFactor>(tx, ty).length() * TFactor(0.70710678118654752440084436210485));
614
615 // 1 0
616 // 0 0
617 case 0x00000001:
618 return v00;
619
620 // 0 1
621 // 0 0
622 case 0x00000100:
623 return v01;
624
625 // 0 0
626 // 1 0
627 case 0x00010000:
628 return v10;
629
630 // 0 0
631 // 0 1
632 case 0x01000000:
633 return v11;
634
635 default:
636 break;
637 }
638
639 ocean_assert(false && "Invalid interpolation statement!");
640 return T();
641}
642
643template <typename T, typename TFactor>
644inline T Interpolation::cubic(const T& v0, const T& v1, const T& v2, const T& v3, const TFactor& t)
645{
646 ocean_assert((std::is_same<T, float>::value) ? NumericT<TFactor>::isInsideWeakRange(TFactor(0), t, TFactor(1)) : NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
647
648 return (v0 * TFactor(-0.5) + v1 * TFactor(1.5) - v2 * TFactor(1.5) + v3 * TFactor(0.5)) * t * t * t
649 + (v0 - v1 * TFactor(2.5) + v2 * TFactor(2) - v3 * TFactor(0.5)) * t * t
650 + (v0 * TFactor(-0.5) + v2 * TFactor(0.5)) * t
651 + v1;
652}
653
654template <typename T, typename TFactor>
655inline VectorT3<T> Interpolation::spherical(const VectorT3<T>& v0, const VectorT3<T>& v1, const TFactor& t)
656{
657 ocean_assert(v0.isUnit(NumericT<T>::weakEps()));
658 ocean_assert(v1.isUnit(NumericT<T>::weakEps()));
659 ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
660
661 if (t <= TFactor(0))
662 {
663 return v0;
664 }
665
666 if (t >= TFactor(1))
667 {
668 return v1;
669 }
670
671 const RotationT<T> v0_R_v1 = RotationT<T>::left_R_right(v0, v1);
672 const RotationT<T> interpolated_R_v1 = RotationT<T>(v0_R_v1.axis(), v0_R_v1.angle() * (T(1) - T(t)));
673
674 return interpolated_R_v1 * v1;
675}
676
677template <typename T, typename TKey>
678T Interpolation::lagrange2(const TKey& x0, const T& y0, const TKey& x1, const T& y1, const TKey& x)
679{
680 ocean_assert(NumericT<TKey>::isNotEqual(x0, x1));
681
682 return (y0 * (x1 - x) + y1 * (x - x0)) * (TKey(1) / (x1 - x0));
683}
684
685template <typename T, typename TKey>
686T Interpolation::lagrange3(const TKey& x0, const T& y0, const TKey& x1, const T& y1, const TKey& x2, const T& y2, const TKey& x)
687{
688 ocean_assert(NumericT<TKey>::isNotEqual(x0, x1) && NumericT<TKey>::isNotEqual(x0, x2) && NumericT<TKey>::isNotEqual(x1, x2));
689
690 return y0 * ((x - x1) * (x - x2)) * (TKey(1) / ((x0 - x1) * (x0 - x2)))
691 + y1 * ((x - x0) * (x - x2)) * (TKey(1) / ((x1 - x0) * (x1 - x2)))
692 + y2 * ((x - x0) * (x - x1)) * (TKey(1) / ((x2 - x0) * (x2 - x1)));
693}
694
695template <typename TKey, typename TValue, typename TFactor>
697{
698 // nothing to do here
699}
700
701template <typename TKey, typename TValue, typename TFactor>
703 valueMap_(interpolationMap.valueMap_)
704{
705 // nothing to do here
706}
707
708template <typename TKey, typename TValue, typename TFactor>
710 valueMap_(std::move(interpolationMap.valueMap_))
711{
712 // nothing to do here
713}
714
715template <typename TKey, typename TValue, typename TFactor>
717 valueMap_(valueMap)
718{
719 // nothing to do here
720}
721
722template <typename TKey, typename TValue, typename TFactor>
724 valueMap_(std::move(valueMap))
725{
726 // nothing to do here
727}
728
729template <typename TKey, typename TValue, typename TFactor>
731{
732 return valueMap_.size();
733}
734
735template <typename TKey, typename TValue, typename TFactor>
737{
738 return valueMap_.empty();
739}
740
741template <typename TKey, typename TValue, typename TFactor>
743{
744 valueMap_.clear();
745}
746
747template <typename TKey, typename TValue, typename TFactor>
752
753template <typename TKey, typename TValue, typename TFactor>
755{
756 valueMap_ = interpolationMap;
757}
758
759template <typename TKey, typename TValue, typename TFactor>
761{
762 valueMap_ = std::move(interpolationMap);
763}
764
765template <typename TKey, typename TValue, typename TFactor>
767{
768 return valueMap_.find(key) != valueMap_.end();
769}
770
771template <typename TKey, typename TValue, typename TFactor>
773{
774 return valueMap_[key];
775}
776
777template <typename TKey, typename TValue, typename TFactor>
779{
780 return valueMap_.erase(key) != 0;
781}
782
783template <typename TKey, typename TValue, typename TFactor>
784inline bool InterpolationMap<TKey, TValue, TFactor>::insert(const TKey& key, const TValue& value, const bool forceOverwrite)
785{
786 if (forceOverwrite)
787 {
788 valueMap_[key] = value;
789 return true;
790 }
791
792 if (valueMap_.find(key) != valueMap_.end())
793 {
794 return false;
795 }
796
797 valueMap_[key] = value;
798
799 return true;
800}
801
802template <typename TKey, typename TValue, typename TFactor>
803inline bool InterpolationMap<TKey, TValue, TFactor>::insert(const TKey& key, TValue&& value, const bool forceOverwrite)
804{
805 if (forceOverwrite)
806 {
807 valueMap_[key] = std::move(value);
808 return true;
809 }
810
811 if (valueMap_.find(key) != valueMap_.end())
812 {
813 return false;
814 }
815
816 valueMap_[key] = std::move(value);
817
818 return true;
819}
820
821template <typename TKey, typename TValue, typename TFactor>
822inline TValue InterpolationMap<TKey, TValue, TFactor>::linear(const TKey& key) const
823{
824 return linear(valueMap_, key);
825}
826
827template <typename TKey, typename TValue, typename TFactor>
828inline TValue InterpolationMap<TKey, TValue, TFactor>::linear(const TKey& key, const LinearInterpolationFunction interpolationFunction) const
829{
830 return linear(valueMap_, key, interpolationFunction);
831}
832
833template <typename TKey, typename TValue, typename TFactor>
834TValue InterpolationMap<TKey, TValue, TFactor>::linear(const ValueMap& valueMap, const TKey& key)
835{
836 if (valueMap.empty())
837 {
838 return TValue();
839 }
840
841 const typename ValueMap::const_iterator iHigher = valueMap.lower_bound(key);
842
843 // if the key is larger than the last key
844 if (iHigher == valueMap.end())
845 {
846 ocean_assert(valueMap.rbegin() != valueMap.rend());
847 return valueMap.rbegin()->second;
848 }
849
850 // if the key is the first element
851 if (iHigher == valueMap.begin())
852 {
853 return iHigher->second;
854 }
855
856 // we have at least one key in front of the higher key
857
858 typename ValueMap::const_iterator iLower(iHigher);
859 iLower--;
860
861 TFactor width = TFactor(iHigher->first - iLower->first);
862
863 ocean_assert(width > 0);
864 ocean_assert(key > iLower->first);
865
866 TFactor interpolationFactor = TFactor(key - iLower->first) / width;
867 ocean_assert(interpolationFactor >= TFactor(0) && interpolationFactor <= TFactor(1));
868
869 return Interpolation::linear(iLower->second, iHigher->second, interpolationFactor);
870}
871
872template <typename TKey, typename TValue, typename TFactor>
873TValue InterpolationMap<TKey, TValue, TFactor>::linear(const ValueMap& valueMap, const TKey& key, const LinearInterpolationFunction interpolationFunction)
874{
875 ocean_assert(interpolationFunction);
876
877 if (valueMap.empty() || !interpolationFunction)
878 {
879 return TValue();
880 }
881
882 const typename ValueMap::const_iterator iHigher = valueMap.lower_bound(key);
883
884 // if the key is larger than the last key
885 if (iHigher == valueMap.end())
886 {
887 ocean_assert(valueMap.rbegin() != valueMap.rend());
888 return valueMap.rbegin()->second;
889 }
890
891 // if the key is the first element
892 if (iHigher == valueMap.begin())
893 {
894 return iHigher->second;
895 }
896
897 // we have at least one key in front of the higher key
898
899 typename ValueMap::const_iterator iLower(iHigher);
900 iLower--;
901
902 TFactor width = TFactor(iHigher->first - iLower->first);
903
904 ocean_assert(width > 0);
905 ocean_assert(key > iLower->first);
906
907 TFactor interpolationFactor = TFactor(key - iLower->first) / width;
908 ocean_assert(interpolationFactor >= TFactor(0) && interpolationFactor <= TFactor(1));
909
910 return interpolationFunction(iLower->second, iHigher->second, interpolationFactor);
911}
912
913template <typename TKey, typename TValue, typename TFactor>
919
920template <typename TKey, typename TValue, typename TFactor>
922{
923 if (this != &object)
924 {
925 valueMap_ = std::move(object.valueMap_);
926 }
927
928 return *this;
929}
930
931template <typename TKey, typename TValue, typename TFactor>
933{
934 return valueMap_ == object.valueMap_;
935}
936
937template <typename TKey, typename TValue, typename TFactor>
939{
940 return !(*this == object);
941}
942
943template <typename TKey, typename TValue, typename TFactor>
945{
946 return value(key);
947}
948
949}
950
951#endif // META_OCEAN_MATH_INTERPOLATION_H
This class implements a 4x4 homogeneous transformation matrix using floating point values with the pr...
Definition HomogenousMatrix4.h:110
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition HomogenousMatrix4.h:1806
bool decompose(VectorT3< T > &translation, QuaternionT< T > &rotation, VectorT3< T > &scale, VectorT3< T > &shear) const
Decomposes the transformation matrix into translation, rotation, scale and shear parameters.
Definition HomogenousMatrix4.h:1407
This class implements a helper linear interpolation helper class allowing to overload the interpolati...
Definition Interpolation.h:38
static T interpolate(const T &v0, const T &v1, const TFactor &t)
Performs a linear interpolation between two values.
Definition Interpolation.h:382
This class implements data interpolation functions.
Definition Interpolation.h:29
static T cubic(const T &v0, const T &v1, const T &v2, const T &v3, const TFactor &t)
Performs a cubic (Catmull-Rom) interpolation between mainly two values while two further supporting p...
Definition Interpolation.h:644
static T linear(const T &v0, const T &v1, const TFactor &t)
Performs a linear interpolation between two values.
Definition Interpolation.h:522
static VectorT3< T > spherical(const VectorT3< T > &v0, const VectorT3< T > &v1, const TFactor &t)
Performs a spherical linear interpolation (SLERP) between two unit vectors.
Definition Interpolation.h:655
static T bilinear(const T &v00, const T &v01, const T &v10, const T &v11, const TFactor &tx, const TFactor &ty)
Performs a bi-linear interpolation between four values within a 2x2 neighborhood.
Definition Interpolation.h:539
static T lagrange2(const TKey &x0, const T &y0, const TKey &x1, const T &y1, const TKey &x)
Performs a Lagrange interpolation for a polynomial with degree 2.
Definition Interpolation.h:678
static T lagrange3(const TKey &x0, const T &y0, const TKey &x1, const T &y1, const TKey &x2, const T &y2, const TKey &x)
Performs a Lagrange interpolation for a polynomial with degree 3.
Definition Interpolation.h:686
This class implements an interpolation map allowing to determine an interpolated value between severa...
Definition Interpolation.h:182
void clear()
Clears all elements (pairs of keys and values) of this interpolation map object.
Definition Interpolation.h:742
TValue & value(const TKey &key)
Returns the value of this interpolation map object defined by a corresponding key.
Definition Interpolation.h:772
bool operator==(const InterpolationMap< TKey, TValue, TFactor > &object) const
Returns whether two interpolation objects are equal.
Definition Interpolation.h:932
TValue(*)(const TValue &, const TValue &, const TFactor &) LinearInterpolationFunction
Definition of a function pointer for a function providing a linear interpolation.
Definition Interpolation.h:196
const ValueMap & interpolationMap() const
Returns the entire internal interpolation map.
Definition Interpolation.h:748
bool isEmpty() const
Returns whether this interpolation map object is empty.
Definition Interpolation.h:736
InterpolationMap()
Default constructor.
Definition Interpolation.h:696
void setInterpolationMap(const ValueMap &interpolationMap)
Sets or changes the entire internal interpolation map.
Definition Interpolation.h:754
InterpolationMap< TKey, TValue, TFactor > & operator=(const InterpolationMap< TKey, TValue, TFactor > &object)
Assign operator.
Definition Interpolation.h:914
bool hasValue(const TKey &key) const
Returns whether this interpolation map object holds a value for a specified key.
Definition Interpolation.h:766
std::map< TKey, TValue > ValueMap
Definition of a map mapping keys to values.
Definition Interpolation.h:188
bool remove(const TKey &key)
Removes an elements (pair of key and value) from this interpolation map object.
Definition Interpolation.h:778
bool insert(const TKey &key, const TValue &value, const bool forceOverwrite=false)
Inserts a new pair of key and value to this map object.
Definition Interpolation.h:784
TValue linear(const TKey &key) const
Returns the linear interpolation of the stored values for a given key.
Definition Interpolation.h:822
bool operator!=(const InterpolationMap< TKey, TValue, TFactor > &object) const
Returns whether two interpolation objects are not equal.
Definition Interpolation.h:938
size_t size() const
Returns the number of elements (pairs of keys and values) of this interpolation map.
Definition Interpolation.h:730
ValueMap valueMap_
Map mapping keys to values.
Definition Interpolation.h:377
TValue & operator[](const TKey &key)
Returns the value of this interpolation map object defined by a corresponding key.
Definition Interpolation.h:944
This class provides basic numeric functionalities.
Definition Numeric.h:57
static constexpr bool isInsideRange(const T lower, const T value, const T upper, const T epsilon=NumericT< T >::eps())
Returns whether a value lies between a given range up to a provided epsilon border.
Definition Numeric.h:2881
VectorT3< T > translation() const
Returns the translation of this pose.
Definition Pose.h:422
QuaternionT< T > orientation() const
Returns the orientation of this pose.
This class implements a unit quaternion rotation.
Definition Quaternion.h:100
bool isValid() const
Returns whether this quaternion is a valid unit quaternion.
Definition Quaternion.h:882
QuaternionT< T > slerp(const QuaternionT< T > &quaternion, T factor) const
Spherical linear interpolation between two quaternions.
Definition Quaternion.h:848
This class implements a axis-angle rotation using floating point values.
Definition Rotation.h:73
static RotationT< T > left_R_right(const VectorT3< T > &left, const VectorT3< T > &right)
Returns a rotation object based on two given unit vectors.
Definition Rotation.h:705
VectorT3< T > axis() const
Returns the axis of the rotation.
Definition Rotation.h:643
T angle() const
Returns the angle of the rotation.
Definition Rotation.h:649
bool isValid() const
Returns whether this rotation has valid parameters.
Definition Rotation.h:547
This class implements a vector with two elements.
Definition Vector2.h:96
This class implements a vector with three elements.
Definition Vector3.h:97
bool isUnit(const T eps=NumericT< T >::eps()) const
Returns whether this vector is a unit vector (whether the vector has the length 1).
Definition Vector3.h:873
PoseT< Scalar > Pose
Definition of the Pose object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag either with sing...
Definition Pose.h:31
The namespace covering the entire Ocean framework.
Definition Accessor.h:15