用户:
萌新大佬查看:3 回复:7 评论:3 创建时间:2023-05-23T22:14:27
经过了几天的喵
我终于关掉了十几个csdn的页面
在此郑重发布我的最新作品
Box3Curve
——————————————
很多人会因为无法描绘出完美的曲线而烦恼
这时就要请出伟大的贝塞尔曲线了!
在Box3Curve1.0.0中
我创建了Bezier类
终于可以使用贝塞尔曲线力!
—————知道贝塞尔曲线的人可以跳过此部分—————
贝塞尔曲线可以把粗造的折线转换为平滑的曲线
如果你想逼近一条曲线
那么就在上面取很多很多个点
并计算一个贝塞尔曲线
最终就会得到这个曲线的逼近值
————————————————————
废话不多说(明明已经说了很多了!)直接上代码
/**
* EasyCurve 是由萌新大佬开发的一款便于构建各种曲线的模块
* 此工具完全开源,免费试用,共所有人学习与参考
* @author 萌新大佬 <https://box3.codemao.cn/u/mxdlorzorz>
* @version 1.0.0
*/
//Bezier curves
class Bezier{
yht=[1];
/**
* @param {Box3Vector3[]} controllPoints 控制点(相对值) 不包括起点!起点相对值默认{x:0,y:0,z:0}
*/
constructor(...controllPoints){
let l=controllPoints.length;
if(l<1){
console.error('Invalid controll points number: '+l);
return;
}
this.controllPoints=controllPoints;
this.l=l;
for(let i=1;i<=l;i++)this.yht.push(this.yht[i-1]*(l-i+1)/i);
}
/**
* @param {number} t 表示获取什么时刻的位置 t在0~1之间
* @returns
*/
getPosition(t){
if(t<0||t>1){
console.error("Invalid time");
return new Box3Vector3(0,0,0);
}
let x=0,y=0,z=0;
for(let i=0;i<this.controllPoints.length;i++){
x+=this.controllPoints[i].x*this.yht[i]*((1-t)**(this.l-i))*(t**i);
y+=this.controllPoints[i].y*this.yht[i]*((1-t)**(this.l-i))*(t**i);
z+=this.controllPoints[i].z*this.yht[i]*((1-t)**(this.l-i))*(t**i);
}
return new Box3Vector3(x,y,z);
}
}
//exports
module.exports = {
Bezier,
}
使用方法:
构造函数传入控制点(即参考点),注意起点默认为new Box3Vector3(0,0,0)
传入的控制点为相对值,这样可以使在不同位置使用同一曲线时可以轻松转换
只有一个方法:getPosition
传入一个参数t
因为贝塞尔曲线是通过传入一个时间参数而确定位置的
所以此处的参数t为所需要计算的时间(0<=t<=1)
接下来为大家展示一个使用案例
let x = new Bezier({ x: 1, y: 0, z: 1 }, { x: 0, y: 5, z: 2 }, { x: 10, y: 0, z: 3 }, { x: 3, y: 2, z: 9 });//创建一个曲线
world.onPlayerJoin(async ({ entity }) => {//当玩家进入地图
for (let i = 1; i <= 500; i++) {//循环五百次迭代
await sleep(10);//每次更新视角间隔10ms
entity.player.cameraMode = 'fixed';//相机视角固定
//设置相机位置为贝塞尔曲线位置加上一定值再放大
entity.player.cameraPosition = x.getPosition(i / 500/* i/500可以将0~1这段时间等分为500段进行计算 */).add({ x: 1, y: 2, z: 1 }).scale(10);
entity.player.cameraTarget = entity.position.clone();//始终看向玩家
entity.player.cameraUp = new Box3Vector3(0,1,0);//正常是角
}
})
效果图:
