curve
curve
「曲線」。形狀隨意的線。
parametric curve
想要建立曲線,可以使用函數。
這種方式有個嚴重的問題:曲線是一個函數,每個X值只對應一個Y值;曲線不能到處亂繞,只能左右伸展。
要解決這個問題,最簡單的方法,就是分別處理X軸與Y軸。用一個函數專門處理X座標,用另一個函數專門處理Y座標。
{ x(t) = abs(t-2) exp(abs(t-1)) { y(t) = abs(4t) 代入t = -0.1,得到一個座標(x(-0.1), y(-0.1)) = (4.673, 0.4) 代入t = 0,得到一個座標(x(0) , y(0) ) = (5.436, 0) 代入t = 0.1,得到一個座標(x(0.1) , y(0.1) ) = (6.308, 0.4)
這個手法叫做「參數式parametric equation」,t就是參數。高中數學、微積分課程都有提到,不是什麼艱深晦澀的玩意。
二維曲線,使用兩個函數。三維曲線,使用三個函數。
polynomial curve
polynomial curve
想要建立曲線,可以使用多項式函數,平滑柔順。
{ x(t) = 1 + 2t¹ + 3t² - t³ { y(t) = 2 - t¹ + t² - t³ 代入t = -0.1,得到一個座標(x(-0.1), y(-0.1)) = (0.831, 2.111) 代入t = 0,得到一個座標(x(0) , y(0) ) = (1, 2) 代入t = 0.1,得到一個座標(x(0.1) , y(0.1) ) = (1.229, 1.909)
引入control point以操控曲線
想要操控曲線,最便捷的方式,就是點上幾個點,然後運用「多項式內插」,得到一條穿過這些點的曲線。操控點的位置,就操控了曲線的位置。
電腦擅於處理大量資料。我們可以製作非常多條曲線,讓曲線銜接曲線,就得到各式各樣的形狀了。因此,通常我們不會製作無限長的曲線,其實製作一小段曲線就夠了。
我們習慣讓t值的範圍是0到1。設定三個點、用二次多項式實施內插,三個點的t值分別是0、0.5、1。或者設定四個點、用三次多項式實施內插,四個點的t值分別是0、1/3、2/3、1。
一次多項式只能產生直線,二次以上的多項式才能產生曲線。
引入knot point以微調曲線
自由調整控制點的參數t,不一定要等分。曲線仍然穿過所有控制點,但是曲線形狀會改變。
額外建立一條數線,範圍是t = 0到t = 1。在數線上放置四個樞紐點,分別調控四個控制點的參數t。第一個樞紐點固定於t = 0,最後一個樞紐點固定於t = 1。
簡單起見,以下暫不考慮樞紐點。
小結
一、欲建立二維平面的曲線,X座標、Y座標分開處理,採用兩個函數。 二、欲使曲線平滑,採用多項式函數。 三、欲穿過四個點,採用三次多項式函數。 四、代入0≤t≤1,畫出一條曲線。 五、挪動四個控制點,畫出各種曲線。
採用Vandermonde matrix演算法,進行多項式內插。
一、設定內插多項式。
平面上四個點 (x₀,y₀) (x₁,y₁) (x₂,y₂) (x₃,y₃) X座標、Y座標分別處理,採用三次(四項)多項式。 x(t) = a₀t⁰ + a₁t¹ + a₂t² + a₃t³ y(t) = b₀t⁰ + b₁t¹ + b₂t² + b₃t³
二、求得內插多項式的係數。
首先處理X座標! 令四個點對應的t值是 t = 0, 1/3, 2/3, 1 也就是說 x(0) = x₀ , x(1/3) = x₁ , x(2/3) = x₂ , x(1) = x₃ [ 0⁰ 0¹ 0² 0³ ] [ a₀ ] [ x₀ ] [ (1/3)⁰ (1/3)¹ (1/3)² (1/3)³ ] [ a₁ ] = [ x₁ ] [ (2/3)⁰ (2/3)¹ (2/3)² (2/3)³ ] [ a₂ ] [ x₂ ] [ 1⁰ 1¹ 1² 1³ ] [ a₃ ] [ x₃ ] -1 [ a₀ ] [ 0⁰ 0¹ 0² 0³ ] [ x₀ ] [ a₁ ] = [ (1/3)⁰ (1/3)¹ (1/3)² (1/3)³ ] [ x₁ ] [ a₂ ] [ (2/3)⁰ (2/3)¹ (2/3)² (2/3)³ ] [ x₂ ] [ a₃ ] [ 1⁰ 1¹ 1² 1³ ] [ x₃ ] [ a₀ ] [ 1 0 0 0 ] [ x₀ ] [ a₁ ] = [ -5.5 9 -4.5 1 ] [ x₁ ] [ a₂ ] [ 9 -22.5 18 -4.5 ] [ x₂ ] [ a₃ ] [ -4.5 13.5 -13.5 4.5 ] [ x₃ ] a₀ = 1 x₀ + 0 x₁ + 0 x₂ + 0 x₃ a₁ = -5.5 x₀ + 9 x₁ + -4.5 x₂ + 1 x₃ a₂ = 9 x₀ + -22.5 x₁ + 18 x₂ + -4.5 x₃ a₃ = -4.5 x₀ + 13.5 x₁ + -13.5 x₂ + 4.5 x₃
三、曲線X座標公式。
無論一開始給定哪四個點,矩陣都是固定不變的。 無論一開始給定哪四個點,往後都可以直接套用公式,求得多項式係數。 a₀ = 1 x₀ + 0 x₁ + 0 x₂ + 0 x₃ a₁ = -5.5 x₀ + 9 x₁ + -4.5 x₂ + 1 x₃ a₂ = 9 x₀ + -22.5 x₁ + 18 x₂ + -4.5 x₃ a₃ = -4.5 x₀ + 13.5 x₁ + -13.5 x₂ + 4.5 x₃ 代入到內插多項式 x(t) = a₀t⁰ + a₁t¹ + a₂t² + a₃t³ 得到曲線X座標公式 x(t) = -4.5 (t-1/3) (t-2/3) (t-1) x₀ + 13.5 (t-0) (t-2/3) (t-1) x₁ + -13.5 (t-0) (t-1/3) (t-1) x₂ + 4.5 (t-0) (t-1/3) (t-2/3) x₃ 代入各種t值(範圍是0≤t≤1),得到曲線上每個點的X座標。
四、曲線Y座標公式。如法炮製。
x(t) = -4.5 (t-1/3) (t-2/3) (t-1) x₀ + 13.5 (t-0) (t-2/3) (t-1) x₁ + -13.5 (t-0) (t-1/3) (t-1) x₂ + 4.5 (t-0) (t-1/3) (t-2/3) x₃ y(t) = -4.5 (t-1/3) (t-2/3) (t-1) y₀ + 13.5 (t-0) (t-2/3) (t-1) y₁ + -13.5 (t-0) (t-1/3) (t-1) y₂ + 4.5 (t-0) (t-1/3) (t-2/3) y₃
五、代入各種t,得到曲線座標。
basis function
曲線座標公式可以改寫成:參數t的多項式函數的加權平均。
援引線性代數:參數t的多項式函數,視作基底。
x(t) = a₀t⁰ + a₁t¹ + a₂t² + a₃t³ [ a₀ ] = [ t⁰ t¹ t² t³ ] [ a₁ ] 點積 [ a₂ ] [ a₃ ] [ 1 0 0 0 ] [ x₀ ] = [ t⁰ t¹ t² t³ ] [ -5.5 9 -4.5 1 ] [ x₁ ] [ 9 -22.5 18 -4.5 ] [ x₂ ] [ -4.5 13.5 -13.5 4.5 ] [ x₃ ] [ x₀ ] = [ a₀(t) a₁(t) a₂(t) a₃(t) ] [ x₁ ] 前面兩個矩陣先相乘 [ x₂ ] [ x₃ ] = a₀(t)x₀ + a₁(t)x₁ + a₂(t)x₂ + a₃(t)x₃ 控制點的座標,視作權重 a₀(t) ... a₃(t),視作基底 其中 a₀(t) = -4.5 (t-1/3) (t-2/3) (t-1) a₁(t) = 13.5 (t-0) (t-2/3) (t-1) a₂(t) = -13.5 (t-0) (t-1/3) (t-1) a₃(t) = 4.5 (t-0) (t-1/3) (t-2/3)
採用Lagrange interpolation演算法,進行多項式內插。
不必算得要死不活,輕鬆得到曲線座標公式:四個多項式函數a₀(t) a₁(t) a₂(t) a₃(t)的加權平均數,權重是四個控制點的座標。
x(t) = a₀(t) x₀ + a₁(t) x₁ + a₂(t) x₂ + a₃(t) x₃ a₀(t) = -4.5 (t-1/3) (t-2/3) (t-1) a₁(t) = 13.5 (t-0) (t-2/3) (t-1) a₂(t) = -13.5 (t-0) (t-1/3) (t-1) a₃(t) = 4.5 (t-0) (t-1/3) (t-2/3)
Hermite curve
Hermite curve
改用兩個點暨兩斜率來建立曲線。特色是:曲線與曲線之間,得共用端點、共用斜率,平順銜接,讓銜接點一次可微。
平面上兩個點 (x₀,y₀) (x₁,y₁) 以及這兩個點的斜率 (x₀′,y₀′) (x₁′,y₁′) 三次多項式(四項)作為內插多項式 x (t) = a₀t⁰ + a₁t¹ + a₂t² + a₃t³ y (t) = b₀t⁰ + b₁t¹ + b₂t² + b₃t³ x′(t) = a₁t⁰ + 2a₂t¹ + 3a₃t² y′(t) = b₁t⁰ + 2b₂t¹ + 3b₃t² 首先處理X座標! 令兩個點對應的t值分別是 t = 0, 1 也就是說 x(0) = x₀ , x(1) = x₁ , x′(0) = x₀′ , x′(1) = x₁′ x (0) = x₀ = a₀0⁰ + a₁0¹ + a₂0² + a₃0³ x (1) = x₁ = a₀1⁰ + a₁1¹ + a₂1² + a₃1³ x′(0) = x₀′ = a₁0⁰ + 2a₂0¹ + 3a₃0² x′(1) = x₁′ = a₁1⁰ + 2a₂1¹ + 3a₃1² [ 1 0 0 0 ] [ a₀ ] [ x₀ ] [ 1 1 1 1 ] [ a₁ ] = [ x₁ ] [ 0 1 0 0 ] [ a₂ ] [ x₀′ ] [ 0 1 2 3 ] [ a₃ ] [ x₁′ ] [ a₀ ] [ 1 0 0 0 ] [ x₀ ] [ a₁ ] = [ 0 0 1 0 ] [ x₁ ] [ a₂ ] [ -3 3 -2 -1 ] [ x₀′ ] [ a₃ ] [ 2 -2 1 1 ] [ x₁′ ] a₀ = x₀ a₁ = x₀′ a₂ = -3x₀ + 3x₁ - 2x₀′ - x₁′ a₃ = 2x₀ - 2x₁ + x₀′ + x₁′ x(t) = (2t³ - 3t² + 1) ⋅ x₀ + (t³ - 2t² + t) ⋅ x₀′ + (-2t³ + 3t²) ⋅ x₁ + (t³ - t²) ⋅ x₁′
Bézier curve
Bézier curve四個點的版本
使用四個點,推導出兩個點暨兩斜率。特色是:在使用者介面當中,控制點的位置,比起控制斜率大小來得直覺多了。
平面上四個點 (x₀,y₀) (x₁,y₁) (x₂,y₂) (x₃,y₃) (x₀,y₀) (x₃,y₃) 是曲線穿過的點,對應的t值分別是 t = 0 , 1 (x₁,y₁) (x₂,y₂) 用來計算斜率,對應的t值分別是 t = 1/3 , 2/3 [(x₁,y₁) - (x₀,y₀)] ÷ 1/3 , [(x₃,y₃) - (x₂,y₂)] ÷ 1/3 是這兩個點的斜率。 [ a₀ ] [ 1 0 0 0 ] [ x₀ ] [ a₁ ] = [ -3 3 0 0 ] [ x₁ ] [ a₂ ] [ 3 -6 3 0 ] [ x₂ ] [ a₃ ] [ -1 3 -3 1 ] [ x₃ ] x(t) = (-t³ + 3t² - 3t + 1) ⋅ x₀ + (3t³ - 6t² + 3t) ⋅ x₁ + (-3t³ + 3t²) ⋅ x₂ + (t³) ⋅ x₃
Bézier Curve
仔細觀察基底函數a₀(t) a₁(t) a₂(t) a₃(t),恰是((1-t) + (t))³的二項式展開,稱作「Bernstein Polynomials」。
藉此推廣成N個控制點:((1-t) + (t))ᴺ⁻¹的二項式展開。
x(t) = (-t³ + 3t² - 3t + 1) ⋅ x₀ + (3t³ - 6t² + 3t) ⋅ x₁ + (-3t³ + 3t²) ⋅ x₂ + (t³) ⋅ x₃ x(t) = 1(1-t)³(t)⁰ ⋅ x₀ + 3(1-t)²(t)¹ ⋅ x₁ + 3(1-t)¹(t)² ⋅ x₂ + 1(1-t)⁰(t)³ ⋅ x₃ x(t) = a₀(t) x₀ + a₁(t) x₁ + a₂(t) x₂ + a₃(t) x₃ a₀(t) = 1(1-t)³(t)⁰ a₁(t) = 3(1-t)²(t)¹ a₂(t) = 3(1-t)¹(t)² a₃(t) = 1(1-t)⁰(t)³
數學公式(De Casteljau formula)
((1-t) + (t))³的二項式展開,可以化作金字塔遞推。
[layer 0] x₀ x₁ x₂ x₃ \ / \ / \ / [layer 1] x₀ x₁ x₂ \ / \ / [layer 2] x₀ x₁ 1-t \ / t [layer 3] x₀
[layer 0] x₀⁽⁰⁾ = x₀ x₁⁽⁰⁾ = x₁ x₂⁽⁰⁾ = x₂ x₃⁽⁰⁾ = x₃ [layer 1] x₀⁽¹⁾ = (1-t) x₀⁽⁰⁾ + t x₁⁽⁰⁾ x₁⁽¹⁾ = (1-t) x₁⁽⁰⁾ + t x₂⁽⁰⁾ x₂⁽¹⁾ = (1-t) x₂⁽⁰⁾ + t x₃⁽⁰⁾ [layer 2] x₀⁽²⁾ = (1-t) x₀⁽¹⁾ + t x₁⁽¹⁾ x₁⁽²⁾ = (1-t) x₁⁽¹⁾ + t x₂⁽¹⁾ [layer 3] x₀⁽³⁾ = (1-t) x₀⁽²⁾ + t x₁⁽²⁾
演算法(De Casteljau's algorithm)
相鄰的兩個控制點求加權平均數,遞推下去。
每條線段在t:(1-t)的地方取點,依序連線;遞推下去,得到一點。窮舉0≤t≤1,連成一條曲線。
Bézier curve數學性質
平滑:平滑程度(多項式最高次方),等於控制點的數目減一。
凸包:曲線永遠在控制點的「凸包」內部。
碎形:從切點切開,兩段曲線都是Bézier Curve。左曲線的控制點,即是每一層的最左線段的中繼點。右曲線亦然。
仿射:控制點實施仿射變換(線性變換與位移)求新曲線,即是原曲線實施仿射變換。
Bézier curve進階主題
《Computer Aided Geometric Design》
arc length:曲線長度。(三個點的特殊公式解) intersection:兩曲線交點。 degree elevation:新增控制點、樞紐點,而且不改變曲線。 subdivision:曲線一分為二。 reparameterization:調整移動速度。 parameter finding:已知曲線上一點,求得參數。 inverse problem (interpolation):只知曲線上四個點,求得四個控制點。 rendering:曲線畫在圖片上、填入到像素裡。
此處僅列出一小部分主題。大部分主題都沒有簡易解法。
Bézier curve實際應用
四個點的版本應用廣泛。例如Microsoft PowerPoint的曲線:
例如字體設計:
B-spline curve
B-spline curve
一、基底函數a₀(t) a₁(t) a₂(t) a₃(t),從Bernstein polynomial改成B-spline,得以調整平滑程度。
關於B-spline,請見文站文件「B-spline interpolation」。
二、B-spline自帶樞紐點t₀ t₁ t₂ t₃ ...,得以微調曲線形狀。
Bernstein polynomial屬於B-spline的特例:樞紐點等距。
數學公式(Cox–de Boor formula)
金字塔遞推,最後得到基底函數B-spline。
自訂層數k,B-spline的平滑程度(多項式最高次方)為k。
[layer 0] a₀(t) a₁(t) a₂(t) a₃(t) a₃₊₁(t) a₃₊₂(t) ... a₃₊ₖ(t) \ / \ / \ / \ / \ / \ / [layer 1] a₀(t) a₁(t) a₂(t) a₃(t) a₃₊₁(t) ... a₃₊ₖ₋₁(t) \ / \ / \ / \ / \ / : : \ / \ / \ / \ / \ / [layer k-1] a₀(t) a₁(t) a₂(t) a₃(t) a₄(t) \ / \ / \ / \ / [layer k] a₀(t) a₁(t) a₂(t) a₃(t)
[layer 0] a₀(t)⁽⁰⁾ = (t₀ ≤ t < t₁) ? 1 : 0 a₁(t)⁽⁰⁾ = (t₁ ≤ t < t₂) ? 1 : 0 a₂(t)⁽⁰⁾ = (t₂ ≤ t < t₃) ? 1 : 0 a₃(t)⁽⁰⁾ = (t₃ ≤ t < t₄) ? 1 : 0 : : a₃₊ₖ(t)⁽⁰⁾ = (t₃₊ₖ ≤ t ≤ t₄₊ₖ) ? 1 : 0 [layer k] a₀(t)⁽ᵏ⁾ = (t-t₀)/(t₀₊ₖ-t₀) a₀(t)⁽ᵏ⁻¹⁾ + (t₁₊ₖ-t)/(t₁₊ₖ-t₁) a₁(t)⁽ᵏ⁻¹⁾ a₁(t)⁽ᵏ⁾ = (t-t₁)/(t₁₊ₖ-t₁) a₁(t)⁽ᵏ⁻¹⁾ + (t₂₊ₖ-t)/(t₂₊ₖ-t₂) a₂(t)⁽ᵏ⁻¹⁾ a₂(t)⁽ᵏ⁾ = (t-t₂)/(t₂₊ₖ-t₂) a₂(t)⁽ᵏ⁻¹⁾ + (t₃₊ₖ-t)/(t₃₊ₖ-t₃) a₃(t)⁽ᵏ⁻¹⁾ a₃(t)⁽ᵏ⁾ = (t-t₃)/(t₃₊ₖ-t₃) a₃(t)⁽ᵏ⁻¹⁾ + (t₄₊ₖ-t)/(t₄₊ₖ-t₄) a₄(t)⁽ᵏ⁻¹⁾
曲線的平滑程度(多項式最高次方)為n+k-1。
曲線座標公式 x(t) = a₀(t)⁽ᵏ⁾ x₀ + a₁(t)⁽ᵏ⁾ x₁ + a₂(t)⁽ᵏ⁾ x₂ + a₃(t)⁽ᵏ⁾ x₃
演算法(de Boor's algorithm)
平移的三角金字塔。
相鄰的k條線段,找到對應的樞紐點區間,求得比例。相鄰的k條線段,按比例取點,依序連線;遞推下去,得到一點。
窮舉tᵢ≤t≤tᵢ₊ₖ₊₁,連成一段曲線。窮舉每一條線段i,取得後方相鄰的k條線段,連成整條曲線。
B-spline curve進階主題
degree elevation、Greville abscissae。
《Bézier and B-Spline Techniques》
NURBS curve
non-uniform rational B-spline curve(NURBS curve)
形容詞non-uniform:樞紐點非均勻、樞紐點不等距。
樞紐點越靠近,曲線越靠近控制點。
形容詞rational:追加控制點Z座標,求得曲線Z座標,最後曲線座標改成(X/Z, Y/Z),即是「齊次座標」。
以便形成封閉曲線,例如圓形、橢圓形。方便實施射影變換。
UVa 12565
NURBS curve實際應用
工業繪圖軟體習慣使用NURBS curve。
NURBS curve涵蓋了Bézier curve所有特性。
surface
surface
「曲面」或「表面」。形狀隨意的面。
parametric surface
曲線,一個參數t。曲面,兩個參數u和v。
{ x(u,v) = u - sin(u) cosh(v) { y(u,v) = 1 - cos(u) cosh(v) 代入(u,v) = (-0.1,0),得到一個座標(x(-0.1,0), y(-0.1,0)) = (-0.0001,0.005) 代入(u,v) = (0,0) ,得到一個座標(x(0,0) , y(0,0) ) = (0,0) 代入(u,v) = (0.1,0) ,得到一個座標(x(0.1,0) , y(0.1,0) ) = (0.0001,0.005)
二維曲面,使用兩個函數。三維曲面,使用三個函數。
polynomial surface
polynomial surface
使用多項式函數。
引入control point以操控曲面
參數u負責橫向曲線,參數v負責縱向曲線。
建立N×M個控制點。先算橫向:每N點以參數u求得橫向曲線上一點。再算縱向:方才得到的M個點以參數v求得縱向曲線上一點。
縱橫互不干涉,互相獨立。先橫再縱、先縱再橫,結果相同。
引入knot point以微調曲面
自由調整同一橫排的控制點們的參數u、同一直排的控制點們的參數v,不一定要等分。曲面仍然穿過所有控制點,但是曲面形狀會改變。
Bézier surface
NURBS surface
NURBS surface
建立N×M個控制點。計算方式同前。
工業繪圖軟體習慣使用NURBS surface。
polyline
polyline
電腦擅於處理大量資料。與其處心積慮、用少量控制點製造曲線,不如直截了當、用大量控制點製造折線。法理上,根據微積分的極限概念,極短的、綿密的、大量的直線,可以逼近曲線。情理上,只要點數夠多,折線就足夠耐看了。
折線與多邊形的資料結構相同。封閉折線就是多邊形。
折線應用廣泛。例如Microsoft PowerPoint的徒手畫。寫程式實作時,不斷擷取當前滑鼠座標,自然而然形成折線。
mesh🚧
mesh
曲線的離散化是折線,曲面的離散化是網格。
大量的平坦的多邊形連成一片。通常是三角形。或者是四邊形。
網格與多面體的資料結構相同。封閉網格就是多面體。
網格應用廣泛。例如三維模型經常使用網格。