Ocean
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"
15 #include "ocean/math/Quaternion.h"
16 #include "ocean/math/Rotation.h"
17 
18 #include <map>
19 
20 namespace 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 Lagrange interpolation for a polynomial with degree 2.
130  * @param x0 Position of the first supporting value, must not be identical with x1
131  * @param y0 First supporting value
132  * @param x1 Position of the second supporting value, must not be identical with x0
133  * @param y1 Second supporting value
134  * @param x Position for that the interpolation value is requested
135  * @return Resulting Lagrange intgerpolatino value
136  * @tparam T Data type of the supporting values
137  * @tparam TKey Data type of the positions of the supporting values
138  */
139  template <typename T, typename TKey>
140  static T lagrange2(const TKey& x0, const T& y0, const TKey& x1, const T& y1, const TKey& x);
141 
142  /**
143  * Performs a Lagrange interpolation for a polynomial with degree 3.
144  * @param x0 Position of the first supporting value, must not be identical with x1 or x2
145  * @param y0 First supporting value
146  * @param x1 Position of the second supporting value, must not be identical with x0 or x2
147  * @param y1 Second supporting value
148  * @param x2 Position of the third supporting value, must not be identical with x0 or x1
149  * @param y2 Third supporting value
150  * @param x Position for that the interpolation value is requested
151  * @return Resulting Lagrange intgerpolatino value
152  * @tparam T Data type of the supporting values
153  * @tparam TKey Data type of the positions of the supporting values
154  */
155  template <typename T, typename TKey>
156  static T lagrange3(const TKey& x0, const T& y0, const TKey& x1, const T& y1, const TKey& x2, const T& y2, const TKey& x);
157 };
158 
159 /**
160  * This class implements an interpolation map allowing to determine an interplated value between several individual key values.
161  * @tparam TKey The data type of the stored keys
162  * @tparam TValue The data type of the stored values
163  * @tparam TFactor The data type of the interpolation factor
164  * @ingroup math
165  */
166 template <typename TKey, typename TValue, typename TFactor>
168 {
169  public:
170 
171  /**
172  * Definition of a map mapping keys to values.
173  */
174  typedef std::map<TKey, TValue> ValueMap;
175 
176  /**
177  * Definition of a function pointer for a function providing a linear interpolation.
178  * The first parameter defines the first interpolation value.<br>
179  * The second parameter defines the second interpolation value.<br>
180  * The third parameter defines the interpolation factor, with range [0, 1].<br>
181  */
182  typedef TValue (*LinearInterpolationFunction)(const TValue&, const TValue&, const TFactor&);
183 
184  public:
185 
186  /**
187  * Default constructor.
188  */
189  inline InterpolationMap();
190 
191  /**
192  * Copy constructor for interpolation maps.
193  * @param interpolationMap The interpolation map to copy
194  */
196 
197  /**
198  * Move constructor for interpolation maps.
199  * @param interpolationMap The interpolation map to move
200  */
202 
203  /**
204  * Creates a new interpolation map object by a given value map.
205  * @param valueMap The value map that will be stored in this object
206  */
207  inline InterpolationMap(const ValueMap& valueMap);
208 
209  /**
210  * Creates a new interpolation map object by a given value map.
211  * @param valueMap The value map that will be moved to this object
212  */
213  inline InterpolationMap(ValueMap&& valueMap);
214 
215  /**
216  * Returns the number of elements (pairs of keys and values) of this interpolation map.
217  * @return The number of stored elements
218  */
219  inline size_t size() const;
220 
221  /**
222  * Returns whether this interpolation map object is empty.
223  * @return True, if so
224  */
225  inline bool isEmpty() const;
226 
227  /**
228  * Clears all elements (pairs of keys and values) of this interpolation map object.
229  */
230  inline void clear();
231 
232  /**
233  * Returns the entire internal interpolation map.
234  * @return Interpolation map of this object
235  */
236  inline const ValueMap& interpolationMap() const;
237 
238  /**
239  * Sets or changes the entire internal interpolation map.
240  * @param interpolationMap The interpolation map that will replace the current one
241  */
242  inline void setInterpolationMap(const ValueMap& interpolationMap);
243 
244  /**
245  * Sets or changes the entire internal interpolation map.
246  * @param interpolationMap The interpolation map that will be moved to this object
247  */
249 
250  /**
251  * Returns whether this interpolation map object holds a value for a specified key.
252  * @param key Key which is checked
253  * @return True, if so
254  */
255  inline bool hasValue(const TKey& key) const;
256 
257  /**
258  * Returns the value of this interpolation map object defined by a corresponding key.
259  * If no value exists for this key, the pair of key and value is inserted and the default value is returned.<br>
260  * @param key Key for that the value is returned
261  * @return Value that corresponds to the specified key
262  * @see hasValue().
263  */
264  inline TValue& value(const TKey& key);
265 
266  /**
267  * Removes an elements (pair of key and value) from this interpolation map object.
268  * @param key The key of the element to be removed
269  * @return True, if the element existed
270  */
271  inline bool remove(const TKey& key);
272 
273  /**
274  * Inserts a new pair of key and value to this map object.
275  * @param key New key to be inserted
276  * @param value Corresponding value to be instered
277  * @param forceOverwrite True, if an already existing pair with same key will be overwritten by the given pair
278  * @return True, if the given pair has been inserted
279  */
280  inline bool insert(const TKey& key, const TValue& value, const bool forceOverwrite = false);
281 
282  /**
283  * Inserts a new pair of key and value to this map object.
284  * @param key New key to be inserted
285  * @param value Corresponding value to be moved
286  * @param forceOverwrite True, if an already existing pair with same key will be overwritten by the given pair
287  * @return True, if the given pair has been inserted
288  */
289  inline bool insert(const TKey& key, TValue&& value, const bool forceOverwrite = false);
290 
291  /**
292  * Returns the linear interpolation of the stored values for a given key.
293  * @param key The key of the value that will be (interpolated and) returned
294  * @return Resulting interpolated value
295  */
296  inline TValue linear(const TKey& key) const;
297 
298  /**
299  * Returns the linear interpolation of the stored values for a given key and a given interpolation function.
300  * @param key The key of the value that will be (interpolated and) returned
301  * @param interpolationFunction An explicit interpolation function that is applied
302  * @return Resulting interpolated value
303  */
304  inline TValue linear(const TKey& key, const LinearInterpolationFunction interpolationFunction) const;
305 
306  /**
307  * Returns the linear interpolation of given values for a given key.
308  * @param valueMap The map of values that are used for interpolation
309  * @param key The key of the value that will be (interpolated and) returned
310  * @return Resulting interpolated value
311  */
312  static TValue linear(const ValueMap& valueMap, const TKey& key);
313 
314  /**
315  * Returns the linear interpolation of given values for a given key and a given interpolation function.
316  * @param valueMap The map of values that are used for interpolation
317  * @param key The key of the value that will be (interpolated and) returned
318  * @param interpolationFunction An explicit interpolation function that is applied
319  * @return Resulting interpolated value
320  */
321  static TValue linear(const ValueMap& valueMap, const TKey& key, const LinearInterpolationFunction interpolationFunction);
322 
323  /**
324  * Assign operator.
325  * @param object The interpolation map object which will be assigned to this object
326  * @return Reference to this object
327  */
329 
330  /**
331  * Move operator.
332  * @param object The interpolation map object which will be moved to this object
333  * @return Reference to this object
334  */
336 
337  /**
338  * Returns whether two interpolation objects are equal.
339  * @param object Second interpoation object
340  * @return True, if so
341  */
342  inline bool operator==(const InterpolationMap<TKey, TValue, TFactor>& object) const;
343 
344  /**
345  * Returns whether two interpolation objects are not equal.
346  * @param object Second interpoation object
347  * @return True, if so
348  */
349  inline bool operator!=(const InterpolationMap<TKey, TValue, TFactor>& object) const;
350 
351  /**
352  * Returns the value of this interpolation map object defined by a corresponding key.
353  * If no value exists for this key, the pair of key and value is inserted and the default value is returned.<br>
354  * @param key Key for that the value is returned
355  * @return Value that corresponds to the specified key
356  * @see value(), hasValue().
357  */
358  inline TValue& operator[](const TKey& key);
359 
360  protected:
361 
362  /// Map mapping keys to values.
364 };
365 
366 template <typename T>
367 template <typename TFactor>
368 inline T Interpolation::LinearInterpolation<T>::interpolate(const T& v0, const T& v1, const TFactor& t)
369 {
370  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
371 
372  return v0 * (TFactor(1) - t) + v1 * t;
373 }
374 
375 template <>
376 template <>
377 inline float Interpolation::LinearInterpolation<float>::interpolate(const float& v0, const float& v1, const double& t)
378 {
379  ocean_assert(NumericT<double>::isInsideRange(0.0, t, 1.0));
380 
381  return float(v0 * (1.0 - t)) + float(v1 * t);
382 }
383 
384 template <>
385 template <typename TFactor>
387 {
388  ocean_assert(v0.isValid() && v1.isValid());
389  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
390 
391  VectorT3<float> translation0(0, 0, 0), translation1(0, 0, 0);
392  VectorT3<float> scale0(0, 0, 0), scale1(0, 0, 0);
393  VectorT3<float> shear0(0, 0, 0), shear1(0, 0, 0);
394 
395  QuaternionT<float> rotation0, rotation1;
396 
397  v0.decompose(translation0, rotation0, scale0, shear0);
398  v1.decompose(translation1, rotation1, scale1, shear1);
399 
400  return HomogenousMatrixT4<float>(linear(translation0, translation1, t), linear(rotation0, rotation1, t), linear(scale0, scale1, t), linear(shear0, shear1, t));
401 }
402 
403 template <>
404 template <typename TFactor>
406 {
407  ocean_assert(v0.isValid() && v1.isValid());
408  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
409 
410  VectorT3<double> translation0(0, 0, 0), translation1(0, 0, 0);
411  VectorT3<double> scale0(0, 0, 0), scale1(0, 0, 0);
412  VectorT3<double> shear0(0, 0, 0), shear1(0, 0, 0);
413 
414  QuaternionT<double> rotation0, rotation1;
415 
416  v0.decompose(translation0, rotation0, scale0, shear0);
417  v1.decompose(translation1, rotation1, scale1, shear1);
418 
419  return HomogenousMatrixT4<double>(linear(translation0, translation1, t), linear(rotation0, rotation1, t), linear(scale0, scale1, t), linear(shear0, shear1, t));
420 }
421 
422 template <>
423 template <typename TFactor>
424 inline 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)
425 {
426  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
427 
428  return std::make_pair(linear(v0.first, v1.first, t), linear(v0.second, v1.second, t));
429 }
430 
431 template <>
432 template <typename TFactor>
433 inline 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)
434 {
435  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
436 
437  return std::make_pair(linear(v0.first, v1.first, t), linear(v0.second, v1.second, t));
438 }
439 
440 template <>
441 template <typename TFactor>
442 inline 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)
443 {
444  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
445 
446  return std::make_pair(linear(v0.first, v1.first, t), linear(v0.second, v1.second, t));
447 }
448 
449 template <>
450 template <typename TFactor>
451 inline 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)
452 {
453  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
454 
455  return std::make_pair(linear(v0.first, v1.first, t), linear(v0.second, v1.second, t));
456 }
457 
458 template <>
459 template <typename TFactor>
460 inline Pose Interpolation::LinearInterpolation<Pose>::interpolate(const Pose& v0, const Pose& v1, const TFactor& t)
461 {
462  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
463 
464  return Pose(v0.translation() * (TFactor(1) - t) + v1.translation() * t, v0.orientation().slerp(v1.orientation(), t));
465 }
466 
467 template <>
468 template <typename TFactor>
470 {
471  ocean_assert(v0.isValid() && v1.isValid());
472  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
473 
474  return v0.slerp(v1, float(t));
475 }
476 
477 template <>
478 template <typename TFactor>
480 {
481  ocean_assert(v0.isValid() && v1.isValid());
482  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
483 
484  return v0.slerp(v1, double(t));
485 }
486 
487 template <>
488 template <typename TFactor>
490 {
491  ocean_assert(v0.isValid() && v1.isValid());
492  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
493 
494  return RotationT<float>(QuaternionT<float>(v0).slerp(QuaternionT<float>(v1), t));
495 }
496 
497 template <>
498 template <typename TFactor>
500 {
501  ocean_assert(v0.isValid() && v1.isValid());
502  ocean_assert(NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
503 
505 }
506 
507 template <typename T, typename TFactor>
508 inline T Interpolation::linear(const T& v0, const T& v1, const TFactor& t)
509 {
510  ocean_assert(t >= TFactor(0) && t <= TFactor(1));
511 
512  if (t <= TFactor(0))
513  {
514  return v0;
515  }
516  if (t >= TFactor(1))
517  {
518  return v1;
519  }
520 
521  return LinearInterpolation<T>::template interpolate<TFactor>(v0, v1, t);
522 }
523 
524 template <typename T, typename TFactor>
525 inline T Interpolation::bilinear(const T& v00, const T& v01, const T& v10, const T& v11, const TFactor& tx, const TFactor& ty)
526 {
527  return linear(linear(v00, v01, tx), linear(v10, v11, tx), ty);
528 }
529 
530 template <typename T, typename TFactor>
531 inline 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)
532 {
533  ocean_assert(valid00 || valid01 || valid10 || valid11);
534 
535  ocean_assert(valid00 == 1 || valid00 == 0);
536  ocean_assert(valid01 == 1 || valid01 == 0);
537  ocean_assert(valid10 == 1 || valid10 == 0);
538  ocean_assert(valid11 == 1 || valid11 == 0);
539 
540  const unsigned int state = (unsigned int)(valid00) | ((unsigned int)(valid01) << 8) | ((unsigned int)(valid10) << 16) | ((unsigned int)(valid11) << 24);
541 
542  switch (state)
543  {
544  // 1 1
545  // 1 1
546  case 0x01010101:
547  return bilinear(v00, v01, v10, v11, tx, ty);
548 
549  // 0 1
550  // 1 1
551  case 0x01010100:
552  return linear(v01, linear(v10, v11, tx), ty);
553 
554  // 1 0
555  // 1 1
556  case 0x01010001:
557  return linear(v00, linear(v10, v11, tx), ty);
558 
559  // 1 1
560  // 0 1
561  case 0x01000101:
562  return linear(linear(v00, v01, tx), v11, ty);
563 
564  // 1 1
565  // 1 0
566  case 0x00010101:
567  return linear(linear(v00, v01, tx), v10, ty);
568 
569  // 0 0
570  // 1 1
571  case 0x01010000:
572  return linear(v10, v11, tx);
573 
574  // 1 0
575  // 1 0
576  case 0x00010001:
577  return linear(v00, v10, ty);
578 
579  // 1 1
580  // 0 0
581  case 0x00000101:
582  return linear(v00, v01, tx);
583 
584  // 0 1
585  // 0 1
586  case 0x01000100:
587  return linear(v01, v11, ty);
588 
589  // 0 1
590  // 1 0
591  case 0x00010100:
592  // position on the diagonal
593  return linear(v10, v01, Vector2(tx, 1 - ty).length() * Scalar(0.70710678118654752440084436210485));
594 
595  // 1 0
596  // 0 1
597  case 0x01000001:
598  // position on the diagonal
599  return linear(v00, v11, Vector2(tx, ty).length() * Scalar(0.70710678118654752440084436210485));
600 
601  // 1 0
602  // 0 0
603  case 0x00000001:
604  return v00;
605 
606  // 0 1
607  // 0 0
608  case 0x00000100:
609  return v01;
610 
611  // 0 0
612  // 1 0
613  case 0x00010000:
614  return v10;
615 
616  // 0 0
617  // 0 1
618  case 0x01000000:
619  return v11;
620  }
621 
622  ocean_assert(false && "Invalid interpolation statement!");
623  return T();
624 }
625 
626 template <typename T, typename TFactor>
627 inline T Interpolation::cubic(const T& v0, const T& v1, const T& v2, const T& v3, const TFactor& t)
628 {
629  ocean_assert((std::is_same<T, float>::value) ? NumericT<TFactor>::isInsideWeakRange(TFactor(0), t, TFactor(1)) : NumericT<TFactor>::isInsideRange(TFactor(0), t, TFactor(1)));
630 
631  return (v0 * TFactor(-0.5) + v1 * TFactor(1.5) - v2 * TFactor(1.5) + v3 * TFactor(0.5)) * t * t * t
632  + (v0 - v1 * TFactor(2.5) + v2 * TFactor(2) - v3 * TFactor(0.5)) * t * t
633  + (v0 * TFactor(-0.5) + v2 * TFactor(0.5)) * t
634  + v1;
635 }
636 
637 template <typename T, typename TKey>
638 T Interpolation::lagrange2(const TKey& x0, const T& y0, const TKey& x1, const T& y1, const TKey& x)
639 {
640  ocean_assert(NumericT<TKey>::isNotEqual(x0, x1));
641 
642  return (y0 * (x1 - x) + y1 * (x - x0)) * (TKey(1) / (x1 - x0));
643 }
644 
645 template <typename T, typename TKey>
646 T Interpolation::lagrange3(const TKey& x0, const T& y0, const TKey& x1, const T& y1, const TKey& x2, const T& y2, const TKey& x)
647 {
648  ocean_assert(NumericT<TKey>::isNotEqual(x0, x1) && NumericT<TKey>::isNotEqual(x0, x2) && NumericT<TKey>::isNotEqual(x1, 2));
649 
650  return y0 * ((x - x1) * (x - x2)) * (TKey(1) / ((x0 - x1) * (x0 - x2)))
651  + y1 * ((x - x0) * (x - x2)) * (TKey(1) / ((x1 - x0) * (x1 - x2)))
652  + y2 * ((x - x0) * (x - x1)) * (TKey(1) / ((x2 - x0) * (x2 - x1)));
653 }
654 
655 template <typename TKey, typename TValue, typename TFactor>
657 {
658  // nothing to do here
659 }
660 
661 template <typename TKey, typename TValue, typename TFactor>
663  interpolationValueMap(interpolationMap.interpolationValueMap)
664 {
665  // nothing to do here
666 }
667 
668 template <typename TKey, typename TValue, typename TFactor>
670  interpolationValueMap(std::move(interpolationMap.interpolationValueMap))
671 {
672  // nothing to do here
673 }
674 
675 template <typename TKey, typename TValue, typename TFactor>
677  interpolationValueMap(valueMap)
678 {
679  // nothing to do here
680 }
681 
682 template <typename TKey, typename TValue, typename TFactor>
684  interpolationValueMap(std::move(valueMap))
685 {
686  // nothing to do here
687 }
688 
689 template <typename TKey, typename TValue, typename TFactor>
691 {
692  return interpolationValueMap.size();
693 }
694 
695 template <typename TKey, typename TValue, typename TFactor>
697 {
698  return interpolationValueMap.empty();
699 }
700 
701 template <typename TKey, typename TValue, typename TFactor>
703 {
704  interpolationValueMap.clear();
705 }
706 
707 template <typename TKey, typename TValue, typename TFactor>
709 {
710  return interpolationValueMap;
711 }
712 
713 template <typename TKey, typename TValue, typename TFactor>
715 {
716  interpolationValueMap = interpolationMap;
717 }
718 
719 template <typename TKey, typename TValue, typename TFactor>
721 {
722  interpolationValueMap = std::move(interpolationMap);
723 }
724 
725 template <typename TKey, typename TValue, typename TFactor>
726 inline bool InterpolationMap<TKey, TValue, TFactor>::hasValue(const TKey& key) const
727 {
728  return interpolationValueMap.find(key) != interpolationValueMap.end();
729 }
730 
731 template <typename TKey, typename TValue, typename TFactor>
732 inline TValue& InterpolationMap<TKey, TValue, TFactor>::value(const TKey& key)
733 {
734  return interpolationValueMap[key];
735 }
736 
737 template <typename TKey, typename TValue, typename TFactor>
739 {
740  return interpolationValueMap.erase(key) != 0;
741 }
742 
743 template <typename TKey, typename TValue, typename TFactor>
744 inline bool InterpolationMap<TKey, TValue, TFactor>::insert(const TKey& key, const TValue& value, const bool forceOverwrite)
745 {
746  if (forceOverwrite)
747  {
748  interpolationValueMap[key] = value;
749  return true;
750  }
751 
752  if (interpolationValueMap.find(key) != interpolationValueMap.end())
753  {
754  return false;
755  }
756 
757  interpolationValueMap[key] = value;
758 
759  return true;
760 }
761 
762 template <typename TKey, typename TValue, typename TFactor>
763 inline bool InterpolationMap<TKey, TValue, TFactor>::insert(const TKey& key, TValue&& value, const bool forceOverwrite)
764 {
765  if (forceOverwrite)
766  {
767  interpolationValueMap[key] = std::move(value);
768  return true;
769  }
770 
771  if (interpolationValueMap.find(key) != interpolationValueMap.end())
772  {
773  return false;
774  }
775 
776  interpolationValueMap[key] = std::move(value);
777 
778  return true;
779 }
780 
781 template <typename TKey, typename TValue, typename TFactor>
782 inline TValue InterpolationMap<TKey, TValue, TFactor>::linear(const TKey& key) const
783 {
784  return linear(interpolationValueMap, key);
785 }
786 
787 template <typename TKey, typename TValue, typename TFactor>
788 inline TValue InterpolationMap<TKey, TValue, TFactor>::linear(const TKey& key, const LinearInterpolationFunction interpolationFunction) const
789 {
790  return linear(interpolationValueMap, key, interpolationFunction);
791 }
792 
793 template <typename TKey, typename TValue, typename TFactor>
794 TValue InterpolationMap<TKey, TValue, TFactor>::linear(const ValueMap& valueMap, const TKey& key)
795 {
796  if (valueMap.empty())
797  {
798  return TValue();
799  }
800 
801  const typename ValueMap::const_iterator iHigher = valueMap.lower_bound(key);
802 
803  // if the key is larger than the last key
804  if (iHigher == valueMap.end())
805  {
806  ocean_assert(valueMap.rbegin() != valueMap.rend());
807  return valueMap.rbegin()->second;
808  }
809 
810  // if the key is the first element
811  if (iHigher == valueMap.begin())
812  {
813  return iHigher->second;
814  }
815 
816  // we have at least one key in front of the higher key
817 
818  typename ValueMap::const_iterator iLower(iHigher);
819  iLower--;
820 
821  TFactor width = TFactor(iHigher->first - iLower->first);
822 
823  ocean_assert(width > 0);
824  ocean_assert(key > iLower->first);
825 
826  TFactor interpolationFactor = TFactor(key - iLower->first) / width;
827  ocean_assert(interpolationFactor >= TFactor(0) && interpolationFactor <= TFactor(1));
828 
829  return Interpolation::linear(iLower->second, iHigher->second, interpolationFactor);
830 }
831 
832 template <typename TKey, typename TValue, typename TFactor>
833 TValue InterpolationMap<TKey, TValue, TFactor>::linear(const ValueMap& valueMap, const TKey& key, const LinearInterpolationFunction interpolationFunction)
834 {
835  ocean_assert(interpolationFunction);
836 
837  if (valueMap.empty() || !interpolationFunction)
838  {
839  return TValue();
840  }
841 
842  const typename ValueMap::const_iterator iHigher = valueMap.lower_bound(key);
843 
844  // if the key is larger than the last key
845  if (iHigher == valueMap.end())
846  {
847  ocean_assert(valueMap.rbegin() != valueMap.rend());
848  return valueMap.rbegin()->second;
849  }
850 
851  // if the key is the first element
852  if (iHigher == valueMap.begin())
853  {
854  return iHigher->second;
855  }
856 
857  // we have at least one key in front of the higher key
858 
859  typename ValueMap::const_iterator iLower(iHigher);
860  iLower--;
861 
862  TFactor width = TFactor(iHigher->first - iLower->first);
863 
864  ocean_assert(width > 0);
865  ocean_assert(key > iLower->first);
866 
867  TFactor interpolationFactor = TFactor(key - iLower->first) / width;
868  ocean_assert(interpolationFactor >= TFactor(0) && interpolationFactor <= TFactor(1));
869 
870  return interpolationFunction(iLower->second, iHigher->second, interpolationFactor);
871 }
872 
873 template <typename TKey, typename TValue, typename TFactor>
875 {
876  interpolationValueMap = object.interpolationValueMap;
877  return *this;
878 }
879 
880 template <typename TKey, typename TValue, typename TFactor>
882 {
883  if (this != &object)
884  {
885  interpolationValueMap = std::move(object.interpolationValueMap);
886  }
887 
888  return *this;
889 }
890 
891 template <typename TKey, typename TValue, typename TFactor>
893 {
894  return interpolationValueMap == object.interpolationValueMap;
895 }
896 
897 template <typename TKey, typename TValue, typename TFactor>
899 {
900  return !(*this == object);
901 }
902 
903 template <typename TKey, typename TValue, typename TFactor>
905 {
906  return value(key);
907 }
908 
909 }
910 
911 #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:368
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:627
static T linear(const T &v0, const T &v1, const TFactor &t)
Performs a linear interpolation between two values.
Definition: Interpolation.h:508
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:525
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:638
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:646
This class implements an interpolation map allowing to determine an interplated value between several...
Definition: Interpolation.h:168
void clear()
Clears all elements (pairs of keys and values) of this interpolation map object.
Definition: Interpolation.h:702
std::map< TKey, TValue > ValueMap
Definition of a map mapping keys to values.
Definition: Interpolation.h:174
TValue & value(const TKey &key)
Returns the value of this interpolation map object defined by a corresponding key.
Definition: Interpolation.h:732
bool operator==(const InterpolationMap< TKey, TValue, TFactor > &object) const
Returns whether two interpolation objects are equal.
Definition: Interpolation.h:892
const ValueMap & interpolationMap() const
Returns the entire internal interpolation map.
Definition: Interpolation.h:708
bool isEmpty() const
Returns whether this interpolation map object is empty.
Definition: Interpolation.h:696
InterpolationMap()
Default constructor.
Definition: Interpolation.h:656
void setInterpolationMap(const ValueMap &interpolationMap)
Sets or changes the entire internal interpolation map.
Definition: Interpolation.h:714
InterpolationMap< TKey, TValue, TFactor > & operator=(const InterpolationMap< TKey, TValue, TFactor > &object)
Assign operator.
Definition: Interpolation.h:874
bool hasValue(const TKey &key) const
Returns whether this interpolation map object holds a value for a specified key.
Definition: Interpolation.h:726
ValueMap interpolationValueMap
Map mapping keys to values.
Definition: Interpolation.h:363
TValue(* LinearInterpolationFunction)(const TValue &, const TValue &, const TFactor &)
Definition of a function pointer for a function providing a linear interpolation.
Definition: Interpolation.h:182
bool remove(const TKey &key)
Removes an elements (pair of key and value) from this interpolation map object.
Definition: Interpolation.h:738
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:744
TValue linear(const TKey &key) const
Returns the linear interpolation of the stored values for a given key.
Definition: Interpolation.h:782
bool operator!=(const InterpolationMap< TKey, TValue, TFactor > &object) const
Returns whether two interpolation objects are not equal.
Definition: Interpolation.h:898
size_t size() const
Returns the number of elements (pairs of keys and values) of this interpolation map.
Definition: Interpolation.h:690
TValue & operator[](const TKey &key)
Returns the value of this interpolation map object defined by a corresponding key.
Definition: Interpolation.h:904
This class provides basic numeric functionalities.
Definition: Numeric.h:57
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:899
QuaternionT< T > slerp(const QuaternionT< T > &quaternion, T factor) const
Spherical linear interpolation between two quaternions.
Definition: Quaternion.h:865
This class implements a axis-angle rotation using floating point values.
Definition: Rotation.h:79
bool isValid() const
Returns whether this rotation has valid parameters.
Definition: Rotation.h:665
This class implements a vector with three elements.
Definition: Vector3.h:97
float Scalar
Definition of a scalar type.
Definition: Math.h:128
PoseT< Scalar > Pose
Definition of the Pose object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION flag either with sing...
Definition: Pose.h:31
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15