“问题六十:怎么用ray tracing画回旋体(rotational sweeping / revolution)”中的“基本曲线”是由三次b-spline曲线段拼接而成。
在这一章节,我们以其中一段曲线段为例,改变其对应的控制点,看看曲线段形状的改变,同时也看看对应的回旋体图形的改变。
控制点坐标如下图:
“问题六十”中的“基本曲线”的控制点对应如上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)};
最后,说一下,“曲线段”是怎么从回旋体中切出来的呢?
只需要对“一元六次方程”的根对应的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]; 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);