SplineMath.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. namespace Urho
  2. {
  3. internal static class SplineMath
  4. {
  5. // CatmullRom Spline formula:
  6. /// <summary>
  7. /// See http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline
  8. /// </summary>
  9. /// <param name="p0">Control point 1</param>
  10. /// <param name="p1">Control point 2</param>
  11. /// <param name="p2">Control point 3</param>
  12. /// <param name="p3">Control point 4</param>
  13. /// <param name="tension"> The parameter c is a tension parameter that must be in the interval (0,1). In some sense, this can be interpreted as the "length" of the tangent. c=1 will yield all zero tangents, and c=0 yields a Catmull–Rom spline.</param>
  14. /// <param name="t">Time along the spline</param>
  15. /// <returns>The point along the spline for the given time (t)</returns>
  16. internal static Vector2 CardinalSplineAt(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float tension, float t)
  17. {
  18. if (tension < 0f)
  19. {
  20. tension = 0f;
  21. }
  22. if (tension > 1f)
  23. {
  24. tension = 1f;
  25. }
  26. float t2 = t * t;
  27. float t3 = t2 * t;
  28. /*
  29. * Formula: s(-ttt + 2tt - t)P1 + s(-ttt + tt)P2 + (2ttt - 3tt + 1)P2 + s(ttt - 2tt + t)P3 + (-2ttt + 3tt)P3 + s(ttt - tt)P4
  30. */
  31. float s = (1 - tension) / 2;
  32. float b1 = s * ((-t3 + (2 * t2)) - t); // s(-t3 + 2 t2 - t)P1
  33. float b2 = s * (-t3 + t2) + (2 * t3 - 3 * t2 + 1); // s(-t3 + t2)P2 + (2 t3 - 3 t2 + 1)P2
  34. float b3 = s * (t3 - 2 * t2 + t) + (-2 * t3 + 3 * t2); // s(t3 - 2 t2 + t)P3 + (-2 t3 + 3 t2)P3
  35. float b4 = s * (t3 - t2); // s(t3 - t2)P4
  36. float x = (p0.X * b1 + p1.X * b2 + p2.X * b3 + p3.X * b4);
  37. float y = (p0.Y * b1 + p1.Y * b2 + p2.Y * b3 + p3.Y * b4);
  38. return new Vector2(x, y);
  39. }
  40. // Bezier cubic formula:
  41. // ((1 - t) + t)3 = 1
  42. // Expands to
  43. // (1 - t)3 + 3t(1-t)2 + 3t2(1 - t) + t3 = 1
  44. internal static float CubicBezier(float a, float b, float c, float d, float t)
  45. {
  46. float t1 = 1f - t;
  47. return ((t1 * t1 * t1) * a + 3f * t * (t1 * t1) * b + 3f * (t * t) * (t1) * c + (t * t * t) * d);
  48. }
  49. internal static float QuadBezier(float a, float b, float c, float t)
  50. {
  51. float t1 = 1f - t;
  52. return (t1 * t1) * a + 2.0f * (t1) * t * b + (t * t) * c;
  53. }
  54. }
  55. }