2022 年 11 月 30 日

貝茲曲線

貝茲曲線用於電腦繪圖中的繪製形狀、CSS 動畫和許多其他地方。

它們非常簡單,值得學習一次,然後在向量繪圖和進階動畫的世界中感到自在。

請提供一些理論

本文提供了貝茲曲線的理論,但非常需要的見解,而 下一篇文章 顯示我們如何將它們用於 CSS 動畫。

請花時間閱讀並了解這個概念,它將對你有所幫助。

控制點

一個 貝茲曲線 由控制點定義。

可能會有 2、3、4 或更多。

例如,兩點曲線

三點曲線

四點曲線

如果你仔細觀察這些曲線,你可以立即注意到

  1. 點並不總是在曲線上。這是完全正常的,稍後我們將看到曲線是如何建立的。

  2. 曲線階等於點數減一。對於兩點,我們有一個線性曲線(這是一條直線),對於三點 - 二次曲線(拋物線),對於四點 - 三次曲線。

  3. 曲線總是位於控制點的 凸包 內部

由於最後一個屬性,在電腦圖形中可以最佳化相交測試。如果凸包不相交,則曲線也不相交。因此,首先檢查凸包相交可以得到非常快速的「不相交」結果。檢查凸包的相交容易得多,因為它們是矩形、三角形等(見上圖),比曲線簡單得多的圖形。

貝茲曲線用於繪圖的主要價值 - 通過移動點,曲線會以直觀明顯的方式改變。

嘗試在以下範例中使用滑鼠移動控制點

正如你所看到的,曲線沿切線 1 → 2 和 3 → 4 伸展。

經過一些練習後,很明顯如何放置點以獲得所需的曲線。並且通過連接多條曲線,我們可以得到幾乎任何東西。

以下是一些範例

德卡斯特里奧演算法

貝茲曲線有一個數學公式,但讓我們稍後再討論,因為 德卡斯特里奧演算法 與數學定義相同,並直觀地顯示它是如何建構的。

首先讓我們看看 3 點範例。

以下是示範,然後說明。

控制點(1、2 和 3)可以用滑鼠移動。按「播放」按鈕來執行。

De Casteljau 演算法用於建立 3 點貝茲曲線

  1. 繪製控制點。在上面的範例中,它們標示為:123

  2. 在控制點 1 → 2 → 3 之間建立線段。在上面的範例中,它們是 褐色 的。

  3. 參數 t0 移動到 1。在上面的範例中,使用步長 0.05:迴圈會遍歷 0、0.05、0.1、0.15、... 0.95、1

    對於這些 t 的每個值

    • 在每個 褐色 線段上,我們取一個點,其位置與從線段起點到該點的距離成正比。由於有兩個線段,因此我們有兩個點。

      例如,對於 t=0,兩個點都會在線段的起點,而對於 t=0.25,兩個點會在線段長度的 25% 處,對於 t=0.5,兩個點會在 50% 處(中間),對於 t=1,兩個點會在線段的終點。

    • 連接這些點。在下面的圖片中,連接線段塗成 藍色

對於 t=0.25 對於 t=0.5
  1. 現在在 藍色 線段上,取一個點,其位置與 t 的相同值成正比。也就是說,對於 t=0.25(左圖),我們在線段左四分之一的終點取一個點,而對於 t=0.5(右圖),我們在線段的中間取一個點。在上面的圖片中,那個點是 紅色的

  2. t0 跑到 1 時,t 的每個值都會在曲線上增加一個點。這些點的集合形成貝茲曲線。在上面的圖片中,貝茲曲線是紅色且拋物線形的。

這是針對 3 個點的處理程序。但對於 4 個點也是一樣的。

4 個點的範例(點可以用滑鼠移動)

4 個點的演算法

  • 用線段連接控制點:1 → 2、2 → 3、3 → 4。將會有 3 個 褐色 線段。
  • 對於區間 [0, 1] 中的每個 t
    • 我們在這些線段上取點,其位置與從線段起點到該點的距離成正比。這些點是連接的,因此我們有兩個 綠色線段
    • 在這些線段上,我們取點,其位置與 t 成正比。我們得到一個 藍色線段
    • 在藍色線段上,我們取一個點,其位置與 t 成正比。在上面的範例中,它是 紅色的
  • 這些點一起形成曲線。

演算法是遞迴的,且可以概化為任何數量的控制點。

給定 N 個控制點

  1. 我們將它們連接起來,以最初獲得 N-1 個區段。
  2. 然後,對於從 01 的每個 t,我們在每個區段上取一個點,其距離與 t 成正比,並將它們連接起來。將會有 N-2 個區段。
  3. 重複步驟 2,直到只有一個點。

這些點構成曲線。

執行並暫停範例,以清楚地看到區段以及曲線是如何建立的。

看起來像 y=1/t 的曲線

曲折的控制點也能正常運作

製作迴圈是可能的

非平滑的貝茲曲線(是的,這也是可能的)

如果演算法說明中有任何不清楚的地方,請查看上面的動態範例,以了解曲線是如何建立的。

由於演算法是遞迴的,因此我們可以建立任何順序的貝茲曲線,也就是:使用 5、6 個或更多控制點。但在實務上,許多點較不實用。我們通常會取 2-3 個點,並將多條曲線黏合在一起以形成複雜線條。這樣開發和計算會比較簡單。

如何繪製一條「通過」給定點的曲線?

為了指定貝茲曲線,會使用控制點。正如我們所見,它們不在曲線上,除了第一個和最後一個。

有時我們有另一個任務:繪製一條「通過多個點」的曲線,以便它們全部都在單一條平滑曲線上。該任務稱為插值,我們在此不予討論。

此類曲線有數學公式,例如拉格朗日多項式。在電腦圖學中,樣條插值通常用於建立連接許多點的平滑曲線。

數學

貝茲曲線可以用數學公式來描述。

正如我們所見,實際上不需要知道它,大多數人只是透過滑鼠移動點來繪製曲線。但如果你喜歡數學,以下是公式。

給定控制點 Pi 的座標:第一個控制點的座標為 P1 = (x1, y1),第二個為 P2 = (x2, y2),以此類推,曲線座標由依賴於參數 t 的方程式描述,從線段 [0,1]

  • 2 點曲線的公式

    P = (1-t)P1 + tP2

  • 對於 3 個控制點

    P = (1−t)2P1 + 2(1−t)tP2 + t2P3

  • 對於 4 個控制點

    P = (1−t)3P1 + 3(1−t)2tP2 +3(1−t)t2P3 + t3P4

這些是向量方程式。換句話說,我們可以用 xy 取代 P 以取得對應的座標。

例如,3 點曲線由點 (x,y) 形成,計算如下

  • x = (1−t)2x1 + 2(1−t)tx2 + t2x3
  • y = (1−t)2y1 + 2(1−t)ty2 + t2y3

我們應將 3 個控制點的座標放入 x1, y1, x2, y2, x3, y3 中,然後當 t0 移動到 1 時,對於 t 的每個值,我們將得到曲線的 (x,y)

例如,如果控制點為 (0,0)(0.5, 1)(1, 0),方程式變為

  • x = (1−t)2 * 0 + 2(1−t)t * 0.5 + t2 * 1 = (1-t)t + t2 = t
  • y = (1−t)2 * 0 + 2(1−t)t * 1 + t2 * 0 = 2(1-t)t = –2t2 + 2t

現在當 t0 運行到 1 時,對於每個 t 的值集合 (x,y) 形成這些控制點的曲線。

摘要

貝茲曲線由其控制點定義。

我們看到了貝茲曲線的兩個定義

  1. 使用繪圖流程:德卡斯特里奧演算法。
  2. 使用數學公式。

貝茲曲線的良好屬性

  • 我們可以透過移動控制點,使用滑鼠繪製平滑線條。
  • 複雜形狀可以由多條貝茲曲線組成。

用法

  • 在電腦繪圖、建模、向量圖形編輯器中。字體由貝茲曲線描述。
  • 在網頁開發中 - 用於 Canvas 上的圖形和 SVG 格式。順帶一提,上面「動態」範例是以 SVG 編寫的。它們實際上是一個單一的 SVG 文件,給定不同的點作為參數。您可以在一個獨立的視窗中開啟它,並查看原始碼:demo.svg
  • 在 CSS 動畫中,用於描述動畫的路徑和速度。
教學地圖

留言

留言前請先閱讀…
  • 如果您有改進建議,請 提交 GitHub 問題 或提交拉取請求,而非留言。
  • 如果您無法理解文章中的內容,請詳細說明。
  • 若要插入幾行程式碼,請使用 <code> 標籤,若要插入多行程式碼,請將其包覆在 <pre> 標籤中,若要插入超過 10 行的程式碼,請使用沙盒 (plnkrjsbincodepen…)