@osbjs/osbjs
Version:
a minimalist osu! storyboarding framework
80 lines (79 loc) • 3.68 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CatmullCurve = void 0;
const Math_1 = require("../../Math");
const Curve_1 = require("./Curve");
class CatmullCurve extends Curve_1.Curve {
constructor(points, precision) {
super();
this.points = points;
this.precision = precision;
this.startPosition = points[0];
this.endPosition = points[points.length - 1];
this.distancePositions = [];
this.length = this._initLength();
}
getPositionAtProgress(t) {
return this.getPositionAtDistance(this.precision * t);
}
getPositionAtDelta(delta) {
return this.getPositionAtDistance(delta * this.length);
}
getPositionAtDistance(distance) {
let previousDistance = 0.0;
let previousPosition = this.startPosition;
let nextDistance = this.length;
let nextPosition = this.endPosition;
let i = 0;
while (i < this.distancePositions.length) {
let distancePosition = this.distancePositions[i];
if (distancePosition.distance > distance)
break;
previousDistance = distancePosition.distance;
previousPosition = distancePosition.position;
i++;
}
if (i < this.distancePositions.length - 1) {
let distancePosition = this.distancePositions[i + 1];
nextDistance = distancePosition.distance;
nextPosition = distancePosition.position;
}
let delta = (distance - previousDistance) / (nextDistance - previousDistance);
let prevNext = Math_1.Vector2.sub(nextPosition, previousPosition);
return Math_1.Vector2.add(previousPosition, Math_1.Vector2.multiplyScalar(prevNext, delta));
}
_initLength() {
let precision = this.points.length > 2 ? this.precision : 0;
let distance = 0.0;
let linePrecision = precision / this.points.length;
let previousPosition = this.startPosition;
for (let lineIndex = 0; lineIndex < this.points.length - 1; ++lineIndex) {
for (let i = 1; i <= linePrecision; ++i) {
let delta = i / (linePrecision + 1);
let p1 = lineIndex > 0 ? this.points[lineIndex - 1] : this.points[lineIndex];
let p2 = this.points[lineIndex];
let p3 = this.points[lineIndex + 1];
let p4 = lineIndex < this.points.length - 2 ? this.points[lineIndex + 2] : this.points[lineIndex + 1];
let nextPosition = this._getPositionAtDelta(p1, p2, p3, p4, delta);
let prevNext = Math_1.Vector2.sub(nextPosition, previousPosition);
distance += prevNext.length();
this.distancePositions.push({ distance, position: nextPosition });
previousPosition = nextPosition;
}
}
let prevEnd = Math_1.Vector2.sub(this.endPosition, previousPosition);
distance += prevEnd.length();
return distance;
}
_getPointPositionAtDelta(p1, p2, p3, p4, delta) {
return (0.5 *
((-p1 + 3 * p2 - 3 * p3 + p4) * delta * delta * delta + (2 * p1 - 5 * p2 + 4 * p3 - p4) * delta * delta + (-p1 + p3) * delta + 2 * p2));
}
_getPositionAtDelta(p1, p2, p3, p4, delta) {
const result = new Math_1.Vector2();
result.x = this._getPointPositionAtDelta(p1.x, p2.x, p3.x, p4.x, delta);
result.y = this._getPointPositionAtDelta(p1.y, p2.y, p3.y, p4.y, delta);
return result;
}
}
exports.CatmullCurve = CatmullCurve;