B样条背后的直觉
在这篇文章中,我们将从理论上讨论两种类型的样条曲线及其数学表示。 我们将重点介绍 OpenCASCADE (OCC) 技术中的 b 样条,其中包含一个简单的场景和我们使用的必要类。
1、样条曲线
样条曲线是一种数学表示,可以很容易地为其构建一个界面,允许用户设计和控制复杂曲线和曲面的形状。 一般的方法是用户输入一系列点,然后构造一条曲线,其形状与该序列非常接近。 这些点称为控制点。 实际通过每个控制点的曲线称为插值曲线; 通过控制点附近但不一定通过控制点的曲线称为近似曲线。 一旦我们建立了这个界面,然后要改变曲线的形状,我们只需移动控制点。
2、多项式曲线
多项式具有一般形式:
多项式的次数对应于非零的最高系数。 例如,如果 c 不为零,但系数 d 和更高的系数均为零,则多项式的次数为 2。
示例:3 次,d 是最高非零系数。
由四个点唯一定义的三次曲线(在本例中可以在 x = 0 处有一个拐点)。
三次多项式是在计算机图形学中最常被选择用于构建平滑曲线的多项式。 使用它是因为:
- 它是可以支持拐点的最低阶多项式,因此我们可以制作有趣的曲线。
- 它在数值上表现得非常好,这意味着曲线通常是平滑的而不是跳跃的
3、分段多项式曲线
在上一节中,我们看到了四个控制点如何定义三次多项式曲线,从而允许对曲线的四个系数求解四个线性方程。 在这里,我们将看到如何使用两个新想法制作更复杂的曲线:
- 分段多项式曲线的构建
- 曲线的参数化。
假设我们想制作下面显示的曲线。 我们知道一条三次曲线只能有一个拐点,但是这条曲线有三个,用O标示。 我们可以通过输入额外的控制点并使用具有六个系数的 5 次多项式来制作此曲线,但次数高于 3 的多项式往往对控制点的位置非常敏感,因此并不总是能制作出平滑的形状。
在计算机图形学和计算机辅助设计中,通常解决这个问题的方法是通过拼凑几条三次曲线来构造一条具有大量拐点的复杂曲线:
这是可以做到这一点的一种方法。 让每对控制点代表曲线的一段。 每个曲线段都是一个具有自己系数的三次多项式:
在此示例中,十个控制点的 x 坐标值递增,并用索引 0 到 9 进行编号。每个控制点对之间是一个函数,其编号与其最左边的点的索引相同。
4、曲线参数化
到目前为止,我们已经了解了一系列控制点如何定义分段多项式曲线,使用三次函数定义控制点之间的曲线段并在段连接处强制执行不同级别的连续性。 特别是,我们利用了:
- C0 连续性,这意味着两个段在连接处匹配值。
- C1 连续性,这意味着它们在连接处匹配斜率。
- C2 连续性,意味着它们在连接处匹配曲率。
我们能够通过一组线性方程确定曲线段的系数:
其中 a 是所有系数的向量,y 是线性方程右侧常数的向量,M 是编码 C0、C1 和 C2 条件的矩阵。
可以修改此方法以指定参数形式的每个曲线段,如下图所示。
在示例中,两条曲线相同,但是描述它们的方程式不同。 在右侧的参数形式中,我们定义了参数 t0、t1 和 t2,当我们沿着 x 轴在控制点之间移动时,它们在 0 和 1 之间变化。 我们可以写方程:
将 t 与原始 x 坐标相关联。 导数表示当我们在 x 方向上移动时每个 t 变化的速度。
现在我们通过参数三次曲线指定每个曲线段:
5、Open Cascade B 样条曲线
b 样条曲线定义为:
- 次数:Geom_BSplineCurve 的次数限制为由系统定义和控制的值 (25)。 该值由函数 MaxDegree 返回。
- 极点(Pole)表,极点也称为控制点:曲线的极点是用于使曲线变形的“控制点”。
- 具有多重性的结(Knot)表。 对于 Geom_BSplineCurve,结表是不重复的递增实数序列; 多重性定义了结的重复。 B样条曲线是分段多项式或有理曲线。 结是两部分之间连接点的参数。
下图说明 b 样条的节点和控制点之间的区别:
我们的用例:
第1步:在 3D 模型(.STEP 文件)上选择边(边组)
第2步,使用 GeomConvert_CompCurveToBSplineCurve 类将这 3 条边组合成一条曲线。
第3步:使用 BSplineCurve() 从上面的类中获取对象的 B 样条曲线。
Handle(Geom_BSplineCurve) bs = comined_crv.BSplineCurve();
int deg = bs->Degree();
int num_knots = bs->NbKnots();
int num_poles = bs->NbPoles();
第4步:显示 b 样条的一些重要属性,如(度数、结数、控制点数)。
可视化 3D 顶点(根据节点表示)及其切线和二阶导数向量。
gp_Pnt point;//3D point represents the knot(i)
Standard_Real U = bs->Knot(i);//Actual knot
//D2 function computes the corresponding point, tangent vector at the point
//and the second derevitive vector at the same point also.
bs->D2(U, point, tangent_vector, d2_vector);
绿色十字:表示节点的 3D 点,红色箭头:表示该点处的切线向量,黄色箭头:表示该点处的二阶导数向量
我们得出结论,OCC 将许多 b 样条处理为三次样条,并且两个相邻子段之间的连接点上的连续性是 C1 连续性。
原文链接:Dealing with B-splines in OpenCASCADE
BimAnt翻译整理,转载请标明出处