B樣條曲線(B-spline Curves)
關鍵字:NURBS,基函式,控制點,節點,
看了網上很多相關資料才得以下筆,資料太多,這裡就不一一列舉了,感謝各位大佬的資料
本部落格順序不太好,看前面的東西可能需要提前看後面的東西。正在努力修煉,敬請諒解
寫了個B樣條曲線計算的完成程式,包括繪圖,https://download.csdn.net/download/qq_40597317/10646881,BaseFunction部分參考了https://www.cnblogs.com/nobodyzhou/p/5451528.html 侵刪 重點就是由於規定了0/0=0,所以最需要注意的地方,原作者的思路是如果除數為0,就讓除數為1,然後繼續運算。這個思路真的很棒,如果被除數為0的話,那麼結果就是0,否則的話結果就是被除數了。顯然也沒有人要求到這點。執行影象結果如下:
一、定義
1.1 概述
是B-樣條基曲線(給定區間上的所有樣條函式組成一個線性空間。這個線性空間的基函式就叫做B樣條基函式)的線性組合。
B-樣條是貝茲曲線的一種一般化,B樣條不能表示一些基本的曲線,比如圓,所以引入了NURBS,可以進一步推廣為非均勻有理B-樣條(NURBS)。三者關係可以表示為:
細分定義域
直接細分(Subdividing)曲線是很困難的。因此,我們細分曲線的定義域。因此,如果曲線的定義域是[0,1],這個閉區間被稱為節點(knots)的點細分而成。設這些節點是 0 <= u0 <= u1 <= ... <= um <= 1。那麼點C(ui)的曲線細分如下圖所示,因此,修改[0,1]的細分會改變曲線的形狀。
如下圖,這裡有5段曲線組成了整個曲線。下面的直線定義域為[0,1],就是[0,1]被分成五段
可以看出,這裡定義域被節點細分,節點分別是0, 0.2, 0.4, 0.6, 0.8,1,6個節點正好可以把定義域(即下面的黑色線段)分成5段。
可以看出,6個節點分別對應於曲線上的一個點,可以用代表對應的曲線上的點,被稱為節點點(knot point),節點點把B-樣條曲線劃分成5個曲線段,每個都定義在一個節點區間上。這些曲線段都是 p 次的貝塞爾曲線。
節點(knots)
有
那麼被稱為節點,顯然上述的m=5
設U是m+1個非遞減數的集合,那麼有,集合U稱為節點向量(knot vector)。
如果,那麼是一個重複度(multiplicity)為k的多重節點,k>1,否則如果一個節點只出現一次,那麼這就 是一個簡單節點。如果節點等間距,節點向量或節點序列稱為均勻的;否則它是非均勻的。
是第i節點個區間,i=0,1,...,m
所有的B樣條基函式都被假設在定義域上,通常為0,為1
1.2 組成
總之,為了設計一個B-樣條曲線,我們需要一系列的控制點(就是下圖折線的連線點,一共8個),一系列的節點和一系列的係數,每個係數對應一個控制點,所以所有曲線段連線在一起滿足某個連續 條件。係數的計算可能是最複雜的步驟因為它們必須保證某個連續條件。
將多個貝塞爾曲線連線就可以得到B樣條。
如下圖所示,這裡有8個控制點,依次用線段連線,B樣條曲線由一系列5條3次的貝塞爾曲線連線形成。
一般次數越低(即p越小),那麼B樣條曲線就更容易逼近他的控制折線
二、特點
2.1 一般不經過控制點
B樣條由一系列控制點決定,但是B樣條不會經過其控制點。
2.2 分段
以上所有的分段都為Bezier曲線,對於分段Bezier曲線,不同的曲線段相互獨立,移動控制點只會影響其所在的Bezier曲線段,而其他的Bezier曲線段都不會改變,甚至所有關於Bezier曲線的演算法可以同樣地適用於分段Bezier曲線。
核心思想就是:用分段低階多項式通過連續的連線來代替高階多項式
2.3 與Bezier對比
Bezier曲線/曲面不支援區域性的修改和編輯;
Bezier曲線/曲面拼接時,滿足幾何連續條件是十分困難的。
三、數學表達
3.1 一般表達
有n+1個控制點Pi(i=0,1,...,n)和一個節點向量,依次連線這些控制點可以構成一個特徵多邊形,k+1階(k次)B樣條曲線的表示式為(2<=k<=n+1),必須滿足m=n+k+1
其中是k次B樣條基函式,也叫調和函式,或者 k次規範B樣條基函式,下面為其遞迴公式(這個公式叫Cox-de Boor)的定義
顯然,基函式由U定義,其中基函式滿足微分方程:
上圖是基函式的運算關係,從左向右,從上往下可以依次計算各個基函式
基函式:
基函式只在附近的一個子區間非0,這就是區域性的概念。(不明白的)
基函式表示基函式的次數(degree)為k,這是第i個k次B樣條基函式,i=0,1,...
四、性質
4.1 基函式的性質
1. 區域性支撐性
若,那麼
2.
在任意給定節點區間,最多p+1個非零,分別是
3.非負性
4.規範性
任意給定節點區間,時
可微性
在節點內部,無限次可微,時,
4.2 凸包包含
樣條曲線包含在控制折線(ployline)的凸包內。更特別地,如果u 在節點區間[ui,ui+1)裡,那麼C(u)在控制點Pi-p, Pi-p+1, ..., Pi的凸包裡。
4.3 Pi 隻影響在區間[ui, ui+p+1)上的曲線 C(u)。
五、分類(根據節點向量中節點的分佈)
5.1 均勻B樣條曲線
(這裡的節點可以理解為控制點)
節點成等差數列均勻分佈
5.2 準均勻B樣條曲線
兩端節點0,1重複度為次數k的基礎上加1,即k+1,即,所有內部節點重複度為k+1.
顯然,首尾兩邊是相切的
5.3 分段Bezier曲線
兩端節點重複度為k+1,內部節點重複度為k,顯然此時必須滿足條件(m-1)%k==0
5.4 非均勻B樣條
任意選取的一個序列[u0,...,um],只要在數學上成立即可,這是最一般的情況
六、計算B樣條上的一點的值
7.1 修改曲線的形狀
可以修改一個或多個控制引數:控制點的位置(n+1),節點位置(m+1),和曲線的次數p。
一般為開(open )B-樣條曲線,也就是產生的曲線不會與控制折線(polyline)的第一邊(leg)和最後一邊(leg)接觸,如下圖,對於開曲線,區間不會有基函式的完全支援(“full support”),就是指在這些區間上,只有一個非零基函式。所以有以下結論,對於開B樣條曲線,定義域為
強制第一個節點和最後一個節點的重複度為p+1,那麼產生的曲線就會分別與第一個控制點和最後一個控制點的第一邊和最後一邊相切,如下圖,這是clamped B-樣條曲線。注意,Clamped B-樣條曲線C(u)通過首尾兩個控制點 P0 和Pn
通過重複某些節點和控制點,產生的曲線會是 閉(closed)曲線。會產生閉環,如下圖
如何產生閉曲線?
1.Wrapping控制點
(1)設計一個均勻 m+1 個節點的節點序列:u0 = 0, u1 = 1/m, u1 = 2/m, ..., um = 1。注意曲線的定義域是 [up, un-p].
(2)Wrap頭p 個和最後p 個控制點。更準確地,設P0 = Pn-p+1, P1 = Pn-p+2, ..., Pp-2 = Pn-1 and Pp-1 = Pn.
構建的曲線在連線點處 C(up) = C(un-p)是Cp-1 連續的。.
1.Wrapping節點
1)增加一個新控制點 Pn+1 = P0.因此,控制點的數目是 n+2.
(2)找到一個合適的有 n+1節點的節點序列u0, u1, ..., un 。這些節點不必要是均勻的
(3)增加 p+2 個節點並 wrap 頭 p+2個節點: un+1 = u0, un+2 = u1, ..., un+p = up-1, un+p+1 = up, un+p+2 = up+1 ,如下圖所示。這樣,我們有n+p+2 = (n+1) + p + 1 個節點
(4)定義在上述構建的 n+1個控制點和n+p+2 個節點上的 p 次開B-樣條曲線C(u)是一個閉曲線,在連線點處C(u0) = C(un+1)有Cp-1 連續性。注意閉曲線的定義域是 [u0, un+1]
七、例子
7.1 簡單節點
節點向量是U = { 0, 0.25, 0.5, 0.75, 1 }
7.2 帶正重複度的節點
這個比較簡單,略略略
(4)後面的主要是B樣條曲線的一些性質,暫時用不到,後續更新