游戲開發中的貝塞爾曲線,曲線和路徑貝塞爾曲線是自然幾何形狀的數學近似。我們使用它們來表示一條曲線,該曲線具有盡可能少的信息并具有很高的靈活性。 與更抽象的數學概念不同,貝塞爾曲線是為工業設計而創建的。它們是圖形軟件行業中流行的工具。 它們依賴于插值(我在上一篇文章中提過),結合了多個步驟以創建平滑曲線。為了更好地了解貝塞爾曲線的工作原理,讓我們從其最簡單的形式開始:二次貝塞爾曲線。 二次貝塞爾曲線取三點,這是二次貝塞爾曲線起作用的最低要求: 為了在它們之間繪制一條曲線,我們首先使用0到1范圍內的值,在由三個點組成的兩個線段的每個頂點的兩個頂點上逐步進行插值。這使我們在改變線段值時沿著線段移動兩個點的t從0到1。
然后q0,我們進行插值并q1獲得r沿曲線移動的單個點。
這種類型的曲線稱為二次貝塞爾曲線。
三次貝塞爾曲線在前面的示例的基礎上,我們可以通過在四個點之間進行插值來獲得更多控制。 我們首先使用的功能與四個參數取四點作為輸入, p0,p1,p2和p3:
我們對每個點應用線性插值以將其減少到三個:
然后,我們將三點簡化為兩點:
并給一個:
這是全部功能:
結果將是在所有四個點之間插值的平滑曲線: (圖片來源:維基百科)
添加控制點以立方貝塞爾曲線為基礎,我們可以更改兩個點的工作方式以自由控制曲線的形狀。而是具有
這樣,我們有兩個點和兩個控制點,它們是相對于各個點的相對向量。如果您以前使用過圖形或動畫軟件,則可能看起來很熟悉: 這就是圖形軟件如何向用戶顯示Bezier曲線,以及它們在Godot中的工作方式和外觀。 Curve2D,Curve3D,路徑和Path2D有兩個包含曲線的對象:Curve3D和Curve2D(分別用于3D和2D)。 它們可以包含多個點,從而可以使用更長的路徑。也可以將它們設置為節點:Path和Path2D(也分別用于3D和2D): 但是,使用它們可能并不十分明顯,因此以下是Bezier曲線最常見用例的描述。 評估僅評估它們可能是一種選擇,但是在大多數情況下,它不是很有用。 貝塞爾曲線的最大缺點是,如果以恒定速度從t = 0到t = 1遍歷它們,則實際插補將不會以恒定速度移動。 速度也是點p0,p1,p2和p3之間距離的插值,并且沒有數學上簡單的方法來以恒定速度遍歷曲線。 讓我們用下面的偽代碼做一個簡單的例子:
如您所見,即使t以恒定速度增加,圓的速度(以每秒像素為單位)也會變化。這使得貝塞爾曲線難以在開箱即用的情況下使用。 畫畫繪制貝塞爾曲線(或基于曲線的對象)是一種非常常見的用例,但這也不容易。在幾乎任何情況下,貝塞爾曲線都需要轉換為某種線段。但是,這通常很困難,而又不創建大量的代碼。 原因是曲線的某些部分(特別是拐角)可能需要大量的點,而其他部分可能不需要: 此外,如果兩個控制點都是0, 0(請記住它們是相對矢量),則貝塞爾曲線將只是一條直線(因此繪制大量的點將是浪費的)。 在繪制貝塞爾曲線之前,需要進行細分。這通常通過遞歸或分而治之的功能來完成,該功能可以分割曲線,直到曲率量小于某個閾值為止。 的曲線類通過提供這種 Curve2D.tessellate()函數(其接收可選stages的遞歸和角度tolerance參數)。這樣,基于曲線繪制對象就更容易了。 遍歷曲線的最后一個常見用例是遍歷它們。由于前面提到的有關恒速的內容,這也很困難。 為了使此操作更容易,需要將曲線烘焙到等距的點。這樣,它們可以通過常規插值進行近似(可以通過三次選項進一步改進)。為此,只需將Curve.interpolate_baked()方法與Curve2D.get_baked_length()一起使用 。第一次調用它們中的任何一個都會在內部烘焙曲線。 然后,可以使用以下偽代碼完成恒速遍歷:
然后,輸出將以恒定速度移動: |
|