Abstract. This paper is concerned with parametric curves and surfaces definitions, such as singular point and regular point and their application in OpenCascade. The two most common methods of representing curves and surfaces in geometric modeling are implicit equations and parametric functions. Successful geometric modeling is done using both techniques. When you use parametric functions to represent curves and surfaces, you need to pay attention for the characteristic of it, such as singularity of parametric functions.
Key words. OpenCascade, Parametric Curves, Parametric Surfaces, Singular Point, Regular Point
在几何造型中,两种最常用的曲线曲面表示方法是隐式表示(Implicit equations)和参数表示(Parametric functions)。其中参数表示由于构造简单、计算容易、数值稳定等特点而流行于世并成为几何造型的主要方法之一。相比于参数曲线曲面,隐式表示法同样具有自身的优势,如判定点是否位于曲面上很方便。在几何造型内核OpenCascade中,主要也是采用参数表示法来表示曲线曲面,因为有理、非有理B样条曲线曲面及Bezier曲线曲面都是参数表示的。本文主要结合OpenCascade对参数表示的曲线曲面一些性质进行说明,如因参数化引起的奇异性的处理等,学习如何将数学定义应用到实际程序中的思想。
根据向量函数的概念,空间中一条曲线可以表示为参数t的向量函数,
曲线的这种表示方法称为曲线的参数表示,[a, b]称之为参数域。给定了一个具体的曲线方程,称之为给定了一个曲线的参数化。显然,同一条曲线的参数化可能是不同的。如果,
称为曲线p(t)在t=t0是正则的,则p(t0)称为曲线的正则点(Regular Point)。由上式,点p(t0)为正则点的充要条件为x(t0), y(t0), z(t0)的导数不同时为零。若曲线p(t)的所有点都是正则点,就称曲线p(t)为正则曲线。非正则的点称为奇点(Singular Point)。值得注意的是,同一条曲线上的一个点,在某些参数化下为正则点,但是在另外的参数化下可能不是正则点。
例如直线:
为正则曲线,没有奇点。而直线:
表示为同一直线,但是它在以下情况下有两个奇点:
如果曲线p(t)的所有分量函数x(t), y(t), z(t)的k阶导数存在且连续,并且曲线p(t)是正则曲线,则称曲线属于Ck类的。
用两个变量u, v的向量函数p(u,v)描述的曲面称为曲面的参数表示。
参数u,v通常的变化区间为uv平面上的一个矩形区域。如果图2.2.1所示为从参数空间到三维实向量空间(即模型空间)的映射。给定了曲面的参数方程就给定了曲面的一个参数化,也决定了参数域[u1, u2]和[v1, v2]上的点与曲面上点的对应关系。显然曲面的参数化也不是唯一的。
Figure 2.2.1 Parametric Surface
如果固定一个参数,例如v=v0,那么p(u, v0)为单参数u的向量函数,它表示曲面上的一条曲线,称为等参线(Isoparametric curve)或u曲线(u constant Isoparametric curve)。显然曲面p(u, v)上存在两簇等参线即一簇u线和一簇v线。如图2.2.2所示:
Figure 2.2.2 Parametric surface and Isoparametric curves
曲面上的点p(u0,v0)沿u和v线方向的切向量分别为:
如果切向量pu(u0,v0)和pv(u0,v0)不平行,即:
则称点p(u0,v0)为曲面的正则点(Regular Point),否则称为奇点(Singular Point)。如果曲面p(u,v)上所有点都是正则点,即曲面上每点都存在法向量,就称这样的参数化曲面为正则的。
Figure 2.2.3 Tangents on a surface
曲面上过任意点p的切向量为上述两个偏导数的线性组合,因此其切线位于这两个向量所张成的平面内,如图2.2.3所示。这个平面称为曲面在点p的切平面。称过点p且垂直于该点切平面的直线为法线,与两个切向量满足右手法则,法向量为这两个向量的叉乘:
曲面上任意点处的法向量如图2.2.4所示:
Figure 2.2.4 Normal on a surface
参数表示法易于规定曲线曲面的范围。在参数表示形式中,曲线曲面的有界性由参数区间的有界性自然得到。另一方面,无界的几何元素如直线,利用参数方法表示也是不方便的。OpenCascade的拓朴结构中TopoDS_Edge和TopoDS_Face包含的几何元素都是有界的,主要是因为其中的几何曲线曲面是参数表示的。
Figure 3.1 Get bound of parametric curve and surface
曲线的参数表示同时给出了曲线的一个方向(natural direction),如设a≤u≤b,曲线C(u)方向为从C(a)到C(b)。对于曲面而言,方向为曲面的法向。
在OpenCascade中使用枚举TopAbs_Orientation定义了方向的几中类型。若拓朴边的朝向为TopAbs_FORWARD,则表示边的的逻辑方向与参数曲线的natural direction相同;若为TopAbs_REVERSED,则表示逻辑方向与参数曲线的natural direction相反。类似地,若拓朴面的朝向为TopAbs_FORWARD,则面的朝向与参数曲面的法向相同;若面的朝向为TopAbs_REVERSED,则面的朝向与参数曲面的法向相反。
Figure 3.2 Orientation of TopoDS_Shape
参数曲线曲面上点的计算很简单,只需要根据参数直接可计算出曲线曲面上的点。计算曲线曲面上点的切向量等也很方便。
Figure 3.3 Get point on parametric curve and surface
在用计算机进行形状设计和表示时,参数形式更直观、自然。在很多参数表示形式中,如Bezier和B样条系统具有相当重要的几何意义。这导致直观的设计方法和具有几何特色、数值稳定的算法。
任何事物都不是完美的,既存在有利的一面,也存在不利的一面,参数表示法也不例外。因此也有人对参数表示与隐式表示之间的转换进行了研究,以便在适当的情况下选择更适合的计算方式。
当计算曲线曲面上的点时,采用隐式表示形式是困难的,用参数表示就很容易;但当给定一个点,要判断它是否在曲线或曲面上时,采用参数形式很困难,但是使用隐式给示就很容易。
尽管用参数表示不易判断点是否在曲线曲面上,在OpenCascade中也只能在一定的偏差范围Tolerance内来判定点是否在参数曲线曲面上。类GeomLib_Tool提供了相关的功能:
Figure 4.1 Compute the parameters of a given point for curve and surface
当采用参数形式时,经常需要处理由参数化引起的奇异性(Singularity),而这种奇异性并不是由于本身的几何特性引起的。典型的例子是用参数表示的球面。按参数方程它的两个极点是奇点,处理时需要特别注意。但在几何上,两个极点和球面上的其他点并无不同之处。下面结合OpenCascade中球面的参数方程进行说明。
在OpenCascade中球面的参数方程为:
分别沿u,v方向求偏导矢,即分别沿经线和纬线的速度矢量,得:
曲面在一点处存在法矢及相应切平面是曲面的几何性质,与曲面的参数化无关。因此,尽管不同的参数化会产生不同的偏导矢,但只要u或v方向上的切矢都不为零,则将u,v的切矢叉乘单位化后的法向是都是相同的。OpenCascade中的球面,对于所有的u∈[0, 2π]有:
即Su在球面的北极和南极消失(为零矢量),对应v=-π/2和v=π/2时的两个边就分别退化(Degenerated)成两个点。很明显,球面在两个极点的法矢确实是存在的,但在这种参数化之下,无法用上述方法来计算它的法向量。
Figure 4.2 Singularity of Sphere and its Degenerated Edges
OpenCascade中还有衔接边(Seam Edge)的概念。参数区域的矩形范围内的两个对边可以映射成模型空间中的同一条边,这样的边就称为衔接边(Seam Edge)。矩形区域也可映射成模型空间中的一个点,根据正则点和奇点的定义可知,这样的点为奇点(Singular Point),对应的边为退化边(Degenerated Edge)。
Figure 4.3 Singularity of Cone and its Seam Edge
由曲线曲面的正则与奇异性定义来理解OpenCascade中Degenerated的意义。
//======================================================================= //function : Degenerated //purpose : Returns True if the edge is degenerated. //======================================================================= Standard_Boolean BRep_Tool::Degenerated(const TopoDS_Edge& E) { return (*((Handle(BRep_TEdge)*)&E.TShape()))->Degenerated(); }
下面通过程序来验证OpenCascade中参数表示的球面的两个退化边的参数对应为v=-π/2和v=π/2。
通过程序示例来说明OpenCascade中参数表示的球面具有奇异性的两个退化边对应的参数为v=-π/2和v=π/2。程序还演示了如何从拓朴子结构找到与其相关的父结构,如通过拓朴边找到与其相关的面。
/* * Copyright (c) 2014 eryar All Rights Reserved. * * File : Main.cpp * Author : [email protected] * Date : 2014-03-09 22:28 * Version : 1.0v * * Description : Test singularity of the sphere in OpenCascade. * */ // OpenCascade library. #define WNT #include <TopoDS.hxx> #include <TopExp.hxx> #include <TopExp_Explorer.hxx> #include <BRepPrimAPI_MakeSphere.hxx> #include <TopTools_ListIteratorOfListOfShape.hxx> #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> #pragma comment(lib, "TKernel.lib") #pragma comment(lib, "TKMath.lib") #pragma comment(lib, "TKBRep.lib") #pragma comment(lib, "TKTopAlgo.lib") #pragma comment(lib, "TKPrim.lib") /** * @breif Find the face for the given edge, i.e the face which the given edge is on it. */ TopoDS_Face FindFaceOfEdge(const TopoDS_Shape& theShape, const TopoDS_Edge& theEdge) { TopoDS_Face theFace; TopTools_IndexedDataMapOfShapeListOfShape theMap; TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, theMap); const TopTools_ListOfShape& theFaces = theMap.FindFromKey(theEdge); TopTools_ListIteratorOfListOfShape theIterator(theFaces); for (theIterator.Initialize(theFaces); theIterator.More(); theIterator.Next()) { theFace = TopoDS::Face(theIterator.Value()); } return theFace; } void TestSingularity(void) { TopoDS_Shape theSphere = BRepPrimAPI_MakeSphere(1.0); for (TopExp_Explorer edgeExp(theSphere, TopAbs_EDGE); edgeExp.More(); edgeExp.Next()) { const TopoDS_Edge anEdge = TopoDS::Edge(edgeExp.Current()); Standard_Real aFirst = 0.0; Standard_Real aLast = 0.0; gp_Pnt2d U1V1; gp_Pnt2d U2V2; Standard_Boolean IsDegenerated = BRep_Tool::Degenerated(anEdge); BRep_Tool::Range(anEdge, aFirst, aLast); BRep_Tool::UVPoints(anEdge, FindFaceOfEdge(theSphere, anEdge), U1V1, U2V2); std::cout << "Edge is Degenerated: " << (IsDegenerated ? "True" : "False") << std::endl; std::cout << "Edge parameters on face: " << std::endl; std::cout << " (" << U1V1.X() << ", " << U1V1.Y() << ")" << std::endl; std::cout << " (" << U2V2.X() << ", " << U2V2.Y() << ")" << std::endl; std::cout << std::endl; } } int main(int argc, char* argv[]) { TestSingularity(); return 0; }
程序输出结果如下所示:
由上输出结果可知,当球上的边为退化边时,对应的参数u∈[0, 2π],v=-π/2和v=π/2。
本文通过参数曲线曲面的相关定义,来理解曲线曲面参数表示法的特性。通过正则点、奇点的定义来理解参数表示法中存在的奇异现象。结合OpenCascade中球面的参数方程,分析其奇异性,进而去理解OpenCascade中因奇异性导致的退化(Degenerated)现象的处理。关于曲线曲面参数表示的奇异性的更多内容可以参考相关书籍。
感谢OpenCascade Team努力的工作与开放的态度,才有机会接触到并从中学到几何造型相关知识。
感谢OpenSceneGraph对OpenGL的包装,使OpenGL的使用更方便。
感谢全世界志趣相投的朋友们的鼓励与支持,与你们的讨论交流使我受益匪浅,并乐在其中。
感谢WPS提供了免费版本的文档编辑工具,方便了文档的编辑及导出为PDF文件。
我想引用大学英语课本中第一课中的话来描述一下此时的感受:
Learning a foreign language was one of the most difficult yet most rewarding experiences of my life. Although at times, learning a language was frustrating it was well worth the effort.
Learning a foreign language has been a most trying experience for me, but one that I wouldn’t trade for anything. Not only did learning another language teach me the value of hard work, but it also gave me insights into another culture, and my mind was opened to new ways of seeing things. The most wonderful result of having learned a foreign language was that I could communicate with many more people than before. Talking with people is one of my favorite activities, so being able to speak a new language lets me meet new people, participate in conversations, and form new, unforgettable friendships. Now that I speak a foreign language, instead of staring into space when English is being spoken, I can participate and make friends. I am able to reach out to others and bridge the gap between my language and culture and theirs.
把其中的a foreign language换成OpenCascade或其他新鲜事物也同样适用。
1. Les Piegl, Wayne Tiller, The NURBS Book, Springer-Verlag, 1997
2. 王仁宏, 李崇君, 朱春钢. 计算几何教程. 科学出版社, 2008
3. Roman Lygin. OpenCASCADE Notes. http://opencascade.blogspot.com
PDF Version: Parametric Curves and Surfaces