VC402 基于NURBS计算机图形理论的曲线曲面图形设计
1.无需注册登录,支付后按照提示操作即可获取该资料.
2.资料以网页介绍的为准,下载后不会有水印.资料仅供学习参考之用.
密 惠 保
目前,计算机图形学技术已渗透到各行各业,经过30多年的发展,计算机图形学已得到广泛的应用。计算机图形技术也受到越来越多的工程技术人员和科技工作者的关注。
随着计算机技术的迅速发展和快速普及,因发展的迫切需要,计算机处理图形的软件也越来越多,功能越来越复杂,也越来越完善。而我要研究的课题相关的NURBS计算机图形理论是国际标准化组织(ISO)颁布的工业产品数据交换标准STEP中作为定义工业产品几何形状的唯一数学方法。
本课题的目的是研究NURBS的曲线曲面生成算法,实现生成NURBS曲线曲面的软件。利用OpenGL、C++、已及MFC编程实现的软件能生成二维或者是三维的图形,并且提供简单的一些编辑功能。 内容来自think58
目前,计算机图形学技术已渗透到各行各业,经过30多年的发展,计算机图形学已得到广泛的应用。计算机图形技术也受到越来越多的工程技术人员和科技工作者的关注。
随着计算机技术的迅速发展和快速普及,因发展的迫切需要,计算机处理图形的软件也越来越多,功能越来越复杂,也越来越完善。而我要研究的课题相关的NURBS计算机图形理论是国际标准化组织(ISO)颁布的工业产品数据交换标准STEP中作为定义工业产品几何形状的唯一数学方法。
非有理B样条方法虽然在表示与设计自由曲线、曲面形状时有很好的造型能力,然而它却不能精确表示抛物线以外的二次曲线、曲面,而只能给出近似的表示。NURBS方法不但继承了非有理B样条的几乎全部性质,而且有自己独特的优点。此外,由于NURBS方法增加了与控制顶点想对应的附加造型因子即权因子,使得在对曲线进行较小的修改时,不必改变其控制顶点,只需增大或减小权因子即可。如果要对曲线进行较大的修改,可同时对控制顶点和权因子进行修改,这就大大增强了曲线的造型能力。
NURBS能够比传统的网格建模方式更好地控制物体表面的曲线度,从而能够创建出更逼真、生动的造型。NURBS曲线和NURBS曲面在传统的制图领域是不存在的,是为使用计算机进行3D建模而专门建立的。在3D建模的内部空间用曲线和曲面来表现轮廓和外形。它们是用数学表达式构建的,NURBS数学表达式是一种复合体。NURBS继承了BEZIER方法的一切优点,克服了BEZIER方法存在的缺点,较成功的解决了造型曲面局部控制问题,又在参数连续性基础上解决了链接问题,从而使自由型曲线曲面形状的描述问题得到了较好解决。NURBS造型方式与网格、面片等方法相比,在复杂曲线曲面造型方面有较大的优越性,造型效率高、曲线曲面修改更容易。这使得NURBS建模方法能更好地控制物体表面曲线度,从而可以创建出更为复杂、形状更为生动、效果更为逼真的曲面造型。所以NURBS曲线曲面被广泛的应用于产品设计和创新中。 think58好,好think58 [来源:http://think58.com]
1 XXXX系统开发概述
1.1研究的基本内容
NURBS是Non-Uniform Rational B-Splines的缩写,是非统一有理B样条的意思,是在B样条的基础上,引入了权因子,并用有理分式表示的一种曲线表示形式。它是在非有理B样条方法的基础上,引入了权因子和分母得来的。
本课题通过用NURBS构造曲线曲面设计时序列生成的算法,用C语言实现该算法,并通过OPENGL设计可行的图形软件。通过一个实例来说明算法的执行过程和程序的可行性。并且尽可能的完善软件的功能并实现。 内容来自think58
[资料来源:THINK58.com]
需要解决的主要问题
本课题的目的是做出能实现NURBS曲线曲面的软件。在软件设计过程中,应把握的要点:OpenGL是图形学类团建开发的有效开发工具,通过C++编程实现的软件能生成二维或者是三维的图形。若还有时间,打算在软件设计成功后,考虑软件界面的美化问题。
采用的研究方法
设计用软件形式实现计算机图形NURBS的曲线曲面。
本课题选用的开发工具准备用OPENGL。
为了绘制出光滑的曲线和曲面,一般的方法是用大量的基本图元来近似拟合,这种做法常常需要较大的计算量和存储空间,而且不够精确。实际上,许多光滑的曲线和曲面是可以利用少量控制点作精确描述的,在科学计算中常用到的各种样条和样条曲面,如B样条、Bezier曲线和曲面、Hermite样条就属于这一类,这些都在OpenGL的求值器命令中可以被精确的描述。使用OpenGL求值器,可以任意精度描述曲线曲面可以自动计算曲面法向量,还可以轻松自如的绘制曲面的红框图以及有光照和阴影的曲面。而且OpenGL的辅助车函数还提供了NURBS接口。
OpenGL(Open Graphic Library)是近几年发展起来的一个性能卓越的三维图形标准,它是由SGI公司的IRIS GL图形库开发而来的三维真实感图形生成工具,鉴于它的跨平台、高质量、高效率、功能完善等特点,已成为各种平台下的三维图形制作及交互式场景处理的工业标准。被广泛地运用于科学计算可视化、计算机动画和虚拟显示等计算机图形学热点问题的解决中,其特点有:OpenGL独立于窗口系统和操作系统,以它为基础开发应用程序可以十分方便地在各种平台间移植;OpenGL可以与Visual C++紧密接口,便于实现机械有关计算和图形算法, 本文来自think58 [资料来源:www.THINK58.com]
ault)汽车公司的贝塞尔(Bezier)发表了一种用控制多边形定义曲线和曲面的方法。同期,法国雪铁龙(Citroen) 汽车公司的德卡斯特里奥(de Castelijau)也独立地研究出与Bezier类似的方法。1972年,德布尔(de Boor)给出了B样条的标准计算方法。1974年,美国通用汽车公司的戈登(Gorden)和里森费尔德(Riesenfeld)将B样条理论用于形状描述,提出了B样条曲线和曲面。1975年,美国锡拉丘兹(Syracuse)大学的佛斯普里尔(Versprill)提出了有理B样条方法。80年代后期皮格尔(Piegl)和蒂勒(Tiller)将有理B样条发展成非均匀有理B样条方法,并已成为当前自由曲线和曲面描述的最广为流行的技术。
曲线、曲面可以用显式、隐式和参数表示,由于参数表示的曲线、曲面具有几何不变性等优点,计算机图形学中通常用参数形式描述曲线、曲面.
显示、隐式和参数表示
曲线和曲面的表示方程有参数表示和非参数表示之分,非参数表示又分为显式表示和隐式表示。
对于一个平面曲线,显式表示一般形式是:y=f(x)。在此方程中,一个x值与一个y值对应,所以显式方程不能表示封闭或多值曲线,例如,不能用显式方程表示一个圆。
如果一个平面曲线方程,表示成f(x,y)=0的形式,我们称之为隐式表示。隐式表示的优点是易于判断函数f(x,y)是否大于、小于或等于零,也就易于判断点是落在所表示曲线上或在曲线的哪一侧。
[资料来源:www.THINK58.com]
对于非参数表示形式方程(无论是显式还是隐式)存在下述问题:
1. 与坐标轴相关;
2. 会出现斜率为无穷大的情形(如垂线);
3. 对于非平面曲线、曲面,难以用常系数的非参数化函数表示;
4. 不便于计算机编程。 copyright think58 [来源:http://think58.com]
易于用矢量和矩阵运算,从而大大简化了计算。
位置矢量、切矢量、法矢量、曲率和挠率
一条用参数表示的三维曲线是一个有界点集,可写成一个带参数的、连续的、单值的数学函数,其形式为:
x=x(t),y=y(t),z=z(t),0≤t≤1;
1. 位置矢量
如图3.1.1所示,曲线上任一点的位置矢量可表示为:P(t)=[x(t), y(t), z(t)];其一阶、二阶和k阶导数矢量(如果存在的话)可分别表示为:
表示一条参数曲线的有关矢量
2. 切矢量
若曲线上R、Q两点的参数分别是t和t+△t,矢量△P=P(t+△t)-P(t),其大小以连接RQ的弦长表示。如果在R处有确定的切线,则当Q趋向
(ds)2=(dx)2+(dy)2+(dz)2
引入参数t,上式可改写为:
考虑到矢量的模非负,所以:
故弧长s是t的单调增函数,其反函数t(s)存在,且一一对应,得
P(t)=P(t(s))=P(s)
于是:
即T是单位切矢量。
3. 法矢量
对于空间参数曲线任意一点,所有垂直切矢量T的矢量有一束,且位于同一平面上,该平面称为法平面,如图3.1.2所示。
曲线的法矢 think58.com [版权所有:http://think58.com]
若对曲线上任一点的单位切矢为T,因为[T(s)]2=1,两边对s求导矢 于矢量B的法矢称为曲线在该点的副法矢,B则称为单位副法失量。
对于一般参数t,我们可以推导出:
T(切矢)、N(主法矢)和B(副法矢)构成了曲线上的活动坐标架,且N、B构成的平面称为法平面,N、T构成的平面称为密切平面,B、T构成的平面称为从切平面。
4. 曲率和挠率
长的转动率(如图3.1.3(b))。挠率大于0、等于0和小于0分别表示曲线为右旋空间曲线、平面曲线和左旋空间曲线。
[资料来源:http://think58.com]
面说到,使用OpenGL作为图形API。用OpenGL 作为发,需要安装OpenGL的开发包,并需要加入几个头文件、引入相应的库文件,并且在执行期间,需要导入相应的DLL。
下表列出了OpenGL所需要加入的头文件。
#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/GLUT.h> think58好,好think58
图形设备类(GraphicDevice)对OpenGL进行了封装,以提供更加友好的接口,分散系统的复杂度,下边是GraphicDevice的部分代码:
List
//------------------------------------------------------------------
// Graphics
//-------------------------------------------------------------------
class GraphicDevice
{
public:
GraphicDevice(){}
~GraphicDevice(){ Cleanup(); }
本文来自think58 [资料来源:http://think58.com]
[来源:http://think58.com]bool Initialize();
bool Begin();
void End(); 本文来自think58 [资料来源:http://www.THINK58.com]
RenderWindow* CurrentRenderWindow(); 本文来自think58
void SetCurrentRenderWindow(RenderWindow* pRenderWindow); 本文来自think58
[资料来源:http://THINK58.com]
void UpdateRenderWindow(int index);
void UpdateAllRenderWindows(); think58
public:
RenderWindow* m_pCurrentRW; 本文来自think58 [资料来源:www.THINK58.com]
std::vector<RenderWindow*> m_RenderWindows; //渲染窗口 本文来自think58
private:
void Cleanup();
};
内容来自think58 [资料来源:http://THINK58.com]
[资料来源:www.THINK58.com]
gluEndCurve(nurbs); //曲线绘制结束
think58好,好think58
gluDeleteNurbsRenderer(nurbs);
曲面的绘制
GLUnurbsObj *theNurb1;
//GLUnurbsObj *theNurb2;
内容来自think58
[资料来源:www.THINK58.com]
GLfloat ctrlpoints[5][5][3] = {{{-3,0.5,0},{-1,1.5,0},{-2,2,0},{1,-1,0},{-5,0,0}},
{{-3,0.5,-1},{-1,1.5,-1},{-2,2,-1},{1,-1,-1},{-5,0,-1}},
{{-3,0.5,-2},{-1,1.5,-2},{-2,2,-2},{1,-1,-2},{-5,0,-2}},
{{-3,0.5,-3},{-1,1.5,-3},{-2,2,-3},{1,-1,-3},{-5,0,-3}},
{{-3,0.5,-4},{-1,1.5,-4},{-2,2,-4},{1,-1,-4},{-5,0,-4}}};//控制点 think58好,好think58 [资料来源:http://www.THINK58.com]
theNurb1 = gluNewNurbsRenderer();//创建NURBS对象theNurb1
gluNurbsProperty(theNurb1,GLU_SAMPLING_TOLERANCE,25.0);
gluNurbsProperty(theNurb1,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON);
think58
//theNurb2 = gluNewNurbsRenderer();//创建NURBS对象theNurb2
//gluNurbsProperty(theNurb2,GLU_SAMPLING_TOLERANCE,25.0);
//gluNurbsProperty(theNurb2,GLU_DISPLAY_MODE,GLU_FILL);
[资料来源:THINK58.com]
GLfloat knots[10] = {0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0}; copyright think58
[资料来源:www.THINK58.com]
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glRotatef(50.0,1.0,1.0,0.0);
think58好,好think58 [来源:http://www.think58.com]
[来源:http://www.think58.com]
/*第一个曲面*/
glPushMatrix();
gluBeginSurface(theNurb1);
本文来自think58 [资料来源:www.THINK58.com]
[资料来源:http://THINK58.com]
/*定义曲面形状*/
gluNurbsSurface(theNurb1,10,knots,10,knots,5*3,3,&ctrlpoints[0][0][0],5,5,GL_MAP2_VERTEX_3);
gluEndSurface(theNurb1);
glPopMatrix();
think58好,好think58
[来源:http://think58.com]
gluDeleteNurbsRenderer(theNurb1); think58好,好think58
[资料来源:THINK58.com]
系统其部件的实现
旋转、移动、缩放的实现
图形学中使用Matrix进行这些基本的变换,OpenGL同样提供一些控制变换的接口,而本系统的这些功能的实现就是用OpenGL的接口,使用方式如下:
//平移
glTranslatef(theApp.m_PosX, theApp.m_PosY, 0.0);
// 旋转
glRotated(theApp.m_AngleX,1.0,0.0,0.0);
glRotated(theApp.m_AngleY,0.0,1.0,0.0);
//缩放
glScale(theApp.m_ScaleX, theApp.m_ScaleY, theApp.m_Scale.Z);
copyright think58 [资料来源:http://www.THINK58.com]