UNPKG

@osbjs/osbjs

Version:

a minimalist osu! storyboarding framework

80 lines (79 loc) 3.68 kB
"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;