unity 贝塞尔曲线算法

本文详细介绍了贝赛尔曲线的概念及其实现原理,包括线性、二次方、三次方及n次方贝赛尔曲线的数学公式和Unity实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在任意几个点坐标绘制出的一条曲线,就叫贝赛尔曲线。


线性公式

            等同于线性插值

这个最简单,就是很普通的插值算法,给定p0,p1,t取值范围0到1

    // 线性
    Vector3 Bezier(Vector3 p0, Vector3 p1, float t)
    {
        return (1 - t) * p0 + t * p1;
    }


二次方公式

        

        

        p0p1 = (1 - t) * p0 + t * p1;

        p1p2 = (1 - t) * p1 + t * p2;

        B(t) = (1 - t) * p0p1 + t * p1p2;

        B(t)  = ((1 - t) * ((1 - t) * p0 + t * p1)) + (t * ((1 - t) * p1 + t * p2))

二次方的也不是很难理解,还是求插值,p0和p1的插值,p1和p2的插值,在求这两个插值(vector3)的插值

    // 二阶曲线
    Vector3 Bezier(Vector3 p0, Vector3 p1, Vector3 p2, float t)
    {
        Vector3 p0p1 = (1 - t) * p0 + t * p1;
        Vector3 p1p2 = (1 - t) * p1 + t * p2;
        Vector3 result = (1 - t) * p0p1 + t * p1p2;
        return result;
    }


三次方公式

        

        

         p0p1 = (1 - t) * p0 + t * p1;

         p1p2 = (1 - t) * p1 + t * p2;

         p2p3 = (1 - t) * p2 + t * p3;

         p0p1p2 = (1 - t) * p0p1 + t * p1p2;

         p1p2p3 = (1 - t) * p1p2 + t * p2p3;

         B(t) = (1 - t) * p0p1p2 + t * p1p2p3;

三次方的曲线其实和二次没有太大区别,不过是多了一个点,就多了一层要计算的插值

    // 三阶曲线
    Vector3 Bezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
    {
        Vector3 result;
        Vector3 p0p1 = (1 - t) * p0 + t * p1;
        Vector3 p1p2 = (1 - t) * p1 + t * p2;
        Vector3 p2p3 = (1 - t) * p2 + t * p3;
        Vector3 p0p1p2 = (1 - t) * p0p1 + t * p1p2;
        Vector3 p1p2p3 = (1 - t) * p1p2 + t * p2p3;
        result = (1 - t) * p0p1p2 + t * p1p2p3;
        return result;
    }

n次方公式

        

        

最后一个,最难的n次方的公式,其实这个只要能把前面两个理解了,最后一个也不难,都是有规律的,就是不停的去计算插值;点1和点2插值,产生出新的点,点2和点3插值,又产生一个点,依次循环,直到最后只剩下一个点。

    // n阶曲线,递归实现
    public Vector3 Bezier(float t, List<Vector3> p)
    {
        if (p.Count < 2)
            return p[0];
        List<Vector3> newp = new List<Vector3>();
        for (int i = 0; i < p.Count - 1; i++)
        {
            Debug.DrawLine(p[i], p[i + 1]);
            Vector3 p0p1 = (1 - t) * p[i] + t * p[i + 1];
            newp.Add(p0p1);
        }
        return Bezier(t, newp);
    }
    // transform转换为vector3,在调用参数为List<Vector3>的Bezier函数
    public Vector3 Bezier(float t, List<Transform> p)
    {
        if (p.Count < 2)
            return p[0].position;
        List<Vector3> newp = new List<Vector3>();
        for (int i = 0; i < p.Count; i++)
        {
            newp.Add(p[i].position);
        }
        return Bezier(t, newp);
    }


在unity里实现的效果

        
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值