@osbjs/osbjs
Version:
a minimalist osu! storyboarding framework
75 lines (74 loc) • 3.28 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BezierCurve = void 0;
const Math_1 = require("../../Math");
const Curve_1 = require("./Curve");
class BezierCurve 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;
let previousPosition = this.startPosition;
for (let i = 1; i <= precision; ++i) {
let delta = i / (precision + 1);
let nextPosition = this._getPositionAtDelta(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;
}
_getPositionAtDelta(delta) {
let intermediatePoints = [];
for (let i = 0; i < this.points.length; ++i)
intermediatePoints[i] = this.points[i];
for (let i = 1; i < this.points.length; ++i)
for (let j = 0; j < this.points.length - i; ++j) {
intermediatePoints[j] = new Math_1.Vector2();
intermediatePoints[j].x = intermediatePoints[j].x * (1 - delta) + intermediatePoints[j + 1].x * delta;
intermediatePoints[j].y = intermediatePoints[j].y * (1 - delta) + intermediatePoints[j + 1].y * delta;
}
return intermediatePoints[0];
}
}
exports.BezierCurve = BezierCurve;