問題六十一:三次b樣條(b-spline)曲線的控制點和曲線形狀的對應——以迴旋體的“基本曲線”為例
阿新 • • 發佈:2019-02-06
在這一章節,我們以其中一段曲線段為例,改變其對應的控制點,看看曲線段形狀的改變,同時也看看對應的迴旋體圖形的改變。
控制點座標如下圖:
“問題六十”中的“基本曲線”的控制點對應如上ABCDEF六個點(其中A點在1位置)。對應輸出的迴旋體圖形如下(再次貼出來):
說明一下:
1,由於我們接下來測試時的lookfrom座標和“問題六十”中的座標是有差異的,所以,輸出的圖形立體呈現是有差異的。
2,接下來,我們圖片中的曲線段是從迴旋體上切下來的,會得到兩條關於y軸對稱的曲線段,實際的“基本曲線”中的曲線段對應其中的一條。
我們知道如上回旋體的“基本曲線”是有三段三次b-spline曲線段拼接而成,分別對應的控制點為ABCD、BCDE、CDEF。
我們接下來要測試的是控制點ABCD對應的曲線段。
測試方式:BCD的位置保持不變,A點的位置依次如下改變(12,7,6,2,1,3,5,4,8,9,10,11),然後對比這12中情況的曲線段的變化情況和對應迴旋體的變化情況。
//12 vec3 ctrl_points[6] = {vec3(-2.0, -3.0, 0.0), vec3( 2.0, 4.0, 0.0), vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0), vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//7
vec3 ctrl_points[6] = {vec3(-4.0, 0.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//6 vec3 ctrl_points[6] = {vec3(-4.0, 2.0, 0.0), vec3( 2.0, 4.0, 0.0), vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0), vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//2
vec3 ctrl_points[6] = {vec3(-4.0, 5.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//1
vec3 ctrl_points[6] = {vec3(-1.0, 5.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//3
vec3 ctrl_points[6] = {vec3( 2.0, 5.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//5
vec3 ctrl_points[6] = {vec3( 2.0, 7.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//4
vec3 ctrl_points[6] = {vec3( 4.0, 5.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//8--discover some problems
vec3 ctrl_points[6] = {vec3( 4.0, 4.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//9
vec3 ctrl_points[6] = {vec3( 4.0, 2.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//10
vec3 ctrl_points[6] = {vec3( 4.0, 0.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
//11
vec3 ctrl_points[6] = {vec3( 3.0, -5.0, 0.0), vec3( 2.0, 4.0, 0.0),
vec3( 2.0, 1.0, 0.0), vec3(-0.5, 1.0, 0.0),
vec3( 1.5, -3.0, 0.0), vec3( 3.0, 0.0, 0.0)};
接下來,貼一份A在1位置的完整拆解圖形:
=++
=++
最後,說一下,“曲線段”是怎麼從迴旋體中切出來的呢?
只需要對“一元六次方程”的根對應的z座標的範圍加以限制即可。對應修改的程式碼:
roots_equation_6th(ss6, 0, 1, tol, roots);
for (int j=1; j<(int(roots[0])+1); j++) {
yyv = matrix_c_v[0][i]+matrix_c_v[1][i]*roots[j]+matrix_c_v[2][i]*roots[j]*roots[j]+matrix_c_v[3][i]*roots[j]*roots[j]*roots[j];
roots_t[num_roots_t+1][0] = (yyv-yy0)/yyd;
rec.t = roots_t[num_roots_t+1][0];rec.p = r.point_at_parameter(rec.t);
if (fabs(rec.p.z())<0.5) {
roots_t[num_roots_t+1][1] = i;
roots_t[num_roots_t+1][2] = roots[j];
num_roots_t ++;
} }
}
roots_t[0][0] = float(num_roots_t);