/**
* 二阶贝塞尔曲线运动
* @param target 目标
* @param duration 时间
* @param c1 起始点
* @param c2 控制点
* @param to 终点
* @param opts 自定义选项
* @returns
*/
public static bezierTo(target: any, duration: number, c1: Vec3, c2: Vec3, to: Vec3, opts: any) {
opts = opts || Object.create(null);
let twoBezier = (t: number, p1: Vec3, cp: Vec3, p2: Vec3) => {
let x = (1 - t) * (1 - t) * p1.x + 2 * t * (1 - t) * cp.x + t * t * p2.x;
let y = (1 - t) * (1 - t) * p1.y + 2 * t * (1 - t) * cp.y + t * t * p2.y;
return new Vec3(x, y, 0);
};
opts.onUpdate = (arg: Vec3, ratio: number) => {
target.position = twoBezier(ratio, c1, c2, to);
};
return tween(target).to(duration, {}, opts);
}
/**
* 3阶贝塞尔曲线
* @param target
* @param t
* @param p1
* @param cp1
* @param cp2
* @param p2
* @param opts
* @returns
*/
public static bezierTo3(target: any, t: number, p1: Vec3, cp1: Vec3, cp2: Vec3, p2: Vec3, opts: any) {
opts = opts || Object.create(null);
const threeBezier = (t: number, p1: Vec3, cp1: Vec3, cp2: Vec3, p2: Vec3) => {
let x =
(1 - t) * (1 - t) * (1 - t) * p1.x +
3 * t * (1 - t) * (1 - t) * cp1.x +
3 * t * t * (1 - t) * cp2.x +
t * t * t * p2.x;
let y =
(1 - t) * (1 - t) * (1 - t) * p1.y +
3 * t * (1 - t) * (1 - t) * cp1.y +
3 * t * t * (1 - t) * cp2.y +
t * t * t * p2.y;
return new Vec3(x, y, 0);
};
opts.onUpdate = (arg: Vec3, ratio: number) => {
target.position = threeBezier(ratio, p1, cp1, cp2, p2);
};
return tween(target).to(t, {}, opts);
}
/**
* N阶贝塞尔曲线
* @param target Node节点
* @param t 时间
* @param StartP 开始节点
* @param cpN 经过的点
* @param EndP 结束的节点
* @param opts 回调
* @returns
*/
public static bezierToN(target: any, t: number, StartP: Vec3, cpN: Array<Vec3>, EndP: Vec3, opts: any) {
opts = opts || Object.create(null);
const threeBezier = (t: number, StartP: Vec3, cpN: Array<Vec3>, EndP: Vec3) => {
// console.log("cpN.length:"+cpN.length)
let x =
Math.pow(1 - t, cpN.length + 1) * StartP.x +
Math.pow(t, cpN.length + 1) * EndP.x;
for (let index = 0; index < cpN.length; index++) {
let val = cpN[index];
let tNum = index + 1
let oneTNum = cpN.length - index
x = x + (cpN.length + 1) * Math.pow(t, tNum) * Math.pow((1 - t), oneTNum) * val.x
}
let y =
Math.pow(1 - t, cpN.length + 1) * StartP.y +
Math.pow(t, cpN.length + 1) * EndP.y;
for (let index = 0; index < cpN.length; index++) {
let val = cpN[index];
let tNum = index + 1
let oneTNum = cpN.length - index
y = y + (cpN.length + 1) * Math.pow(t, tNum) * Math.pow((1 - t), oneTNum) * val.y
}
// console.log("x:" + x + " y:" + y)
return new Vec3(x, y, 0);
};
opts.onUpdate = (arg: Vec3, ratio: number) => {
target.position = threeBezier(ratio, StartP, cpN, EndP);
};
return tween(target).to(t, {}, opts);
}
cocos 贝塞尔曲线
于 2024-08-28 13:59:28 首次发布