新增bezierSpline提供了一系列立方贝塞尔点,并提供了帮助方法来访问贝塞尔
This commit is contained in:
114
source/src/Math/BezierSpline.ts
Normal file
114
source/src/Math/BezierSpline.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
module es {
|
||||
/**
|
||||
* 提供了一系列立方贝塞尔点,并提供了帮助方法来访问贝塞尔
|
||||
*/
|
||||
export class BezierSpline {
|
||||
public _points: FastList<Vector2> = new FastList<Vector2>();
|
||||
public _curveCount: number = 0;
|
||||
|
||||
/**
|
||||
* 在这个过程中,t被修改为在曲线段的范围内。
|
||||
* @param t
|
||||
*/
|
||||
public pointIndexAtTime(t: Ref<number>): number {
|
||||
let i = 0;
|
||||
if (t.value >= 1) {
|
||||
t.value = 1;
|
||||
i = this._points.length - 4;
|
||||
} else {
|
||||
t.value = MathHelper.clamp01(t.value) * this._curveCount;
|
||||
i = ~~t;
|
||||
t.value -= i;
|
||||
i *= 3;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置一个控制点,考虑到这是否是一个共享点,如果是,则适当调整
|
||||
* @param index
|
||||
* @param point
|
||||
*/
|
||||
public setControlPoint(index: number, point: Vector2) {
|
||||
if (index % 3 == 0) {
|
||||
let delta = Vector2.subtract(point, this._points.buffer[index]);
|
||||
if (index > 0)
|
||||
this._points.buffer[index - 1].add(delta);
|
||||
|
||||
if (index + 1 < this._points.length)
|
||||
this._points.buffer[index + 1].add(delta);
|
||||
}
|
||||
|
||||
this._points.buffer[index] = point;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到时间t的贝塞尔曲线上的点
|
||||
* @param t
|
||||
*/
|
||||
public getPointAtTime(t: number): Vector2{
|
||||
let i = this.pointIndexAtTime(new Ref(t));
|
||||
return Bezier.getPointThree(this._points.buffer[i], this._points.buffer[i + 1], this._points.buffer[i + 2],
|
||||
this._points.buffer[i + 3], t);
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到贝塞尔在时间t的速度(第一导数)
|
||||
* @param t
|
||||
*/
|
||||
public getVelocityAtTime(t: number): Vector2 {
|
||||
let i = this.pointIndexAtTime(new Ref(t));
|
||||
return Bezier.getFirstDerivativeThree(this._points.buffer[i], this._points.buffer[i + 1], this._points.buffer[i + 2],
|
||||
this._points.buffer[i + 3], t);
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到时间t时贝塞尔的方向(归一化第一导数)
|
||||
* @param t
|
||||
*/
|
||||
public getDirectionAtTime(t: number) {
|
||||
return Vector2.normalize(this.getVelocityAtTime(t));
|
||||
}
|
||||
|
||||
/**
|
||||
* 在贝塞尔曲线上添加一条曲线
|
||||
* @param start
|
||||
* @param firstControlPoint
|
||||
* @param secondControlPoint
|
||||
* @param end
|
||||
*/
|
||||
public addCurve(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2) {
|
||||
// 只有当这是第一条曲线时,我们才会添加起始点。对于其他所有的曲线,前一个曲线的终点应该等于新曲线的起点。
|
||||
if (this._points.length == 0)
|
||||
this._points.add(start);
|
||||
|
||||
this._points.add(firstControlPoint);
|
||||
this._points.add(secondControlPoint);
|
||||
this._points.add(end);
|
||||
|
||||
this._curveCount = (this._points.length - 1) / 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置bezier,移除所有点
|
||||
*/
|
||||
public reset() {
|
||||
this._points.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将splitine分解成totalSegments部分,并返回使用线条绘制所需的所有点
|
||||
* @param totalSegments
|
||||
*/
|
||||
public getDrawingPoints(totalSegments: number): Vector2[] {
|
||||
let points: Vector2[] = [];
|
||||
for (let i = 0; i < totalSegments; i ++) {
|
||||
let t = i / totalSegments;
|
||||
points[i] = this.getPointAtTime(t);
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user