0,引入
我们在“问题六十:怎么用ray tracing画回旋体(rotational sweeping / revolution)”中已经学习了这类曲面的画法:
http://blog.youkuaiyun.com/libing_zeng/article/details/54609610
当时,是各种联立方程、微分等等,然后解一元六次方程。不得不说“三角形网格”确实是个好东西,接下来,我们看看怎么用三角形网格来细分这类曲面。
1,理论介绍
“回旋体”是指某“基本曲线”围绕某轴线旋转一周得到的曲面。我们这里考虑的“基本曲线”是由多段b-spline曲线拼接而成的曲线段;“轴线”是Y轴。(关于b-spline曲线,可以参考:
http://blog.youkuaiyun.com/libing_zeng/article/details/54565614)
接下来,我们看看用三角形网格是怎么细分回旋曲面的。(若对下方内容有疑问,请参考前面两个链接对应的文章)
图1中的曲线段是由3段“三次b-spline曲线段”组成,每一段“三次b-spline曲线段”是由四个控制点确定的。
另外,注意图一中的坐标系:曲线有自己的坐标系(一般称为局部坐标系)uv,曲线上任意点P的坐标为(u,v)。图中所示状态是曲线所在平面uov刚好旋转到xoy平面,所以此时:u坐标系和x坐标系重合;v坐标系和y坐标系重合。
对于,每一段“三次b-spline曲线段”上的任意点P(u,v),根据“三次b-spline曲线”的参数方程:
“三次b-spline曲线”的参数方程中引入了参数s,我们还需引入另一个参数phi(如图2所示)。参数phi确定曲线段在旋转过程中的位置。
曲线任意点P(u,v)在空间中的坐标(x,y,z)怎么确定呢?
根据图1,我们知道y=v;
根据图2,我们知道x=u*cos(phi)、z=u*sin(phi)。
即:
计算过程:
1,已知的控制点坐标、参数s可以确定点P在uv坐标系中的坐标。(即“式子100.1”)
2,根据“旋转”的性质(如图2)得到空间坐标(x,y,z)和局部坐标(u,v)之间的关系,从而确定空间坐标(x,y,z)
对应三角形网格细分过程:
1,细分参数s、phi(即给定这两个参数);
2,根据参数确定细分点的空间坐标。
2,C++代码实现
像之前一样,细分函数在Grid.cpp中实现。
// ------------------------------------ tessellate_flat_rotational_sweeping ---------------------------------------
// tesselate rotational sweeping surface into flat triangles that are stored directly in the grid
void
Grid::tessellate_flat_rotational_sweeping(const