B樣條


      在數學的子學科數值分析里,B-樣條是樣條曲線一種特殊的表示形式。它是B-樣條基曲線的線性組合。B-樣條是貝茲(貝塞爾)曲線的一種一般化,可以進一步推廣為非均勻有理B樣條(NURBS),使得我們能給更多一般的幾何體建造精確的模型。

常數B樣條

常數B樣條是最簡單的樣條。只定義在一個節點距離上,而且不是節點的函數。它只是不同節點段(knot span)的標志函數(indicator function)。

b_{j,0}(t) = 1_{[t_j,t_{j+1})} =
\left\{\begin{matrix} 
1 & \mathrm{} \quad t_j \le t < t_{j+1} \\
0 & \mathrm{...} 
\end{matrix}
\right.

線性B樣條

線性B樣條定義在兩個相鄰的節點段上,在節點連續但不可微。

b_{j,1}(t) = 
\left\{\begin{matrix} 
\frac{t - t_j}{t_{j+1} - t_j} & \mathrm{if} \quad t_j \le t < t_{j+1} \\
\frac{t_{j+2} - t}{t_{j+2} - t_{j+1}} & \mathrm{ } \quad t_{j+1} \le t < t_{j+2} \\
0 & \mathrm{... } 
\end{matrix}
\right.

三次B樣條

一個片斷上的B樣條的表達式可以寫作:

S_{i} (t) = \sum_{k=0}^3 \mathbf{P}_{i-3+k} b_{i-3+k,3} (t) \qquad \mbox{ , } t \in [0,1]

其中Si是第i個B樣條片斷而P是一個控制點集,ik是局部控制點索引。控制點的集合會是P_i^w = ( w_i x_i, w_i y_i, w_i z_i, w_i)的集合,其中w_i是比重,當它增加時曲線會被拉向控制點P_i,在減小時則把曲線遠離該點。


片段的整個集合m-2條曲線(S_3,S_4,...,S_m)由m+1個控制點(P_0,P_1,...,P_m, m \ge 3)定義,作為t上的一個B樣條可以定義為

S(t) = \sum_{i=0}^m \mathbf{P}_{i} b_{i,} (t)

其中i是控制點數,t是取節點值的全局參數。這個表達式把B樣條表示為B樣條基函數的線性組合,這也是這個名稱的原因。

有兩類B樣條-均勻和非均勻。非均勻B樣條相鄰控制點間的距離不一定要相等。一個一般的形式是區間隨着插入控制點逐步變小到0。

關於插值與樣條的介紹請看:http://www.cnblogs.com/WhyEngine/p/4020294.html

核心代碼:

 1 void    YcBSpline::BuildWeights()
 2 {
 3     ClearWeights();
 4 
 5     for (Yuint i = 0; i < 4; i++)
 6     {
 7         m_splineWeights[i] = (Yreal*)malloc((m_subD)*sizeof(Yreal));
 8         m_tangentWeights[i] = (Yreal*)malloc((m_subD)*sizeof(Yreal));
 9     }
10 
11     Yreal u, u_2, u_3;
12     for (Yuint i = 0; i < m_subD; i++)
13     {
14         u = (float)i / m_subD;
15         u_2 = u * u;
16         u_3 = u_2 * u;
17 
18         // 參見"游戲編程精粹1"P331
19         m_splineWeights[0][i] = (-1.0f*u_3 + 3.0f*u_2 - 3.0f*u + 1.0f)/6.0f;
20         m_splineWeights[1][i] = ( 3.0f*u_3 - 6.0f*u_2 + 0.0f*u + 4.0f)/6.0f;
21         m_splineWeights[2][i] = (-3.0f*u_3 + 3.0f*u_2 + 3.0f*u + 1.0f)/6.0f;
22         m_splineWeights[3][i] = ( 1.0f*u_3 + 0.0f*u_2 + 0.0f*u + 0.0f)/6.0f;
23 
24         // 參見"游戲編程精粹1"P333
25         m_tangentWeights[0][i] = (-1.0f*u_2 + 2.0f*u - 1.0f)*0.5f;
26         m_tangentWeights[1][i] = ( 3.0f*u_2 - 4.0f*u + 0.0f)*0.5f;
27         m_tangentWeights[2][i] = (-3.0f*u_2 + 2.0f*u + 1.0f)*0.5f;
28         m_tangentWeights[3][i] = ( 1.0f*u_2 + 0.0f*u + 0.0f)*0.5f;
29     }
30 }

切圖:

      相關軟件的下載地址為:http://files.cnblogs.com/WhyEngine/TestSpline.zip

      最后要注意的是:B樣條曲線不會經過其控制點。靠,我一直以為是經過的。因為B樣條是我唯一在項目中使用過的。我用它來平滑游戲中角色刀光所划出的曲面,不過這種細節也沒必要再去修改了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM