【Unity】貝茲路徑關於點、長度、切線計算在 Unity中的C#實現

來源:互聯網
上載者:User

標籤:href   ber   alt   協助   ret   https   向量   b2c   直接   

原文:【Unity】貝茲路徑關於點、長度、切線計算在 Unity中的C#實現

寫在前面

最近給項目做了個路徑編輯,基本思路是滿足幾個基本需求:
【額外說明】其實本篇和這個沒關係,可以跳過“寫在前面”這部分,跨到本文部分

編輯時:
① 隨意增減、插入、刪除路點,只要路點數量大於1,繪製曲線,曲線必定經過路點。
② 調整路點的Forward方向,控制曲線的入線切線方向、出線切線方向。這樣可以通過旋轉直接調整曲線形狀。
③ 控制Forward方向的基礎上,增添描述切線“強度”的變數,來進一步控制曲線的形狀。
④ 可以指定每段曲線的邏輯長度,程式提供一個曲線近似長度協助確定邏輯長度。
⑤ 匯出曲線的資料。

運行時,可以根絕資料:
⑥ 對路點進行從0開始的編號,使用0.01~0.99來描述在某段曲線上的位置(邏輯上的),然後轉化成為實際的座標。
⑦ 可以獲得在曲線上任意一點的切線方向。

本文

從路點、路點forward到三階貝茲路徑的四個點

關於貝茲路徑,可見下文
貝茲路徑
貝茲路徑線上示範

每兩個路點作為三階貝茲路徑的起點(第0個點P0)和終點(第3個點P3)。

起點路點的Forward方向乘以“強度”的變數,再加上起點座標,作為第1個點P1。
起點路點的Forward反方向乘以“強度”的變數,再加上起點座標,作為第2個點P2。

得到 p0~p4這四個點之後,即可使用三階貝茲路徑的相關公式了

繪製貝茲路徑,圖中紅色線條部分

三階貝茲路徑線上某點座標(Unity & C#)

三階貝茲路徑公式(來自百度百科)

形參中的 t, p0, p1, p2, p3 分別對應公式中的 t 以及 p0~p3

    public Vector3 BezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)    {        float u = 1 - t;        float tt = t * t;        float uu = u * u;        float uuu = uu * u;        float ttt = tt * t;        Vector3 p = uuu * p0;        p += 3 * uu * t * p1;        p += 3 * u * tt * p2;        p += ttt * p3;        return p;    }

三階貝茲路徑的近似長度(Unity & C#)

計算長度的思路:
在貝茲路徑上取n個點,計算點之間的直線長度,進行加和,從而取得一個曲線的近似長度。取點越多這個長度越趨向於精確。

形參中的p0, p1, p2, p3 分別對應公式中的 p0~p3。pointCount代表取點個數,預設30。

    public float BezierLength(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, int pointCount = 30)    {        if (pointCount < 2)        {            return 0;        }        //取點 預設 30個        float length = 0.0f;        Vector3 lastPoint = BezierPoint(0.0f / (float)pointCount, p0, p1, p2, p3);        for (int i = 1; i <= pointCount; i++)        {            Vector3 point = BezierPoint((float)i/(float)pointCount, p0, p1, p2, p3);            length += Vector3.Distance(point, lastPoint);            lastPoint = point;        }        return length;    }

三階貝茲路徑線上某點的切線(Unity & C#)

在已知貝茲路徑運算式的情況下,想要知道某點的切線,對曲線求導。
可得:

整理後可得

整體公式構成只有p0~p3 以及 t 和 (1-t),為了運算式更直接,不進行進一步的整理。
所以得到下面的代碼

形參中的 t, p0, p1, p2, p3 分別對應公式中的 t 以及 p0~p3

    public Vector3 BezierTangent(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)    {        float u = 1 - t;        float uu = u * u;        float tu = t * u;        float tt = t * t;        Vector3 P = p0 * 3 * uu * (-1.0f);        P += p1 * 3 * (uu - 2 * tu);        P += p2 * 3 * (2 * tu - tt);        P += p3 * 3 * tt;                //返回單位向量        return P.normalized;    }

寫在後面

主要參照:
Unity遊戲中使用貝茲路徑
求二次、三次貝茲路徑的某個時間的位置及切線方向

轉載請註明,出自喵喵丸的部落格 (http://blog.csdn.net/u011643833/article/details/78540554)

【Unity】貝茲路徑關於點、長度、切線計算在 Unity中的C#實現

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.