猫史档案馆


Box3Curve1.0.0发布了,好耶!

用户:萌新大佬萌新大佬查看: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);//正常是角
    }
})

效果图:

center_image


回复

上一页1 页 / 共 1下一页
萌新大佬萌新大佬

好耶!

点赞0


评论


冷鱼闲风冷鱼闲风

支持,但apifox.com/apidoc/shared-f3366919-0f59-46c4-9ff0-34b48cbc6f03

点赞0


评论


NomenNomen

ddd

点赞0


评论


小树同学小树同学

ddd

点赞0


评论


神岛吉吉喵神岛吉吉喵

emotion_编程猫_厉害了

点赞0


评论


追梦ez追梦ez

ddd

点赞0


评论


萌新大佬萌新大佬

更新力:https://shequ.codemao.cn/community/542303

点赞0


评论