spline.mjs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. export const spline = (function() {
  2. class _CubicHermiteSpline {
  3. constructor(lerp) {
  4. this._points = [];
  5. this._lerp = lerp;
  6. }
  7. AddPoint(t, d) {
  8. this._points.push([t, d]);
  9. }
  10. Get(t) {
  11. let p1 = 0;
  12. for (let i = 0; i < this._points.length; i++) {
  13. if (this._points[i][0] >= t) {
  14. break;
  15. }
  16. p1 = i;
  17. }
  18. const p0 = Math.max(0, p1 - 1);
  19. const p2 = Math.min(this._points.length - 1, p1 + 1);
  20. const p3 = Math.min(this._points.length - 1, p1 + 2);
  21. if (p1 == p2) {
  22. return this._points[p1][1];
  23. }
  24. return this._lerp(
  25. (t - this._points[p1][0]) / (
  26. this._points[p2][0] - this._points[p1][0]),
  27. this._points[p0][1], this._points[p1][1],
  28. this._points[p2][1], this._points[p3][1]);
  29. }
  30. };
  31. class _LinearSpline {
  32. constructor(lerp) {
  33. this._points = [];
  34. this._lerp = lerp;
  35. }
  36. AddPoint(t, d) {
  37. this._points.push([t, d]);
  38. }
  39. Get(t) {
  40. let p1 = 0;
  41. for (let i = 0; i < this._points.length; i++) {
  42. if (this._points[i][0] >= t) {
  43. break;
  44. }
  45. p1 = i;
  46. }
  47. const p2 = Math.min(this._points.length - 1, p1 + 1);
  48. if (p1 == p2) {
  49. return this._points[p1][1];
  50. }
  51. return this._lerp(
  52. (t - this._points[p1][0]) / (
  53. this._points[p2][0] - this._points[p1][0]),
  54. this._points[p1][1], this._points[p2][1]);
  55. }
  56. }
  57. return {
  58. CubicHermiteSpline: _CubicHermiteSpline,
  59. LinearSpline: _LinearSpline,
  60. };
  61. })();