unity3D技术分享Unity游戏开发经验分享

Unity - 贝塞尔曲线浅析

2020-12-14  本文已影响0人  能不写代码么
贤妻插画图

定义

一次方公式

//求公式过程
  B(t) = P0 + (P1 - P0)t
       = P0 + tP1 - tP0
       = (1 - t)P0 + tP1
  //当 t = 0 时,结果为起始点P0
  //当 t = 1 时,结果为终点P1
    //程序中使用
    Vector3 Bezier(Vector3 p0, Vector3 p1, float t)
    {
        return (1 - t) * p0 + t * p1;
    }

二次方公式

//求公式过程
  //由一次方公式得到下面这两个公式
  P0P1 = (1 - t)P0 + tP1
  P1P2 = (1 - t)P1 + tP2
  //图中的绿色点代表了我们最终想要得到的点B(t),可以看做是需要得到P0P1和P1P2这条线段上的一个点,再将P0P1和P1P2换为我们上面得到的公式
  B(t) = (1 - t)P0P1 + tP1P2
       = (1 - t) * ( (1 - t)P0 + tP1) + t * ((1 - t)P1 + tP2)
       = (1 - t)(1 - t)P0 + (1 - t) * tP1 + (1 - t) * tP1 + t²P2
       = (1 - t)²P0 + 2t(1 - t) * P1 + t²P2
  //这就是图中展示的最终公式了     
  //当 t = 0 时,结果为起始点P0P1
  //当 t = 1 时,结果为终点P1P2
   //程序中使用
    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;
    }

三次方公式


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

   //程序中使用
    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阶曲线,递归实现
    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);
    }

t就一个系数,取值范围是0-1,为0时返回值是曲线的出发点,为1时返回值是曲线的终点,为0.5时返回曲线的中间点

相关链接

https://www.cnblogs.com/mmc1206x/p/3709188.html
https://blog.csdn.net/qq_35539447/article/details/80486247

上一篇 下一篇

猜你喜欢

热点阅读