摘要:由于NURBS曲面、曲线构造的复杂性,描述NURBS曲线、曲面必然采用复杂的数据结构,这样给人—机交互带来很大的困难。本文利用VC++编写的NURBS曲线、曲面造型系统可以实时观察曲线、曲面的控制点、节点信息,可以实时对控制点、节点进行诸如添加、修改、删除等操作,这对NURBS曲线曲面造型无疑会带来极大的方便。
关键词:NURBS,造型。
1 NURBS曲线、曲面造型方法
1.1 NURBS曲线方程
一条p阶NURBS曲线被定义作: (图片) 式中:{Pi}——控制点(形成控制多边形);
{ωi}——权因子;
{Ni,p(u)}——p阶B样条基函数,其节点矢量为:
U={a,…,a,up+1,…,um-p-1,b,…,b}
除非另述,一般假定a=0,b=1及对于所有的i都有ωi>0。
令:(图片) 则NURBS曲线方程还可写作:(图片) 1.2 NURBS曲面方程
u向p阶、v向q 阶的NURBS曲面定义为:(图片) 式中:{Pi,j}——构成曲面控制点网;
{ωi,j }——权因子;
{Ni,p(u)}、{Nj,q(v)}——p阶、q阶B样条基函数,其节点矢量为:
U={0,…,0,up+1,…,ur-p-1,1,…,1}
V={0,…,0,vq+1,…,vs-q-1,1,…,1}
这里,r=n+p+1,s=m+q+1。
令:(图片) NURBS曲面方程还可写作:(图片) 2 NURBS曲线、曲面的数据结构
NURBS曲线的属性信息有:次数k,控制点d,权因子w和节点矢量U。NURBS曲面的属性信息有:次数k、l,控制点di,j,权因子wi,j和节点矢量U,V。能否管理好NURBS曲线、曲面,取决于能否对这些属性信息进行有效的组织和管理。而要对曲线、曲面进行方便、有效的管理和计算,良好的数据结构是必不可少的。
NURBS曲线、曲面数据结构图如下:(图片)
Nurbs数据结构图 (图片)
Nurbs曲面数据结构图 这种数据结构形式具有如下几个优点:
(1)运算灵活,便于修改;
(2)易于检索、提高运算速度;
(3)结构简单、便于维护。
3 曲线、曲面数据结构的编程实现
不难看出,上述曲线、曲面数据结构均为双链表结构,并且链表内还包括若干个双链表,如控制点链表、节点链表等。传统的用C语言实现的双链表结构突出的缺点是不直观,编程比较复杂。因此本文采用VC++指针类型的集合样板类实现这种双链表结构,使得对链表中节点的插入、删除和修改非常直观。
3.1 用VC++表示的NURBS曲线的数据结构:
class Curve{
public:
int CurveNo; /*曲线号*/
int k; /*曲线次数*/
ControlPointCP; /*控制点指针*/
KnotVectorKV; /*节点矢量指针*/
}
class ControlPoint
{
public:
int VertexNo; /*控制点序号*/
double Vertex[3]; /*控制点坐标*/
double Weight; /*控制点权因子*/
public:
void FormatControl(CString& str);
};
class KnotVector
{
public:
int KnotNo; /*节点序号*/
int Multiplicity; /*节点重复度*/
double KnotValue; /*节点值*/
public:
void FormatKnot(CString& str);
};
3.2 用VC++表示的NURBS曲面的数据结构
class Surface
{
ControlPoint*Up;
ControlPoint*Vp;
KnotVector*KU;
KnotVector*KV;
}
3.3 用VC++指针类型的集合样板类实现双链表结构
我们以控制点链表为例,说明如何用VC++指针类型的集合样板类CTypedPtrList来实现双链表结构。
typedef CTypedPtrList<CPtrList,ControlPoint>MyTypedPtrList;
MyTypedPtrList ControlPointList;
那么ControlPoint__List为一个空的双链表。我们可以用CtypedPtrList类中的成员函数AddTail()、RemoveTail()、InsertBefore()、InsertAft-er()、GetNext、GetPrev等对表中的数据进行添加、插入和删除等操作。
例如向表中添加一个控制点:
ControlPoint*pControl=new ControlPoint;
pControl->VertexNo=m_VertexNo;;
pControl->Vertex[0]=m_Vertexx;
pControl->Vertex[1]=m_Vertexy;
pControl->Vertex[2]=m_Vertexz;
pControl->Weight=m_Weight;
ControlPoint_List.AddTail(pControl);
如果插入一个控制点:
ControlPoint_List.InsertBefore(pos,pControl);
如果删除一个控制点:
ControlPoint_List.RemoveAt(pos,pControl);
因此用VC++指针类型的集合样板类CtypedPtrList对双链表进行操作简单、直观,不容易出错。其它链表均可照此处理。(图片)
图1 控制点对话框 4 控制点、节点的可视化实现
为了能够实现对控制点、节点链表实时进行插入、删除和修改等操作,将这些操作同对话框联系起来。也就是说,对对话框上控件的操作,就相当于对控制点、节点链表进行相应的操作,从而使对控制点、节点链表实时进行插入、删除和修改等操作的过程可视化。
我们以控制点链表和对话框之间的联系为例,说明利用VC++实现控制点链表的插入、删除和修改等操作过程的可视化。
(1)建立如图1所示的对话框,对话框中有按钮Add、Insert、Update、RemoveAt、RemoveAll,可对控制点链进行操作;有组合框可显示控制点链表中的数据;
(2)建立与对话框相联系的类CmodifierVertex,同时编写与按钮相关的成员函数OnAdd()、OnInsert()、OnUpdate()、OnRemoveAt()和OnRemoveAll();
(3)将控制点链表中的数据在组合框中显示出来。以添加操作为例,VC++代码如下:
void CModifierVertext::OnAdd()
{
∥TODO:Add your control notification handler code here
if(UpdateData()!=TRUE)
return;
ControlPoint*pControl=new ControlPoint;
pControl->VertexNo=m_VertexNo;;
pControl->Vertex[0]=m_Vertexx;
pControl->Vertex[1]=m_Vertexy;
pControl->Vertex[2]=m_Vertexz;
pControl->Weight=m_Weight;
ControlPoint_List.AddTail(pControl);
AddToListBox(pControl); /*将数据添加到组合框*/
}
这样无论何时按系统菜单Modifier中的下拉菜单Vertex,都会看到控制点的数值、个数,为造型提供参考。
5 实例
利用可视化方法建立NURBS曲线、曲面造型系统,对哈尔滨制氧机厂加工的叶轮进行三维实体造型,并通过VC++调用OpenGL图形库中的函数对其进行渲染,完成后如下图2所示,同时提供数控加工数据。(图片)
图2 叶轮的NURBS造型 6 结论
(1)运用VC++指针类型的集合样板类CtypedPtrList处理双链表的新方法,使得对双链表的操作变得简单、直观;
(2)由于造型过程的可视化,使设计者可随时按要求修改、插入和删除控制点、节点而达到设计要求。
** 博士学科点专向科研基金(资助号:98021332)资助项目。
作者单位:哈尔滨工业大学机电学院 哈尔滨 150001
参考文献
1 Les Piegl Wayne Tiller.The NURBS Book,1995
2 Ori Gurewich,Nathan Gurewich.精通Visual C++2.0 for Windows95.学苑出版社,1995
3 Microsoft Corporation.Visual C++2.0 for win32大全(二)——用MFC和win32编程.清华大学出版社,1996
4 孙家广等.计算机辅助几何造型技术.清华大学出版社,1988
5 Jackie Neider,Tom Davis,Mason Woo.OpenGL Program-ming Guide.Addison Welsey,1993
6 Silicon Graphics,Inc.OpenGL Refrence Manual.Addison Welsey,1993
12/7/2004
|