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  inline constexpr float Linear(float percentage)
68  {
69  return percentage;
70  }
71 
85  template <typename Type> constexpr Type Linear(float percentage, const Type& start, const Type& end)
86  {
87  return static_cast<Type>(((end - start) * percentage) + start);
88  }
89 
98  inline constexpr float Squared(float percentage)
99  {
100  return percentage * percentage;
101  }
102 
115  template <typename Type> Type Squared(float percentage, const Type& start, const Type& end)
116  {
117  return ((end - start) * Squared(percentage)) + start;
118  }
119 
126  inline constexpr float Cubic(float percentage)
127  {
128  return percentage * percentage * percentage;
129  }
130 
143  template <typename Type> Type Cubic(float percentage, const Type& start, const Type& end)
144  {
145  return ((end - start) * Cubic(percentage)) + start;
146  }
147 
154  inline constexpr float Quartic(float percentage)
155  {
156  return percentage * percentage * percentage * percentage;
157  }
158 
168  template <typename Type> Type Quartic(float percentage, const Type& start, const Type& end)
169  {
170  return ((end - start) * Quartic(percentage)) + start;
171  }
172 
179  inline constexpr float Quintic(float percentage)
180  {
181  return percentage * percentage * percentage * percentage * percentage;
182  }
183 
193  template <typename Type> Type Quintic(float percentage, const Type& start, const Type& end)
194  {
195  return ((end - start) * Quintic(percentage)) + start;
196  }
197 
204  inline float Exponential(float percentage)
205  {
206  return pow(2.0f, 10.0f * (percentage - 1.0f));
207  }
208 
218  template <typename Type> Type Exponential(float percentage, const Type& start, const Type& end)
219  {
220  return ((end - start) * Exponential(percentage)) + start;
221  }
222 
229  inline float Sine(float percentage)
230  { //Sin in from http://gizma.com/easing/#sin1 where t/d = percentage, c = 1, b = 0 (time, begin, change, distance)
231  return 1.0f - cos(percentage * tbMath::kPi / 2.0f);
232  }
233 
246  template <typename Type> Type Sine(float percentage, const Type& start, const Type& end)
247  {
248  return ((end - start) * Sine(percentage)) + start;
249  }
250 
259  inline float Elastic(float percentage)
260  { //https://github.com/vrld/hump/blob/master/timer.lua#L128L131
261  const float amplitude = 1.0f;
262  const float period = 0.3f;
263  return (-amplitude * sin(tbMath::kTwoPi / period * (percentage - 1.0f) - asin(1.0f / amplitude))) * pow(2.0f, (10.0f * (percentage - 1.0f)));
264  }
265 
266  inline float Elastic(float percentage, float amplitude, float period)
267  { //https://github.com/vrld/hump/blob/master/timer.lua#L128L131
268  return (-amplitude * sin(tbMath::kTwoPi / period * (percentage - 1.0f) - asin(1.0f / amplitude))) * pow(2.0f, (10.0f * (percentage - 1.0f)));
269  }
270 
282  template <typename Type> Type Elastic(float percentage, const Type& start, const Type& end)
283  {
284  return ((end - start) * Elastic(percentage)) + start;
285  }
286 
293  inline float Bounce(const float percentage)
294  { //https://github.com/vrld/hump/blob/master/timer.lua#L123-L126
295  const float a(7.5625f);
296  const float b(1.0f / 2.75f);
297 
298  return tbMath::Minimum(a * percentage * percentage,
299  tbMath::Minimum(a * (percentage - 1.5f * b) * (percentage - 1.5f * b) + 0.75f,
300  tbMath::Minimum(a * (percentage - 2.25f * b) * (percentage - 2.25f * b) + 0.9375f,
301  a * (percentage - 2.625f * b) * (percentage - 2.625f * b) + 0.984375f)));
302  }
303 
316  template <typename Type> Type Bounce(float percentage, const Type& start, const Type& end)
317  {
318  return ((end - start) * Bounce(percentage)) + start;
319  }
320 
321 
322  typedef float(*InterpolationFunction)(float);
323 
324  inline float Out(float percentage, InterpolationFunction interpolation)
325  {
326  return 1.0f - interpolation(1.0f - percentage);
327  }
328 
329  template <typename Type> float Out(float percentage, const Type& start,
330  const Type& end, InterpolationFunction interpolation)
331  {
332  return ((end - start) * Out(percentage, interpolation)) + start;
333  }
334 
335 
336  inline float InOut(float percentage, InterpolationFunction interpolation)
337  {
338  return 0.5f * ((percentage < 0.5f) ? interpolation(2.0f * percentage) :
339  1.0f + Out(2.0f * percentage - 1.0f, interpolation));
340  }
341 
342  template <typename Type> float InOut(float percentage, const Type& start,
343  const Type& end, InterpolationFunction interpolation)
344  {
345  return ((end - start) * InOut(percentage, interpolation)) + start;
346  }
347 
348  inline float Interpolate(float percentage, const InterpolationMode& mode)
349  {
350  switch (mode)
351  {
352  case InterpolationMode::Linear: return Linear(percentage);
353  case InterpolationMode::InSquared: return Squared(percentage);
354  case InterpolationMode::OutSquared: return Out(percentage, Squared);
355  case InterpolationMode::InOutSquared: return InOut(percentage, &Squared);
356 
357  case InterpolationMode::InCubic: return Cubic(percentage);
358  case InterpolationMode::OutCubic: return Out(percentage, Cubic);
359  case InterpolationMode::InOutCubic: return InOut(percentage, &Cubic);
360 
361  case InterpolationMode::InQuartic: return Quartic(percentage);
362  case InterpolationMode::OutQuartic: return Out(percentage, Quartic);
363  case InterpolationMode::InOutQuartic: return InOut(percentage, &Quartic);
364 
365  case InterpolationMode::InQuintic: return Quintic(percentage);
366  case InterpolationMode::OutQuintic: return Out(percentage, Quintic);
367  case InterpolationMode::InOutQuintic: return InOut(percentage, &Quintic);
368 
369  case InterpolationMode::InExponential: return Exponential(percentage);
370  case InterpolationMode::OutExponential: return Out(percentage, Exponential);
371  case InterpolationMode::InOutExponential: return InOut(percentage, &Exponential);
372 
373  case InterpolationMode::InSine: return Sine(percentage);
374  case InterpolationMode::OutSine: return Out(percentage, Sine);
375  case InterpolationMode::InOutSine: return InOut(percentage, &Sine);
376 
377  case InterpolationMode::InElastic: return Elastic(percentage);
378  case InterpolationMode::OutElastic: return Out(percentage, Elastic);
379  case InterpolationMode::InOutElastic: return InOut(percentage, &Elastic);
380 
381  case InterpolationMode::InBounce: return Bounce(percentage);
382  case InterpolationMode::OutBounce: return Out(percentage, Bounce);
383  case InterpolationMode::InOutBounce: return InOut(percentage, &Bounce);
384  }
385 
386  tb_error("tbInternalError: Unhandled case for InterpolationMode: %d\n", mode);
387  return 0.0;
388  }
389 
390  template<typename Type> Type Interpolate(float percentage, const Type& start, const Type& end, const InterpolationMode& mode)
391  {
392  return ((end - start) * Interpolate(percentage, mode)) + start;
393  }
394 
395 
404  inline float SmoothStep(float percentage)
405  {
406  return (percentage * percentage * (3.0f - 2.0f * percentage));
407  }
408 
422  template <typename Type> Type SmoothStep(float percentage, const Type& start, const Type& end)
423  {
424  const float smoothPercentage = SmoothStep(percentage);
425  return (start * smoothPercentage) + (end * (1.0f - smoothPercentage));
426  }
427 
446  template <typename Type> Type CubicBezier(float percentage, const Type& a, const Type& b, const Type& c, const Type& d)
447  {
448  //const Type tempA = Linear(percentage, a, c);
449  //const Type tempB = Linear(percentage, c, d);
450  //const Type tempC = Linear(percentage, d, b);
451  const Type tempA = Linear(percentage, a, b);
452  const Type tempB = Linear(percentage, b, c);
453  const Type tempC = Linear(percentage, c, d);
454 
455  const Type tempAA = Linear(percentage, tempA, tempB);
456  const Type tempBB = Linear(percentage, tempB, tempC);
457 
458  return Linear(percentage, tempAA, tempBB);
459  }
460 
475  template <typename Type> Type CubicBezierTangent(float percentage, const Type& a, const Type& b, const Type& c, const Type& d)
476  { //Source: http://stackoverflow.com/questions/4089443/find-the-tangent-of-a-point-on-a-cubic-bezier-curve-on-an-iphone
477 
478  const Type c1(d - (3.0f * c) + (3.0f * b) - a);
479  const Type c2((3.0f * c) - (6.0f * b) + (3.0f * a));
480  const Type c3((3.0f * b) - (3.0f * a));
481  //const float c4(a);
482 
483  return ((c1 * (3.0f * percentage * percentage)) + (c2 * (2.0f * percentage)) + c3);
484  }
485 
486  }; /* namespace Interpolation */
487  }; /* namespace Math */
488 }; /* namespace TurtleBrains */
489 
490 namespace tbMath = TurtleBrains::Math;
491 
492 #endif /* TurtleBrains_Interpolation_hpp */
Contains objects and functions for dealing with Vector and Matrix math.
#define tb_error(message,...)
Definition: tb_error.hpp:23
Here is some information about the primary namespace.
Definition: tb_application_dialog.hpp:21
constexpr const T & Minimum(const T &leftValue, const T &rightValue) noexcept
Definition: tb_math.hpp:89