Unity - 贝塞尔曲线浅析

贤妻插画图

定义

  • 在任意几个点坐标绘制出的一条曲线,就叫贝塞尔曲线
  • 用我的大白话理解就是:大事化小,小事化了。看到三次方你会发现其实就是通过四个点反复计算,首先是计算出这四个点组成的对应的三条线段上的三个t点,再次计算出三条线段中三个t点组成的两条线段对应两个新的t点,在下一步和之前一样了,就是求出最终的点,N次方的曲线更是同理(可能有点绕好好理解下)

一次方公式

//求公式过程
  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;
    }

二次方公式

Unity - 贝塞尔曲线浅析_第1张图片
//求公式过程
  //由一次方公式得到下面这两个公式
  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;
    }

三次方公式

Unity - 贝塞尔曲线浅析_第2张图片

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

   //程序中使用
    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次方公式

Unity - 贝塞尔曲线浅析_第3张图片
    //程序中使用
    // n阶曲线,递归实现
    public Vector3 Bezier(float t, List p)
    {
        if (p.Count < 2)
            return p[0];
        List newp = new List();
        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的Bezier函数
    public Vector3 Bezier(float t, List p)
    {
        if (p.Count < 2)
            return p[0].position;
        List newp = new List();
        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

你可能感兴趣的:(Unity - 贝塞尔曲线浅析)