TurtleBrains  0.3.5
High quality, portable, C++ framework for rapid 2D game development.
tb_interpolation.hpp
1 
9 #ifndef TurtleBrains_Interpolation_hpp
10 #define TurtleBrains_Interpolation_hpp
11 
12 #include <turtle_brains/math/tb_math.hpp>
13 #include <turtle_brains/math/tb_constants.hpp>
14 
15 namespace TurtleBrains
16 {
17  namespace Math
18  {
19  namespace Interpolation // Tweening / Easing
20  {
21 
22  enum class InterpolationMode
23  {
24  Linear,
25  InSquared,
26  OutSquared,
27  InOutSquared,
28 
29  InCubic,
30  OutCubic,
31  InOutCubic,
32 
33  InQuartic,
34  OutQuartic,
35  InOutQuartic,
36 
37  InQuintic,
38  OutQuintic,
39  InOutQuintic,
40 
41  InExponential,
42  OutExponential,
43  InOutExponential,
44 
45  InSine,
46  OutSine,
47  InOutSine,
48 
49  //Circular,
50  //Back,
51  InElastic,
52  OutElastic,
53  InOutElastic,
54 
55  InBounce,
56  OutBounce,
57  InOutBounce,
58  };
59 
67  template<typename ScalarType> inline constexpr ScalarType Linear(const ScalarType percentage)
68  {
69  return percentage;
70  }
71 
85  template<typename Type, typename ScalarType> constexpr Type Linear(const ScalarType percentage, const Type& start, const Type& end)
86  {
87  return ((end - start) * percentage) + start;
88  }
89 
90 
99  template<typename ScalarType> constexpr ScalarType Squared(const ScalarType percentage)
100  {
101  return percentage * percentage;
102  }
103 
116  template<typename Type, typename ScalarType> Type Squared(const ScalarType percentage, const Type& start, const Type& end)
117  {
118  return ((end - start) * Squared(percentage)) + start;
119  }
120 
127  template<typename ScalarType> constexpr ScalarType Cubic(const ScalarType percentage)
128  {
129  return percentage * percentage * percentage;
130  }
131 
144  template<typename Type, typename ScalarType> Type Cubic(const ScalarType percentage, const Type& start, const Type& end)
145  {
146  return ((end - start) * Cubic(percentage)) + start;
147  }
148 
155  template<typename ScalarType> constexpr ScalarType Quartic(const ScalarType percentage)
156  {
157  return percentage * percentage * percentage * percentage;
158  }
159 
169  template<typename Type, typename ScalarType> Type Quartic(const ScalarType percentage, const Type& start, const Type& end)
170  {
171  return ((end - start) * Quartic(percentage)) + start;
172  }
173 
180  template<typename ScalarType> constexpr ScalarType Quintic(const ScalarType percentage)
181  {
182  return percentage * percentage * percentage * percentage * percentage;
183  }
184 
194  template<typename Type, typename ScalarType> Type Quintic(const ScalarType percentage, const Type& start, const Type& end)
195  {
196  return ((end - start) * Quintic(percentage)) + start;
197  }
198 
205  template<typename ScalarType> ScalarType Exponential(const ScalarType percentage)
206  {
207  return std::pow(ScalarType(2.0), ScalarType(10.0) * (percentage - ScalarType(1.0)));
208  }
209 
219  template<typename Type, typename ScalarType> Type Exponential(const ScalarType percentage, const Type& start, const Type& end)
220  {
221  return ((end - start) * Exponential(percentage)) + start;
222  }
223 
230  template<typename ScalarType> ScalarType Sine(const ScalarType percentage)
231  { //Sin in from http://gizma.com/easing/#sin1 where t/d = percentage, c = 1, b = 0 (time, begin, change, distance)
232  return ScalarType(1.0) - cos(percentage * tbMath::Pi<ScalarType>() / ScalarType(2.0));
233  }
234 
247  template<typename Type, typename ScalarType> Type Sine(const ScalarType percentage, const Type& start, const Type& end)
248  {
249  return ((end - start) * Sine(percentage)) + start;
250  }
251 
260  template<typename ScalarType> ScalarType Elastic(const ScalarType percentage)
261  { //https://github.com/vrld/hump/blob/master/timer.lua#L128L131
262  const ScalarType amplitude = ScalarType(1.0);
263  const ScalarType period = ScalarType(0.3);
264  return (-amplitude * std::sin(tbMath::kTwoPi / period * (percentage - ScalarType(1.0)) -
265  std::asin(ScalarType(1.0) / amplitude))) * std::pow(ScalarType(2.0), (ScalarType(10.0) * (percentage - ScalarType(1.0))));
266  }
267 
268  template<typename ScalarType> ScalarType Elastic(const ScalarType percentage, const ScalarType amplitude, const ScalarType period)
269  { //https://github.com/vrld/hump/blob/master/timer.lua#L128L131
270  return (-amplitude * std::sin(tbMath::kTwoPi / period * (percentage - ScalarType(1.0)) -
271  std::asin(ScalarType(1.0) / amplitude))) * std::pow(ScalarType(2.0), (ScalarType(10.0) * (percentage - ScalarType(1.0))));
272  }
273 
285  template<typename Type, typename ScalarType> Type Elastic(const ScalarType percentage, const Type& start, const Type& end)
286  {
287  return ((end - start) * Elastic(percentage)) + start;
288  }
289 
296  template<typename ScalarType> ScalarType Bounce(const ScalarType percentage)
297  { //https://github.com/vrld/hump/blob/master/timer.lua#L123-L126
298  const ScalarType a = ScalarType(7.5625);
299  const ScalarType b = ScalarType(1.0f / 2.75);
300 
301  return tbMath::Minimum(a * percentage * percentage,
302  tbMath::Minimum(a * (percentage - ScalarType(1.5) * b) * (percentage - ScalarType(1.5) * b) + ScalarType(0.75),
303  tbMath::Minimum(a * (percentage - ScalarType(2.25) * b) * (percentage - ScalarType(2.25) * b) + ScalarType(0.9375),
304  a * (percentage - ScalarType(2.625) * b) * (percentage - ScalarType(2.625) * b) + ScalarType(0.984375))));
305  }
306 
319  template<typename Type, typename ScalarType> Type Bounce(const ScalarType percentage, const Type& start, const Type& end)
320  {
321  return ((end - start) * Bounce(percentage)) + start;
322  }
323 
324 
325  //typedef float(*InterpolationFunction)(float);
326  template<typename ScalarType> using InterpolationFunction = ScalarType(*)(ScalarType);
327 
328  template<typename ScalarType> ScalarType Out(const ScalarType percentage, InterpolationFunction<ScalarType> interpolation)
329  {
330  return ScalarType(1.0) - interpolation(ScalarType(1.0) - percentage);
331  }
332 
333  template<typename Type, typename ScalarType> Type Out(const ScalarType percentage, const Type& start,
334  const Type& end, InterpolationFunction<ScalarType> interpolation)
335  {
336  return ((end - start) * Out(percentage, interpolation)) + start;
337  }
338 
339  template<typename ScalarType> ScalarType InOut(const ScalarType percentage, InterpolationFunction<ScalarType> interpolation)
340  {
341  return ScalarType(0.5) * ((percentage < ScalarType(0.5)) ? interpolation(ScalarType(2.0) * percentage) :
342  ScalarType(1.0) + Out(ScalarType(2.0) * percentage - ScalarType(1.0), interpolation));
343  }
344 
345  template<typename Type, typename ScalarType> Type InOut(const ScalarType percentage, const Type& start,
346  const Type& end, InterpolationFunction<ScalarType> interpolation)
347  {
348  return ((end - start) * InOut(percentage, interpolation)) + start;
349  }
350 
351  template<typename ScalarType> ScalarType Interpolate(const ScalarType percentage, const InterpolationMode& mode)
352  {
353  switch (mode)
354  {
355  case InterpolationMode::Linear: return Linear(percentage);
356  case InterpolationMode::InSquared: return Squared(percentage);
357  case InterpolationMode::OutSquared: return Out(percentage, Squared);
358  case InterpolationMode::InOutSquared: return InOut(percentage, &Squared);
359 
360  case InterpolationMode::InCubic: return Cubic(percentage);
361  case InterpolationMode::OutCubic: return Out(percentage, Cubic);
362  case InterpolationMode::InOutCubic: return InOut(percentage, &Cubic);
363 
364  case InterpolationMode::InQuartic: return Quartic(percentage);
365  case InterpolationMode::OutQuartic: return Out(percentage, Quartic);
366  case InterpolationMode::InOutQuartic: return InOut(percentage, &Quartic);
367 
368  case InterpolationMode::InQuintic: return Quintic(percentage);
369  case InterpolationMode::OutQuintic: return Out(percentage, Quintic);
370  case InterpolationMode::InOutQuintic: return InOut(percentage, &Quintic);
371 
372  case InterpolationMode::InExponential: return Exponential(percentage);
373  case InterpolationMode::OutExponential: return Out(percentage, Exponential);
374  case InterpolationMode::InOutExponential: return InOut(percentage, &Exponential);
375 
376  case InterpolationMode::InSine: return Sine(percentage);
377  case InterpolationMode::OutSine: return Out(percentage, Sine);
378  case InterpolationMode::InOutSine: return InOut(percentage, &Sine);
379 
380  case InterpolationMode::InElastic: return Elastic(percentage);
381  case InterpolationMode::OutElastic: return Out(percentage, Elastic);
382  case InterpolationMode::InOutElastic: return InOut(percentage, &Elastic);
383 
384  case InterpolationMode::InBounce: return Bounce(percentage);
385  case InterpolationMode::OutBounce: return Out(percentage, Bounce);
386  case InterpolationMode::InOutBounce: return InOut(percentage, &Bounce);
387  }
388 
389  tb_error("tbInternalError: Unhandled case for InterpolationMode: %d\n", mode);
390  return ScalarType(0.0);
391  }
392 
393  template<typename Type, typename ScalarType> Type Interpolate(const ScalarType percentage,
394  const Type& start, const Type& end, const InterpolationMode& mode)
395  {
396  return ((end - start) * Interpolate(percentage, mode)) + start;
397  }
398 
399 
408  template<typename ScalarType> ScalarType SmoothStep(const ScalarType percentage)
409  {
410  return (percentage * percentage * (ScalarType(3.0) - ScalarType(2.0) * percentage));
411  }
412 
426  template<typename Type, typename ScalarType> Type SmoothStep(const ScalarType percentage, const Type& start, const Type& end)
427  {
428  const float smoothPercentage = SmoothStep(percentage);
429  return (start * smoothPercentage) + (end * (ScalarType(1.0) - smoothPercentage));
430  }
431 
450  template<typename Type, typename ScalarType> Type CubicBezier(const ScalarType percentage,
451  const Type& a, const Type& b, const Type& c, const Type& d)
452  {
453  //In this version A is start, B is final, C and D are control points.
454  //const Type tempA = Linear(percentage, a, c);
455  //const Type tempB = Linear(percentage, c, d);
456  //const Type tempC = Linear(percentage, d, b);
457  //The following A is start, B and C are control points and D is final.
458  const Type tempA = Linear(percentage, a, b);
459  const Type tempB = Linear(percentage, b, c);
460  const Type tempC = Linear(percentage, c, d);
461 
462  const Type tempAA = Linear(percentage, tempA, tempB);
463  const Type tempBB = Linear(percentage, tempB, tempC);
464 
465  return Linear(percentage, tempAA, tempBB);
466  }
467 
482  template<typename Type, typename ScalarType> Type CubicBezierTangent(const ScalarType percentage,
483  const Type& a, const Type& b, const Type& c, const Type& d)
484  { //Source: http://stackoverflow.com/questions/4089443/find-the-tangent-of-a-point-on-a-cubic-bezier-curve-on-an-iphone
485  const ScalarType kThree = ScalarType(3.0);
486  const Type c1(d - (kThree * c) + (kThree * b) - a);
487  const Type c2((kThree * c) - (ScalarType(6.0) * b) + (kThree * a));
488  const Type c3((kThree * b) - (kThree * a));
489  //const float c4(a);
490 
491  return ((c1 * (kThree * percentage * percentage)) + (c2 * (ScalarType(2.0) * percentage)) + c3);
492  }
493 
494  }; /* namespace Interpolation */
495  }; /* namespace Math */
496 }; /* namespace TurtleBrains */
497 
498 namespace tbMath = TurtleBrains::Math;
499 
500 #endif /* TurtleBrains_Interpolation_hpp */
#define tb_error(message,...)
Definition: tb_error.hpp:23
Contains objects and functions for dealing with Vector and Matrix math.
constexpr const Type & Minimum(const Type &leftValue, const Type &rightValue) noexcept
Definition: tb_math.hpp:42
Here is some information about the primary namespace.
Definition: tb_application_dialog.hpp:22