B样条曲线曲面和NURBS曲线曲面C语言算法源程序

合集下载

权威3DMAX NURBS曲线和曲面教程

权威3DMAX NURBS曲线和曲面教程

权威3DMAX NURBS曲线和曲面教程一、NuRBS曲线作用:可制作圆滑的曲线外形‘Create(创建)‘shape(外形)‘NURBSpoint curve(点曲线)CV curve(控制点曲线):曲线在各控制点连接的多边形内参数:attach(附加):将其它曲线附加到当前曲线中二、NURBS曲面作用:可制作圆滑的面,如汽车外壳,床罩,窗帘丝织物品表面‘create(创建) →‘Geomotry(三维几何体) →‘NurBs surface(NurBs曲面) →‘point surface(点曲面)‘cv surface(控制点曲面)1、point surface(点曲面)参数:u lines:X轴节点数v lines:Y轴节点数次对象:point(点):选择1个顶点(单个):选择一行顶点(单行):选择一列顶点(单列):选择交叉的一行一列顶点(行列):选择所有顶点2、cv suface(控制点曲面)参数:Length cvs:长控制点数Width cvs:宽控制点次对象:与点曲面相同三、NurBs创建工具箱作用:方便创建曲线或者曲面1、Curves(曲线)工具箱第一个():建立cv curve(控制点曲线)第二个():建立Point curve(点曲面)第三个():连接两个顶点,限定在点曲线面类第四个():复制曲线第五个():连接2个顶点,点曲线,CV曲面都可相连第六个():产生曲线的轮廓线第七个():镜像复制曲线3、surface(曲面)工具箱第一个():建立cv surface(控制点曲面)第二个():建立point surface(点曲面)第三个():复制曲面第四个和第九个():将2个曲线连接成面第五个():复制曲面,不能分开第六个():镜向复制曲面第七个():将曲面拉伸成面第八个():将曲线旋转成面3DMAX 第十五讲(材质1)一、材质编辑器作用:赋于物体材质,表现出各种实际效果1、主窗口组成①样本窗②水平工具栏③垂直工具栏④材质名称类型⑤参数展示栏2、样本窗显示方式选择某样本球’→‘5╳3或‘6╳43、垂直工具栏①样本类型:以何种方式显示样本②背光:显示/隐藏样本球暗区光线③背景:检查透明材质效果④重复:检查透明材质效果⑤视频颜色检查:检查材质颜色以适应电视输出⑥材质动画预览⑦选项:设置材质,相关参数⑧按材质选择物体4、水平工具栏(1)获取材质(包括复合标准材质)(2)将冷材质重新赋予场景中的物体(3)将材质赋予场景中被选择的物体(4)清除材质(5)热材质变为冷材质(6)保存材质备以后使用(8)材质效果通道,给材质起编号(9)显示场景中物体的贴图(10)显示最后结果(11)回到父层级(12)到同一层次(13)材质/贴图导航器二、同步材质,异步材质1、同步材质称为热材质,当改变材质参数,场景中的物体材质会同步变化,样本球4个角为白三角形2、异步材质称为冷材质,当改变材质参数,场景中的物体材质不随之变化三、给物体贴图选择物体→(材质编辑器按钮)→选择一个样本球→diffuse(散播颜色) →‘(贴图按钮)→“Bitmap(位图) →选择某图片→‘打开→‘(显示贴图按钮)。

贝塞尔曲线B样条NURBS样条学习总结

贝塞尔曲线B样条NURBS样条学习总结

Bezier曲线、B样条曲线和NURBS曲线0.概述1. 贝塞尔曲线(Bezier Curve):贝塞尔曲线由一组控制点和控制点上的权重组成。

贝塞尔曲线的阶数由控制点的数量决定,阶数为n的贝塞尔曲线需要n+1个控制点。

贝塞尔曲线具有局部控制的特性,即曲线上的一段由相邻的几个控制点决定,不受其他控制点的影响。

贝塞尔曲线的计算相对简单,但在变形过程中可能会出现形状扭曲的问题。

2. B样条(B-Spline): B样条曲线是一种基于分段多项式的曲线表示方法。

与贝塞尔曲线不同,B样条曲线的每个控制点都有一个关联的基函数。

这些基函数决定了曲线上每一点的形状。

B样条曲线的阶数可以是任意的,较高阶的B样条曲线能够更灵活地描述复杂的曲线形状。

B样条曲线具有良好的局部控制性和平滑性,可以很好地避免贝塞尔曲线的形状扭曲问题。

3. NURBS曲线(Non-Uniform Rational B-Spline Curve):NURBS曲线是对B样条曲线的扩展,它引入了有理权重的概念。

NURBS曲线的每个控制点都有一个关联的权重,这些权重可以调节曲线上各个点的影响程度。

NURBS曲线能够表示更复杂的曲线形状,如圆弧和椭圆等。

总的来说Bezier曲线中的每个控制点都会影响整个曲线的形状,而B样条中的控制点只会影响整个曲线的一部分,显然B样条提供了更多的灵活性;Bezier和B样条都是多项式参数曲线,不能表示一些基本的曲线,比如圆,所以引入了NURBS,即非均匀有理B样条来解决这个问题;贝塞尔曲线适用于简单的曲线形状设计,B样条曲线具有更好的局部控制和平滑性,适用于复杂曲线的建模而NURBS曲线在B样条的基础上引入了有理权重,可以更准确地描述各种曲线形状Bezier曲线是B样条的一个特例,而B样条又是NURBS的一个特例1.Bezier曲线1.1 贝塞尔曲线的历史:贝塞尔曲线于 1962 年,由法国工程师皮埃尔·贝济埃(PierreBézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计,贝塞尔曲线最初由保尔·德·卡斯特里奥于1959年运用德卡斯特里奥算法开发,以稳定数值的方法求出贝塞尔曲线。

非均匀有理B样条NURBS曲线课件

非均匀有理B样条NURBS曲线课件
基函数与度数的关系
度数和基函数共同决定了曲线的形状和性质。选择合适的 度数和基函数可以实现各种复杂的曲线形状,同时保证曲 线的光滑度和连续性。
03 NURBS曲线的生成方法
初始曲线生成
确定曲线起点和终点
根据设计需求,确定曲线的起点和终点坐标。
选择控制点
根据曲线形状要求,选择合适的控制点,控制点的数量和位置将影 响曲线的形状和精度。
确定权重因子
权重因子用于控制曲线的形状,通过调整权重因子可以改变曲线的 弯曲程度。
曲线细分与光顺
细分
将初始曲线细分成若干个小段, 每段曲线采用B样条曲线进行拟合 ,提高曲线的精度。
光顺
对细分后的曲线进行光顺处理, 消除曲线中的拐点和平滑曲线的 形状,使曲线更加平滑和连续。
曲线修改与调整
修改控制点
参数化精度
参数化的精度决定了曲线 表示的准确性和光滑度, 精度越高,曲线表示越精 确。
控制点与权因子的影响
控制点
控制点和权因子的关系
控制点是NURBS曲线中的重要元素, 它们决定了曲线的形状和位置。通过 调整控制点的位置,可以改变曲线的 形状。
控制点和权因子共同决定了曲线的形 状,通过合理设置它们的值,可以实 现各种复杂的曲线形状。
非均匀有理B样条( NURBS曲线课件
目录
Contents
• NURBS曲线的基本概念 • NURBS曲线的数学表示 • NURBS曲线的生成方法 • NURBS曲线的应用实例 • NURBS曲线的优缺点分析
01 NURBS曲线的基本概念
NURBS曲线的定义
NURBS曲线是一种参数曲线, 它由非均匀有理基函数( NURBS基函数)定义。
易于实现
NURBS曲线的数学模型相对简单,易于在计算机上实现,并且 已经有了许多现成的软件工具可供使用。

NURBS曲线理论

NURBS曲线理论

NURBS曲线理论第三章 NURBS 曲线理论基础NURBS ⽅法的提出是基于描述⾃由曲⾯曲线的B 样条⽅法。

B 样条基函数和B 样条曲线是UURBS 曲线的基础,UURBS 是⾮均匀有理B 样条的英⽂缩写。

因此在给出UURBS 曲线定义之前,先介绍⼀下B 样条基函数和B 样条曲线的相关知识。

3.1 B 样条基函数定义和性质B-Spline Function (简称B 样条)就是B 样条基函数,是样条函数的⼀种。

B 样条不但具有⼀般样条函数所具有的分段光滑⼜在各段交接处具有⼀定光滑性等特点,⽽且具有许多其他优良性质,如连续阶数可调、局部⽀撑性、递推性等。

有很多种⽅法可以⽤来定义B 样条基函数,我们这⾥采⽤de Boor-Cox 递推定义⽅法,是由这种递推法很容易和有效地在计算机上实现。

⽽且de Boor-Cox 递推定义很好地揭⽰了B 样条基函数的性质。

B 样条基函数的de Boor-Cox 递推定义如下:1,01,,11,1i 111[,N 0()()000i i i i i k i k i k i k i k i k i u u u u u u u N N u N u u u u u +++-+-++++?∈?=?--=+--=)其他规定: (3. 1) 上式(3.1)中k 为B 样条的次数(k+1阶);令U={u 0,u 1,…,u m }是⼀个单调不减的实数序列,u i 称为节点序列,U 称为节点⽮量,若存在ui-1,<u i =u i+1=…=u i+r-1B 样条具有良好的性质,简单概括主要有【18,20】:●递推性:定义式(3.1)很好的说明了这个性质。

●规范性:对于定义域内任意参数u ,所有的k 次B 样条基函数之和恒为1,即1)(0,=∑=u N mi k i 。

●局部⽀撑性质:对于定义域内参数u ∈[u i u i+1),⾄多有k+1个⾮零的k 次B 样条N j,k (u ),j=i —k ,i —k+l ,...,i ,其他k 次B 样条在该处均为零。

B样条曲线曲面和NURBS曲线曲1

B样条曲线曲面和NURBS曲线曲1

B 样条曲线曲面和NURBS 曲线曲面(学习笔记和上机练习)非均匀有理B 样条,通常简称为NURBS(Non-Uniform Rational B-Splines)。

NURBS 是非有理B 样条、有理以及非有理B ézier 曲线曲面的推广。

一、要对B 样条曲线曲面和NURBS 曲线曲面有所了解应先了解B 样条基函数 B 样条基函数的定义和性质令{}m u u u U ,...,,10=是一个实数列,即i u ≤1+i u ,i=0,1,…,m-1。

其中,i u 称为节点,U 称为节点矢量,用)(,u N p i 表示第i 个p 次(p +1阶)B 样条基函数,其定义为⎩⎨⎧=,0,1)(0,u N i 若i u ≤u <1+i u 值为1,其他值为0 )()()(1,11111,,u N u u u u u N u u u u u N p i i p i p i p i i p i ip i -++++++-+--+--= (2)由(2)式可知:(1))(0,u N i 是一个阶梯函数,它在半开区间),[1+∈i i u u u 外都为零; (2)当p >0时,)(,u N p i 是两个p -1次基函数的线性组合;(3)计算一组基函数时需要事先指定节点矢量U 和次数p ; (4)(2)式中可能出现0/0,我们规定0/0=0;(5))(,u N p i 是定义在整个实数轴上的分段多项式函数,只在区间][,0m u u 上有意义; (6)半开区间),[1+i i u u 称为第i 个节点区间,长度可以为零,因相邻节点可以相同; B 样条基函数的一些重要性质:1 如果),[1++∉p i i u u u ,则)(,u N p i =0。

2 对于所有的p i ,和u ,有)(,u N p i ≥0.3 对于任意的节点区间),[1+i i u u ,当),[1+∈i i u u u 时,∑-==ipi j pj u N1)(,。

occ生成nurbs样条曲线

occ生成nurbs样条曲线

occ生成nurbs样条曲线全文共四篇示例,供读者参考第一篇示例:在计算机辅助设计(CAD)和计算机图形学领域,NURBS(Non-Uniform Rational B-Spline,非均匀有理B样条)曲线是一种强大的数学表示工具,可以用来描述各种曲线和曲面形状。

与其他曲线表示方法相比,NURBS曲线具有许多优势,如灵活性、精度和精细控制等。

在本文中,我们将介绍如何使用OCC(Open CASCADE Technology)库生成NURBS样条曲线,并探讨其在实际应用中的价值。

OCC是一个开放源代码的CAD/CAM/CAE集成平台,在工程设计领域得到广泛应用。

它包含了大量的几何建模和图形算法,可以用来创建、编辑和分析几何实体。

OCC库中提供了丰富的函数和类来处理NURBS曲线,使得用户可以方便地生成各种复杂的曲线形状。

生成NURBS曲线的关键步骤是定义曲线的控制点、权重、节点和次数。

用户需要指定一组控制点,这些点将决定曲线的形状。

每个控制点都有一个权重值,用来影响该点对曲线的影响程度。

权重值越高,控制点对曲线的影响就越大。

节点是描述曲线弯曲和形状的参数,通过调整节点的位置和权重值,可以控制曲线的曲率和光滑度。

次数定义了NURBS曲线的阶数,影响了曲线的灵活性和精度。

在OCC库中,用户可以通过调用相应的函数和类来生成NURBS 曲线。

用户需要创建一个BSplineCurve对象,并设置曲线的控制点、权重、节点和次数。

然后,可以通过调用相应的函数来计算曲线上的点坐标、切线、曲率等信息。

用户还可以使用OCC库提供的绘图工具将生成的曲线显示在屏幕上,以便进行可视化查看和分析。

NURBS曲线在工程设计和制造中有着广泛的应用。

它们可以用来描述各种曲线形状,如自由曲面、汽车车身、船体等。

通过调整控制点和权重值,用户可以实现对曲线形状的精细控制,从而满足不同的设计需求。

NURBS曲线还可以用来进行曲线重构和拟合,从而实现曲线数据的压缩和处理,提高数据的处理效率和精度。

第8讲-B样条曲线曲面-NURBS曲线曲面

第8讲-B样条曲线曲面-NURBS曲线曲面
-------总结 Bezier 曲线与曲面; 定义表达式? 伯恩斯坦基函数定义、性质、对曲线的影响? 递推算法?
35
第3章 车身曲线曲面的数学模型基础
-------总结 B样条曲线与曲面; 如何理解B样条曲线定义? 与贝齐尔相比的区别? 端点性质?
36
作业
1.说明两条曲线达到C、G连续的条件。 2.分析三次伯恩斯坦基函数对贝齐尔曲线的影响。 3.分析曲线升阶后的意义。 4.如何把一段贝齐尔曲线分成等长的两段?
点P0P2的直线段
P1
双曲线
抛物线
椭圆
P0
P2
图3.1.36 圆锥曲线的 NURBS表示 23
NURBS曲线---修改
常用的方法有修改权因子、控制点和反插节点。 修改权因子
当保持控制顶点和其它权因子不变,减少或增加某权因 子时,曲线被推离或拉向相应顶点。
S* Pi
S
N B
修改权因子
24
NURBS曲线---非均匀有理B样条曲面
⎡ 2 − 2 1 1 ⎤⎡ Pk ⎤
= ⎢⎢− 3
⎢0
⎢ ⎣
1
3 0 0
−2 1 0
−1⎥⎥
0⎥
0
⎥ ⎦
⎢ ⎢
Pk
+1
⎥ ⎥
⎢ ⎢ ⎣
Rk Rk +1
⎥ ⎥ ⎦
=
M
h

Gh
28
三次Hermite曲线---弗格森
三次Hermite样条曲线的方程为:
p(t) = T ⋅ M h ⋅ Gh
t ∈[0,1]
p(0) = Pk , p(1) = Pk+1 p′(0) = Rk , p′(1) = Rk+1

第五章 曲线曲面(NURBS)的操作概要

第五章 曲线曲面(NURBS)的操作概要

七、 边框建模的方法
(1)、创建新的场景,命名为Boundary。 (2)、应用CV工具在Top视图中创建一条曲线。 (3)、在Front视图中创建两条直线,同时复制一条曲线。 (4)、 选择 所有线,使用Surface——Boundary选项,点 击图标调出设置窗口。Curve Ordering部分的Automatic 的作用是自动根据边框创建曲面 (5)、 点击Boundary即可创建边界曲面。
四、旋转(Revolve)
(1)、创建一个场景。 (2)、应用CV工具在Front视图中创建一条曲线。 (3)、选择该曲面,使用Surface——Revolve选项,点击 属性图标调出设置窗口。Axis Preset定义曲线旋转 轴;Start Sweep Angle和End Sweep Angle定义开始 和结束的角度。

五、倒角(Bevel)
(1)、新建场景命名为Bevel。 (2)、创建字体。使用Create→Text命令,在场景中创建 文字。 (3)、选择一个字母,使用Surface→Bevel Plus选项,点 击图标调出设置窗口。 (4)、点击Apply按钮,创建一个倒角字母。 (5)、依次选择其他字母进行倒角,完成倒角创建模型的 操作。
一、切割曲面(Trim Surfaces)与布尔运算 (Booleans)
• 1、切割曲面的方法(以圆柱体为例) • (1)、创建一个场景,命名为Trim。 • (2)、在场景中创建一个NURBS圆柱体,并同时创建 一个Curve的圆。 • (3)、使用缩放工具放大该圆,同时进行旋转。 • (4)、选择圆柱和曲线,使用Edit NUEBS—— Project Curve on Surface命令,点击图标调出设置 窗口。完成参数设置,圆环按照法线的方向投射在圆 柱上。 • (5)、选择圆柱,使用Edit NUEBS——Trim Tool命 令,点击图标调出设置窗口。Keep的作用是保留分割 点所在的曲面;Fitting Tolerance定义切割的精确度, 值越小越精确。 • (6)、点击鼠标左键,在保留的曲面上画一个点,也 可以画多个点,回车键结束运行。 • (7)、通过移动切割边界,可以修改切割位置,移动 圆环还可以调整切割形状。

专升本计算机图形学与C技术试卷答案

专升本计算机图形学与C技术试卷答案

专升本计算机图形学与CAD技术一、共70题,共150分1. CAD的一个未来发展方向是实现跨部门或行业、跨地域的企业协同产品开发;描述的是: 2分A.集成化B.网络化C.智能化D.标准化.标准答案:B2. 有限元的基本思想是 2分A.弹性力学B.结构离散C.机构分析与综合D.面向对象编程.标准答案:B3. 以下是计算机辅助制造软件 2分.标准答案:C4. 以下属于CSG表达特点的是 2分A.以边界表示形体B.以二叉树表示形体C.数据结构复杂D.形体更新快.标准答案:B5. 以下结构划分合理的网格是 2分A.B.C..标准答案:C6. AutoCAD中,r是命令的缩写 2分.标准答案:A7. 以下不是形体在计算机内部表示的是 2分A.线框模型B.表面模型C.实体模型D.二叉树模型.标准答案:D8. 可以计算实体的质量和惯性矩 2分A.物性分析B.装配干涉检查C.装配树D.爆炸图;.标准答案:A9. 以下不属于Bezier曲线性质和特点的是: 2分A.曲线通过首末点且与首末控制多边形边相切B.曲线在控制多边形边的凸包内进行针对设计人员的人力资源管理.标准答案:A19. 下列算法不是递推的; 2分算法 B.简单的种子填充算法算法 D.中点画线法.标准答案:A20. 是基本体素 2分A.倒角B.拉伸C.球体.标准答案:C21. 在创成式CAPP系统中进行逻辑决策的常用方法为 2分A.决策树B.决策表C.逻辑联系图D.二叉树.标准答案:A,B22. 形体在计算机内部的表示常用模型; 2分A.线框模型B.表面模型C.实体模型D.渲染模型.标准答案:A,B,C23. 有限元分析软件由组成 2分A.前处理B.分析计算C.概率设计D.后处理.标准答案:A,B,D24. CAD系统的选型原则有: 2分A.具有专业应用足够的系统功能B.软件系统具有良好的用户界面C.具有良好的二次开发接口D.硬件系统要支持并行计算机.标准答案:A,B,C25. 优化数学模型的三要素是 2分A.设计变量B.设计对象C.约束条件D.目标函数.标准答案:A,C,D26. 线性插值的几何意义是 2分A.过三点做三角形B.两点做一直线C.以一点为中心过另一点做圆D.过三点做抛物线.标准答案:B27. 以计算机中所记录的形状参数与属性参数来表示图形的一种方法叫做 2分A.参数法B.图形C.点阵法D.图像.标准答案:A28. 下列不属于图形输出设备的是 2分C.绘图仪D.扫描仪.标准答案:D29. 4按照所构造的图形对象来分,下列哪项属于规则对象 2分A.山B.水C.平面D.云.标准答案:C30. 5均匀二次B样条曲线各曲线段之间具有阶函数连续性; 2分.标准答案:A31. NURBS曲线表达实现了曲线表达的统一 2分,B样条与解析样条,椭圆与正弦C.同一学科在不同场合的不同称呼而已D.完全不同的学科,两者毫不相干.标准答案:B45. 使用下列二维图形变换矩阵:将产生变换的结果为 2分A.图形放大2倍;B.图形放大2倍,同时沿X、Y坐标轴方向各移动1个绘图单位;C.沿X坐标轴方向各移动2个绘图单位;D.沿X坐标轴方向放大2倍,同时沿X、Y坐标轴方向各平移1个绘图单位;.标准答案:D46. 目前常用的特征表示方法有哪三种 2分A.基于B-rep的表达方法B.基于CSG的表达方法C.基于混合B-rep/CSG的表达方法D.基于主从关系的表达方法.标准答案:A,B,C47. 形位公差所指的是 2分A.形状公差B.位置公差C.平行公差D.垂直公差.标准答案:A,B48. 下列命令中属于编辑命令的有: 2分缩放修剪延伸打断.标准答案:A,B,C,D49. 优化数学模型的三要素是 2分A.设计变量B.设计对象C.约束条件D.目标函数.标准答案:A,C,D50. 平面几何投影可分为两大类,分别是 2分A.透视投影B.正投影C.平行投影D.平面投影.标准答案:A,C51齐次坐标就是把n维向量用维向量表示+1答案:B52STEP标准采用的描述语言是A CB C++C BasicD EXPRESSA AutoCADB Pro/EC UGD CATIA答案:A60三维模型中那种模型可以进行布尔运算A 线框模型B 实心体模型C 表面体模型答案:B61在AutoCAD中,如果0层是当前层,则它不可以被A 关闭和删除B 锁死和关闭C 冻结和锁死D 删除和冻结答案:D62下列关于特征的说法不正确的是A 特征可以表达为:产品特征=形状特征+语义信息B 特征不是体素,是某个或某几个加工表面C 特征是完整的零件D 通过定义简单特征,还可以生成组合特征答案:C63如图所示的模型是A 表面模型B 实体模型C 线框模型D CSG模型答案: C64自由曲线曲面指的是A 直线B 抛物线C NURBS曲线曲面D 直纹面答案: C65B样条曲线采用的是A 显式表示B 隐式表示C 参数形式答案: CC 参数D 混合表达答案:ABC73真实感图形显示在Phong模型基础上,常见的浓淡图绘制算法有A Z-Buffer算法B 扫描线Z-Buffer算法C 画家算法D 区间扫描线算法答案: A,B,D74以下属于现代设计方法的是A 有限元分析B 概率设计C 优化设计D 面向制造的设计答案: A,B,C,D75数据库系统一般由组成;A 硬件B 软件C 数据D 人员答案: A,B,C,D。

权威3DMAX NURBS曲线和曲面教程

权威3DMAX NURBS曲线和曲面教程

权威3DMAX NURBS曲线和曲面教程一、NuRBS曲线作用:可制作圆滑的曲线外形‘Create(创建)‘shape(外形)‘NURBSpoint curve(点曲线)CV curve(控制点曲线):曲线在各控制点连接的多边形内参数:attach(附加):将其它曲线附加到当前曲线中二、NURBS曲面作用:可制作圆滑的面,如汽车外壳,床罩,窗帘丝织物品表面‘create(创建) →‘Geomotry(三维几何体) →‘NurBs surface(NurBs曲面) →‘point surface(点曲面)‘cv surface(控制点曲面)1、point surface(点曲面)参数:u lines:X轴节点数v lines:Y轴节点数次对象:point(点):选择1个顶点(单个):选择一行顶点(单行):选择一列顶点(单列):选择交叉的一行一列顶点(行列):选择所有顶点2、cv suface(控制点曲面)参数:Length cvs:长控制点数Width cvs:宽控制点次对象:与点曲面相同三、NurBs创建工具箱作用:方便创建曲线或者曲面1、Curves(曲线)工具箱第一个():建立cv curve(控制点曲线)第二个():建立Point curve(点曲面)第三个():连接两个顶点,限定在点曲线面类第四个():复制曲线第五个():连接2个顶点,点曲线,CV曲面都可相连第六个():产生曲线的轮廓线第七个():镜像复制曲线3、surface(曲面)工具箱第一个():建立cv surface(控制点曲面)第二个():建立point surface(点曲面)第三个():复制曲面第四个和第九个():将2个曲线连接成面第五个():复制曲面,不能分开第六个():镜向复制曲面第七个():将曲面拉伸成面第八个():将曲线旋转成面3DMAX 第十五讲(材质1)一、材质编辑器作用:赋于物体材质,表现出各种实际效果1、主窗口组成①样本窗②水平工具栏③垂直工具栏④材质名称类型⑤参数展示栏2、样本窗显示方式选择某样本球’→‘5╳3或‘6╳43、垂直工具栏①样本类型:以何种方式显示样本②背光:显示/隐藏样本球暗区光线③背景:检查透明材质效果④重复:检查透明材质效果⑤视频颜色检查:检查材质颜色以适应电视输出⑥材质动画预览⑦选项:设置材质,相关参数⑧按材质选择物体4、水平工具栏(1)获取材质(包括复合标准材质)(2)将冷材质重新赋予场景中的物体(3)将材质赋予场景中被选择的物体(4)清除材质(5)热材质变为冷材质(6)保存材质备以后使用(8)材质效果通道,给材质起编号(9)显示场景中物体的贴图(10)显示最后结果(11)回到父层级(12)到同一层次(13)材质/贴图导航器二、同步材质,异步材质1、同步材质称为热材质,当改变材质参数,场景中的物体材质会同步变化,样本球4个角为白三角形2、异步材质称为冷材质,当改变材质参数,场景中的物体材质不随之变化三、给物体贴图选择物体→(材质编辑器按钮)→选择一个样本球→diffuse(散播颜色) →‘(贴图按钮)→“Bitmap(位图) →选择某图片→‘打开→‘(显示贴图按钮)。

OpenGL编程轻松入门之NURBS曲线和曲面

OpenGL编程轻松入门之NURBS曲线和曲面

OpenGL编程轻松入门之NURBS曲线和曲面2006-05-22 09:53作者:黄燕出处:天极开发责任编辑:方舟上一节讲了一般的曲线与曲面的绘制,本节讲NURBS曲线和曲面的绘制。

例11:此例绘制两个相同形状的NURBS曲面,不同之处是一个为线框式,一个是由实多边形组成。

运行后可以看到其中的区别,如图十三所示。

#include <windows.h>#include <GL/glut.h>GLUnurbsObj *theNurb1;GLUnurbsObj *theNurb2;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}}};//控制点GLfloat mat_diffuse[] = {1.0,0.5,0.1,1.0};GLfloat mat_specular[] = {1.0,1.0,1.0,1.0};GLfloat mat_shininess[] = {100.0};GLfloat light_position[] = {0.0,-10.0,0.0,1.0};void myInit(void){glClearColor(1.0,1.0,1.0,0.0);//设置背景色/*为光照模型指定材质参数*/glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess);glLightfv(GL_FRONT,GL_POSITION,light_position);//设置光源参数glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);//设置光照模型参数/*激活光照*/glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);glDepthFunc(GL_LEQUAL);glEnable(GL_DEPTH_TEST);glEnable(GL_LEQUAL);glEnable(GL_AUTO_NORMAL);glEnable(GL_NORMALIZE);/*设置特殊效果*/glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);glHint(GL_LINE_SMOOTH_HINT,GL_DONT_CARE);glEnable(GL_BLEND);glFrontFace(GL_CW);glShadeModel(GL_SMOOTH);glEnable(GL_LINE_SMOOTH);theNurb1 = gluNewNurbsRenderer();//创建NURBS对象theNurb1 gluNurbsProperty(theNurb1,GLU_SAMPLING_TOLERANCE,25.0); gluNurbsProperty(theNurb1,GLU_DISPLAY_MODE,GLU_OUTLINE_POLYGON);theNurb2 = gluNewNurbsRenderer();//创建NURBS对象theNurb2 gluNurbsProperty(theNurb2,GLU_SAMPLING_TOLERANCE,25.0); gluNurbsProperty(theNurb2,GLU_DISPLAY_MODE,GLU_FILL);}int spin = 0;/*接收键盘指令*/static void myKey(unsigned char key,int x,int y){switch(key){case'd':spin = spin + 1;glRotatef(spin,1.0,1.0,0.0);glutPostRedisplay();break;case 27:exit(0);default:break;}}/*绘制曲面*/void myDisplay(void){GLfloat knots[10] = {0.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0};glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glRotatef(50.0,1.0,1.0,0.0);/*第一个曲面*/glPushMatrix();glTranslatef(1.0,0.0,0.0);gluBeginSurface(theNurb1);/*定义曲面形状*/gluNurbsSurface(theNurb1,10,knots,10,knots,5*3,3,&ctrlpoints[0][0][0],5,5,GL_MAP2_VE RTEX_3);gluEndSurface(theNurb1);glPopMatrix();/*第二个曲面*/glPushMatrix();glTranslatef(7.0,0.0,0.0);gluBeginSurface(theNurb2);/*定义曲面形状*/gluNurbsSurface(theNurb2,10,knots,10,knots,5*3,3,&ctrlpoints[0][0][0],5,5,GL_MAP2_VE RTEX_3);gluEndSurface(theNurb2);glPopMatrix();glutSwapBuffers();}void myReshape(GLsizei w,GLsizei h){glViewport(0,0,w,h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(50.0,(GLfloat)w/(GLfloat)h,1.0,15.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glTranslatef(0.0,0.0,-9.0);}int main(int argc,char ** argv){/*初始化*/glutInit(&argc,argv);glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(600,400);glutInitWindowPosition(200,200);/*创建窗口*/glutCreateWindow("NURBS surface");/*绘制与显示*/myInit();glutKeyboardFunc(myKey);glutReshapeFunc(myReshape);glutDisplayFunc(myDisplay);/*进入GLUT事件处理循环*/glutMainLoop();return(0);}·GLUnurbsObj* glNewNurbsRenderer()创建一个NURBS对象,并返回一个指向该对象的指针。

第五章 曲线曲面(NURBS)的操作

第五章 曲线曲面(NURBS)的操作

三、NURBS创建 1、CV工具的使用。CV(Control Vertex)工具绘制控制点
曲线的方法是,使用Create——CV Curve Tool选项。点 击属性图标对CV工具进行设置。 • (1)、Curve Degree参数定义开始组成的点数和曲线 的平滑程度。如默认的3Cubic表示至少用4个点才能显示 曲线。1Linear表示至少用2个点才能显示曲线。数字越大, 曲线越光滑。 • (2)、Knot Spacing选项的Chord Length项可以使曲 线更加平滑。 • (3)、Multiple End Knots复选框可以定义曲线是否达 到开始点和结束点。 • (4)、创建CV曲线的时候,点击鼠标右键,弹出快捷菜 单,其中Complete Tool表示结束CV曲线工具,Select All工具表示选择整条创建的CV曲线。 2、曲面上创建曲线的方法 • (1)、创建一个场景。 • (2)、创建一个球体。 • (3)、调出球体的右键快捷菜单选择Isoparm项进入对 等线的选择状态。 • (4)、选择一条对等线,使用空格键调处主快捷菜单, 选择Edit Curves——Duplicate Surface Curves选项即 可。
(5)、Output Geomertry:决定输出曲面的类型。
二、拉伸创建NURBS物体
(1)、新建场景 (2)、使用EP Curve工具创建一个规则矩形。 (3)、在Front视图中创建一个路径。 (4)、依次选择多边形和路径,选择Surface——
Extrude选项。点击属性图标调出设置窗口。 (5)、点击Apply按钮完成拉伸操作。 (6)、回到未拉伸状态,设置Rotation的参数。为旋转
二、NURBS组件
• 1、曲线是由控制点(Control Vertex)、编辑点 (Edit Point)、曲线点(Curve Point)、轮廓点 (Hull)组成,可通过右键快捷菜单进行曲线组件的 选择。

曲线数学NURBS之B样条曲线

曲线数学NURBS之B样条曲线

曲线数学NURBS之B样条曲线上一篇博客已经讲到了bezier曲线,本篇接着讲解B样条曲线。

B样条曲线是bezier曲线的更一般化,bezier曲线是B样条曲线的特列。

相比于Bezier曲线,B样条曲线是分段组成的,每一段参数的区间都是[0,1],这就克服了Bezier曲线改变任意一个控制点,曲线上所有的点都要改变的缺点。

B样条曲线的数学公式如下:其中di(i=0,1…n)为控制点,K为规定的基函数的次数,Ni,k(i=0,1…n)即为k次B样条基函数,最高次数为k。

u表示参数序列,即B样条分段函数中的参数。

B样条基函数的公式如下:其中i为节点序号,k是基函数的次数,规定:0/0等于0。

这就是Cox-deBoor算法公式。

节点和控制点是不一样的,满足控制关系m+1=n+k+2.即假如有3个控制点控制的2次B样条曲线,其节点的数量为3+2+2=7.Boehm 给出了节点的插入公式:其中r是新插入的节点t在节点序列中的重复度。

如上图,控制点Pj生成新的控制点Pj’。

B样条曲线总的分为均匀和非均匀的。

根据如上的讲解为了设计一个B-样条曲线,我们需要一系列的控制点,一系列的节点和一系列的系数,每个系数对应一个控制点,所有曲线段连接在一起满足某个连续条件,即为B样条曲线。

有了上边整体的了解,接着从B样条基函数开始讲起,如何根据几个控制点,以及给定的B样条基函数次数k画出B样条曲线。

如上图,基函数的系数定义如图中所述,可以看出,每一个系数范围都为(0,1)区间。

而基函数中的Ni,k(u) 可以表示为如下的杨辉三角形状,比如求第1段区间1次基函数N1,1 就要求出N1,0 和N2,0,其他依次类推。

如下三图为本人从基函数推导出来的B样条曲线。

其中控制点个数为3(n=2),基函数最高次数为2(k=2),则节点总数为m+1=n+k+2=6.推导中,为了便于计算,各个节点赋值分别为0,1,2,3,4,5。

最后得出B样条曲线的每一段的函数表示。

讲 B样条曲线曲面 NURBS曲线曲面PPT课件

讲 B样条曲线曲面 NURBS曲线曲面PPT课件

三次Hermite曲线---弗格森 了解内容
a 0 0 0 11 Pk
C
b
1
c 0
d
3
1 0 2
1 1 1
1
Pk
1
0 0
Rk Rk 1
Mh是Hermite矩阵。
。 Gh是Hermite几何矢量
2 2 1 1 Pk
3
0
1
3 0 0
2 1 0
1
0
0
Pk
1
Rk Rk 1
局部性质。 局变差减小性质。 凸包性。 在仿射与透射变换下的不变性。 在曲线定义域内有与有理基函数同样的可微性。
13
第13页/共33页
NURBS曲线---性质
如果某个权因子为零,那么相应控制顶点对曲线没有影响。

,则当
时,非有理与有理Bezier曲线和非
有理B样条曲线是NURBS曲线的特殊情况
i
P67-68
8
第8页/共33页
NURBS曲线曲面
NURBS方法的主要优点
既为标准解析形状(初等曲线曲面),又为自由型曲线 曲面的精确表示与设计提供了一个公共的数学形式。
修改控制顶点和权因子,为各种形状设计提供了充分 的灵活性。
具有明显的几何解释和强有力的几何配套技术。 对几何变换和投影变换具有不变性。 非有理B样条、有理与非有理Bezier方法是其特例。
7
第7页/共33页
NURBS曲线曲面
B样条曲线、Bezier曲线都不能精确表示出抛物 线外的二次曲线,B样条曲面、Bezier曲面都 不能精确表示出抛物面外的二次曲面,而只能 给出近似表示。
提出NURBS方法,即非均匀有理B样条方法主要 是为了找到与描述自由型曲线曲面的B样条方 法既相统一、又能精确表示二次曲线弧与二次 曲面的数学方法。

第7讲-B样条曲线曲面-NURBS曲线曲面

第7讲-B样条曲线曲面-NURBS曲线曲面

P(u, v)
i0 j0 mn
Pij Ri, p; j,q (u, v)
ij Ni, p (u)N j,q (v) i0 j0
i0 j0
u, v [0,1]
Ri, p; j,q (u, v)
m
ij Ni, p (u)N j,q (v)
n
rs Nr, p (u)Ns,q (v)
r0 s0
19
8
NURBS曲线曲面
B样条曲线、Bezier曲线都不能精确表示出抛物 线外的二次曲线,B样条曲面、Bezier曲面都 不能精确表示出抛物面外的二次曲面,而只能 给出近似表示。
提出NURBS方法,即非均匀有理B样条方法主要 是为了找到与描述自由型曲线曲面的B样条方 法既相统一、又能精确表示二次曲线弧与二次 曲面的数学方法。
n
i Pi Ni,k (t) nP(t) Fra biblioteki0 n
Pi Ri,k (t)
i Ni,k (t) i0
i0
Ri,k (t)
i Ni,k (t)
n
j N j,k (t)
j0
12
NURBS曲线---性质
Ri,k(t)具有k阶B样条基函数类似的性质:
局部支承性:Ri,k(t)=0,t[ti, ti+k]
P67-68
9
NURBS曲线曲面
NURBS方法的主要优点
既为标准解析形状(初等曲线曲面),又为自由型曲线 曲面的精确表示与设计提供了一个公共的数学形式。
修改控制顶点和权因子,为各种形状设计提供了充分 的灵活性。
具有明显的几何解释和强有力的几何配套技术。 对几何变换和投影变换具有不变性。 非有理B样条、有理与非有理Bezier方法是其特例。

PPT2-NURBS原理

PPT2-NURBS原理
锐角点并非一种特殊类型点,而是由于以下两种状况的存在而消逝锐角: 一、当曲线内部消逝复节点时,会导致曲线上产生锐角点。 二、锐角点本身就是一个焊接点〔Seam Point〕,由于此点是同时属于两 条直线的起始点或终点,因此导致锐角的消逝。
NURBS圆中曲线对象增加 〔 〔InsertKnot〕〕或者移除一个节点 〔 〔RemoveKnot〕〕,但无法对节点 进展直接操作,可以通过插入锐角点 命令在曲线内插入一个全复节点,并 可炸开成为两条曲线。
通常我们使用 〔Curve〕以CV点建立曲线工具得到的曲线会是均匀曲线,而使用 〔InterpCrv〕以内插点建立曲线工具得到的是不均匀的曲线〔但可以设置子参数让 其变为均匀〕。
节点矢量在消逝重复的地方称为复节点-“MutilKnot”,重复数等于阶数的 节点赋值又称为全复节点〔Full-MultKnot〕。 NURBS一根曲线的节点赋值以全复节点开头,其中间全为单节点,最终以全 复节点完毕,而且节点值呈等差,那么这根NURBS曲线即为 “均匀〔Uniform 〕”的。对于3阶6个把握点的NURBS曲线而言 {0,0,0,1,2,3,3,3}节点赋值即是一 个均匀〔Uniform〕的节点赋值。反之,曲线则为不均匀。〔Non- Uniform〕 的
Grasshopper插件中供给了一个工具-“Knots Vector”可以得到任意阶数和把 握点数量状况下均匀的节点矢量赋值。
复节点假设是消逝在NURBS曲线内部,会导致降低曲线的连续性。重复一次,该 处的连续性降低1,例如3阶曲线内部具有G2连续性,假设是在内部消逝一个全复 节点,也就是节点赋值重复两次,那么在此点处将只具有G0的连续性,消逝一个 Kink锐角点。
在Rhinoceros中建模,理解NURBS的内在原理是建立良好模型的根底,在Rhinoceros中, 有四个根本元素来定义一根NURBS曲线:阶〔Degree〕、把握点〔Control Points〕、 节点〔Knots〕和评定规章〔Evaluation Rule〕,下面将协作使用Rhinoceros中的几何元 素和分析工具来分别争论这些定义。

无序B样条曲线的曲面拟合算法

无序B样条曲线的曲面拟合算法

无序B样条曲线的曲面拟合算法1.引言-简要介绍无序B样条曲线-论述无序B样条曲线的曲面拟合问题-描述研究的主要问题和目标2. 相关研究-介绍曲面拟合算法的发展历程-论述其他曲面拟合算法的优缺点-简单介绍无序B样条曲线拟合算法的前置知识3.算法设计-描述无序B样条曲线的定义和性质-详细阐述无序B样条曲线的曲面拟合算法-主要包括控制点的选择、权重函数的设计和优化策略的实现4.实验与结果-利用自己实现的算法,对高维数据集进行实验-对比不同算法的效果,分析无序B样条曲线曲面拟合算法的优点和局限性-通过实例来展示算法的应用5.结论和展望-对论文进行总结,强调无序B样条曲线曲面拟合算法在实际应用中的重要性-提出进一步研究无序B样条曲线算法的方向和可能的改进方案第一章:引言无序B样条曲线是一种广泛应用于计算机图形学和计算几何领域中的数学工具。

与传统Bezier曲线相比,B样条曲线的控制点可以增删、移动,具有更强的灵活性和变形能力。

因此,B样条曲线被广泛应用于CAD设计、工程制图、物理仿真等领域。

曲面拟合是B样条曲线的一个重要应用,也是本文研究的主题。

曲面拟合的目标是根据给定的数据点集,构建一个能够尽可能地代表原始数据点的曲面模型。

通常,数据点集是从真实物体的点云数据中获得的,因此它们往往是不规则、噪声较大的。

曲面拟合算法的目标是以尽可能少的控制点构建合适的曲面模型,以逼近给定的点云数据。

B样条曲线的曲面拟合算法也分为有序B样条曲线拟合和无序B样条曲线拟合两种。

有序B样条曲线是指曲线上的控制点以固定顺序连接,控制点的顺序和其位置决定了曲线的形状和拟合精度。

而无序B样条曲线对控制点的顺序和位置没有限制,因此拟合出的曲线可以更好地与原始点云数据相匹配。

本文主要研究无序B样条曲线的曲面拟合算法,旨在解决无序B样条曲线拟合算法复杂性高、精度难以控制等问题,提升曲面拟合的效率和精度。

本论文内容包括5个章节。

第一章是引言,对无序B样条曲线的曲面拟合做了简要介绍。

曲线_nurbs_B样条曲线定义2

曲线_nurbs_B样条曲线定义2

B样条曲线是什么?小弟在很多cad的文章中看到B样条曲线,就是不知道到底什么是B样条曲线,希望各位大哥能给小弟一个明确的解释。

谢谢!2003-4-15 22:00 intaNURBS -- Non-Uniform Rational B-Splines中文大致叫“非均匀有理B样条”NURBS是一种描述曲面的 "参数表示法"。

基本上所有的曲面都可以用 polygon,也就是所谓的 "面" 来趋近表现,但绝大部份的东西其实都是平滑的,所以必须用代数式或参数式来表示。

NURBS 即是现在最流形的参数示表式法。

NURBS 基本上是用一组 "control point array" 来表示一个曲面,也就是说只要只定一组 control point 就可以造出一个曲面,而只要调整control point 就可以控制此曲面的形状。

用 NURBS 来拉塑的模型,只要改变其控制点的参数值,即能轻易的改变它的外型,此外,NURBS 只需要几条类似物体剖面的线段或是封闭曲线,即可拉塑出复杂的模型,比如在做人脸或是动物时就十分方便; 此外,因其很容易 Modify,所以在工业设计上也逐渐成为主流。

要特别强调的,Non-Uniform Rational B-Splines 其中的B并不是Bezier Curve,其定义比Bezier Curve还多出一关联项,所以不要把它跟Bezier Curve弄混。

在CAD/CAM中,常采用Bezier曲线曲面,这样便于理解曲线/曲面。

但采用Bezier形式的曲线曲面不能精确的表示二次曲线和二次曲面,如球体和圆。

将多项式改为有理形式,不仅能精确表示二次曲线和二次曲面,且增加了设计的自由度。

重复的进行两点线性插值,可以构造Bezier Curve。

重复的进行两点有理插值,可以构造有理Bezier Curve。

与控制顶点类似,有理Bezter曲线上的点可映射为Bezter曲线上的点或对应的控制多边形上的点。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

学习小结:前面学习了Bezier 曲线,B 样条基函数和B 样条曲线的一些基础知识。

掌握关键问题是一条B 样条曲线间的多段曲线的光滑连接。

因为现在是用多段Bezier 曲线来描绘一条B 样条曲线,所以问题变为两段Bezier 曲线间光滑连接。

两段Bezier 曲线段(3次)B1和B2光滑连接的条件:(1).要求B1和B2有共同的连接点,即G 0连续。

(2).要求B1和B2在连接点处有成比例的一阶导数,即G 1连续。

由端点处的一阶导数)(3)0(2),(3)1(10123Q Q B P P B -='-=',为实现G 1连续,则有:)1(1)0(2B B '=' 即:2301P P Q Q -=- 这也表明,1032),(,Q Q P P 三点共线。

如下图表示了一条3次B 样条曲线的所有控制多边形: 1) P 2 P 3P 4 (P 1112)P 5 P 10 0 P 6 P 9 7 P 8 图5.3次B 样条曲线和所有控制多边形图5中,P0至P6为原始3次B 样条曲线控制多边形顶点,P 0至P 12是计算后最终形成B样条曲线控制多边形顶点。

图6.双二次(2x2)B 样条曲面6.B 样条曲线曲面和NURBS 曲线曲面的C 语言实现算法源程序#ifndef _mynurbs_h#ifndef _MYNURBS_H#include "gl\gl.h"#include "math.h"//*-*-*-*-*-*-*-*-*-*-*-*-*-*-* B样条基函数计算部分 *-*-*-*-*-*-*-*-*-*-*-*-*-* //确定参数u所在的节点区间下标//n=m-p-1//m为节点矢量U[]的最大下标//p为B样条函数次数int FindSource(int n,int p,float u,float U[]){int low,high,mid;if(u==U[n+1])//特殊情况return n;//进行二分搜索low=p;high=n+1;mid=(int)(low+high)/2;while(u<U[mid]||u>U[mid]){if(u<U[mid])high=mid;elselow=mid;mid=(int)(low+high)/2;if(u>=U[mid]&&u<U[mid+1])//找到u所在的节点区间的下标break; //退出二分搜索}return mid; //返回区间下标}//计算所有非零B样条基函数并返回其值//i为参数u所在的节点区间下标void BasisFunction(int i,int p,float u,float U[],float N[]){int j,di,dp,k;float tul,tur,left,right;float tmpN[50][50];for(k=0;k<=p;k++){dp=0;for(di=i+p-k;di>=i-k;di--){if(u>=U[di]&&u<U[di+1])tmpN[di][0]=1;elsetmpN[di][0]=0;dp+=1;for(j=1;j<dp;j++){tul=U[di+j]-U[di];tur=U[di+j+1]-U[di+1];if(tul!=0)left=(u-U[di])/tul;elseleft=0;if(tur!=0)right=(U[di+j+1]-u)/tur;elseright=0;tmpN[di][j]=left*tmpN[di][j-1]+right*tmpN[di+1][j-1];}}N[i-k]=tmpN[i-k][p];}}//----------------------------------------------------------------------- //计算基函数的1阶导数并保存在NP[]中//i为参数u所在的节点区间下标//p为B样条函数次数P>2void DerBasisFunc(int i,int p,float u,float U[],float NP[]){int j,di,dp,k;float tul,tur,left,right,saved,dl,dr;float tmpN[50][50];for(k=0;k<=p;k++){dp=0;for(di=i+p-k;di>=i-k;di--){if(u>=U[di]&&u<U[di+1])tmpN[di][0]=1;elsetmpN[di][0]=0;dp+=1;for(j=1;j<dp;j++){tul=U[di+j]-U[di];tur=U[di+j+1]-U[di+1];if(tul!=0)left=(u-U[di])/tul,dl=1/tul;elseleft=0,dl=0;if(tur!=0)right=(U[di+j+1]-u)/tur,dr=1/tur;elseright=0,dr=0;tmpN[di][j]=(left*tmpN[di][j-1]+right*tmpN[di+1][j-1]);saved=p*(dl*tmpN[di][j-1]-dr*tmpN[di+1][j-1])/(p+p-1);}}NP[i-k]=saved;}}//*-*-*-*-*-*-*-*-*-*-*-*-*-* Bezier曲线曲面部分*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*//计算参数u的p次基函数值并存在BC[]中void BernsteinFunc(int p,double t,float BC[]){for(int i=0;i<=p;i++){if(i==0)BC[0]=(float)pow(1-t,p);if(i==p)BC[p]=(float)pow(t,p);if(i>0&&i<p)BC[i]=p*(float)pow(t,i)*(float)pow(1-t,p-i);}}//获取p次Bezier曲线上的lines个点的值void BezierPoint(int p,float px[],float py[],float pz[],int lines,float tmp[][3]) {float BC[20];int i,j;for(j=0;j<=lines;j++){double t=j/(float)lines;BernsteinFunc(p,t,BC);tmp[j][0]=tmp[j][1]=tmp[j][2]=0;for(i=0;i<p+1;i++){tmp[j][0]+=BC[i]*px[i];tmp[j][1]+=BC[i]*py[i];tmp[j][2]+=BC[i]*pz[i];}}}//获取p次有理Bezier曲线上的lines个点的值void NBezierPoint(int p,float px[],float py[],float pz[],float pw[],int lines,float tmp[][4]){float x,y,z,w,BC[20];int i,j;for(j=0;j<=lines;j++){double t=j/(float)lines;BernsteinFunc(p,t,BC);x=y=z=w=0;for(i=0;i<p+1;i++){x+=BC[i]*px[i]*pw[i];y+=BC[i]*py[i]*pw[i];z+=BC[i]*pz[i]*pw[i];w+=BC[i]*pw[i];}tmp[j][0]=x/w;tmp[j][1]=y/w;tmp[j][2]=z/w;tmp[j][3]=w;}}//-----------------------------------------------------------------------------------//绘制p次的Bezier曲线void Bezier(int p,float px[],float py[],float pz[],int lines){float pt[100][3];int j;BezierPoint(p,px,py,pz,lines,pt);for(j=1;j<=lines;j++){glBegin(GL_LINES);glVertex3f(pt[j-1][0],pt[j-1][1],pt[j-1][2]);glVertex3f(pt[j][0],pt[j][1],pt[j][2]);glEnd();}}//------------------------------------------------------------------------------//绘制p次的有理Bezier曲线void NBezier(int p,float px[],float py[],float pz[],float w[],int lines){float pt[100][4];int j;NBezierPoint(p,px,py,pz,w,lines,pt);for(j=1;j<=lines;j++){glBegin(GL_LINES);glVertex3f(pt[j-1][0],pt[j-1][1],pt[j-1][2]);glVertex3f(pt[j][0],pt[j][1],pt[j][2]);glEnd();}}//---------------------------------------------------------------------------------//计算双p次Bezier曲面上所有的点并保存在Pt[][][]中//u和v分别为曲面(u,v)方向上的网格数void BezierFacePoint(int p,int u,int v,float px[][4],float py[][4],float pz[][4],float pt[161][161][3]){float urx[11][161],ury[11][161],urz[11][161];float tx[11],ty[11],tz[11],tmp[161][3];int i,j,k;for(j=0;j<p+1;j++){for(i=0;i<p+1;i++){tx[i]=px[i][j];ty[i]=py[i][j];tz[i]=pz[i][j];}BezierPoint(p,tx,ty,tz,v,tmp);for(k=0;k<=v;k++){urx[j][k]=tmp[k][0];ury[j][k]=tmp[k][1];urz[j][k]=tmp[k][2];}}for(i=0;i<=v;i++){for(k=0;k<p+1;k++){tx[k]=urx[k][i];ty[k]=ury[k][i];tz[k]=urz[k][i];}BezierPoint(p,tx,ty,tz,u,tmp);for(j=0;j<=u;j++){pt[i][j][0]=tmp[j][0];pt[i][j][1]=tmp[j][1];pt[i][j][2]=tmp[j][2];}}}//--------------------------------------------------------------------------------//计算双p次有理Bezier曲面上所有的点并保存在Pt[][][]中//u和v分别为曲面(u,v)方向上的网格数void NuBezierFacePoint(int p,int u,int v,float px[][4],float py[][4],float pz[][4],float w[][4],float pt[161][161][3]){float urx[11][161],ury[11][161],urz[11][161],urw[11][161];float tx[11],ty[11],tz[11],tw[11],tmp[161][4];int i,j,k;for(j=0;j<p+1;j++){for(i=0;i<p+1;i++){tx[i]=px[i][j];ty[i]=py[i][j];tz[i]=pz[i][j];tw[i]=w[i][j];}NBezierPoint(p,tx,ty,tz,tw,v,tmp);for(k=0;k<=v;k++){urx[j][k]=tmp[k][0];ury[j][k]=tmp[k][1];urz[j][k]=tmp[k][2];urw[j][k]=tmp[k][3];}}for(i=0;i<=v;i++){for(k=0;k<p+1;k++){tx[k]=urx[k][i];ty[k]=ury[k][i];tz[k]=urz[k][i];tw[k]=urw[k][i];}NBezierPoint(p,tx,ty,tz,tw,u,tmp);for(j=0;j<=u;j++){pt[i][j][0]=tmp[j][0];pt[i][j][1]=tmp[j][1];pt[i][j][2]=tmp[j][2];}}}//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* B样条曲线曲面部分-*-*-*-*-*-*-*-*-*-*-*-*-*-*-//计算样条曲线的1阶导矢(u所对应的所有点)保存在Der[]中//n=m-p-1//p为曲线的次数void BSplineDer(int n,int p,float U[],float P[],float Der[]){float N[100],tmp;int i,j;for(i=p+1;i<=n;i++){DerBasisFunc(i,p,U[i],U,N);tmp=0;for(j=i;j>=i-p;j--)tmp+=N[j]*P[j];Der[i-p]=tmp;}}//计算曲线上的点(u所对应的所有点)保存在Poi[]中//n=m-p-1//p为曲线的次数void BSplinePoint(int n,int p,float U[],float P[],float Poi[]) {float N[100],tmp;int i,j;for(i=p+1;i<=n;i++){BasisFunction(i,p,U[i],U,N);tmp=0;for(j=i;j>=i-p;j--)tmp+=N[j]*P[j];Poi[i-p]=tmp;}}//计算3次样条曲线上的所有控制多边形保存在CP[]中//m为节点矢量U[]的最大下标void B3SplineControlPoint(int m,float U[],float P[],float CP[]) {int n,k,i,cp,p;float Poi[100],Der[100],add;p=3;n=m-p-1;BSplinePoint(n,p,U,P,Poi);BSplineDer(n,p,U,P,Der);cp=(n-p)*3+p;for(i=0;i<2;i++){CP[i]=P[i];CP[cp-i]=P[n-i];}for(i=3;i<cp-1;i+=3){k=(int)i/3;add=Der[k]/p;CP[i]=Poi[k];CP[i-1]=CP[i]-add;CP[i+1]=CP[i]+add;}}//计算2次样条曲线上的所有控制多边形保存在CP[]中//m为节点矢量U[]的最大下标void B2SplineControlPoint(int m,float U[],float P[],float CP[]) {int n,k,tm,i,cp,p;float Poi[100];p=2;n=m-p-1;BSplinePoint(n,p,U,P,Poi);cp=(n-p)*2+p;for(i=0;i<2;i++)CP[i]=P[i];CP[cp]=P[n];tm=2;for(i=2;i<cp-1;i+=2){k=(int)i/2;CP[i]=Poi[k];CP[i+1]=P[tm];tm++;}}//绘制3次B样条曲线//m为节点矢量U[]的最大下标void BSpline3L(int m,float U[],float px[],float py[],float pz[]) {float pcx[100],pcy[100],pcz[100],drx[4],dry[4],drz[4];int i,j,tmcp;B3SplineControlPoint(m,U,px,pcx);B3SplineControlPoint(m,U,py,pcy);B3SplineControlPoint(m,U,pz,pcz);/*glColor3f(0.0f,0.0f,0.0f);for(i=1;i<3*m-17;i++){glBegin(GL_LINES);glVertex3f(pcx[i-1],pcy[i-1],pcz[i-1]);glVertex3f(pcx[i],pcy[i],pcz[i]);glEnd();}glColor3f(1.0f,0.0f,0.0f);*/tmcp=m-7;for(i=0;i<=tmcp;i++){for(j=i*3;j<i*3+4;j++){drx[j-i*3]=pcx[j];dry[j-i*3]=pcy[j];drz[j-i*3]=pcz[j];}Bezier(3,drx,dry,drz,20);}}//绘制2次B样条曲线//m为节点矢量U[]的最大下标void BSpline2L(int m,float U[],float px[],float py[],float pz[]){float pcx[100],pcy[100],pcz[100],drx[3],dry[3],drz[3];int i,j,tmcp;B2SplineControlPoint(m,U,px,pcx);B2SplineControlPoint(m,U,py,pcy);B2SplineControlPoint(m,U,pz,pcz);tmcp=m-5;for(i=0;i<=tmcp;i++){for(j=i*2;j<i*2+3;j++){drx[j-i*2]=pcx[j];dry[j-i*2]=pcy[j];drz[j-i*2]=pcz[j];}Bezier(2,drx,dry,drz,20);}}//计算双三次(3x3)B样条曲面所有控制多边形顶点,并保存在pt[][][]中//mu,mv分别为节点矢量U[],V[]的最大下标值void BS3FaceControlPoint(int mu,float U[],int mv,float V[],float px[],float py[],float pz[],float pt[100][100][3]){int i,j,k,dp;float tmx[50],tmy[50],tmz[50];float tmpx[50][100],tmpy[50][100],tmpz[50][100];float uvx[100][100],uvy[100][100],uvz[100][100];for(i=0;i<mv-3;i++){dp=i*(mu-3);for(j=dp;j<mu-3+dp;j++){tmx[j-dp]=px[j];tmy[j-dp]=py[j];tmz[j-dp]=pz[j];}B3SplineControlPoint(mu,U,tmx,tmpx[i]);B3SplineControlPoint(mu,U,tmy,tmpy[i]);B3SplineControlPoint(mu,U,tmz,tmpz[i]);}for(i=0;i<3*mu-17;i++){for(j=0;j<mv-3;j++){tmx[j]=tmpx[j][i];tmy[j]=tmpy[j][i];tmz[j]=tmpz[j][i];}B3SplineControlPoint(mv,V,tmx,uvx[i]);B3SplineControlPoint(mv,V,tmy,uvy[i]);B3SplineControlPoint(mv,V,tmz,uvz[i]);for(k=0;k<3*mv-17;k++){pt[i][k][0]=uvx[i][k];pt[i][k][1]=uvy[i][k];pt[i][k][2]=uvz[i][k];}}}//计算双二次(2x2)B样条曲面所有控制多边形顶点,并保存在pt[][][]中//mu,mv分别为节点矢量U[],V[]的最大下标值void BS2FaceControlPoint(int mu,float U[],int mv,float V[],float px[],float py[],float pz[],float pt[100][100][3]){int i,j,k,dp;float tmx[50],tmy[50],tmz[50];float tmpx[50][100],tmpy[50][100],tmpz[50][100];float uvx[100][100],uvy[100][100],uvz[100][100];for(i=0;i<mv-2;i++){dp=i*(mu-2);for(j=dp;j<mu-2+dp;j++){tmx[j-dp]=px[j];tmy[j-dp]=py[j];tmz[j-dp]=pz[j];}B2SplineControlPoint(mu,U,tmx,tmpx[i]);B2SplineControlPoint(mu,U,tmy,tmpy[i]);B2SplineControlPoint(mu,U,tmz,tmpz[i]);}for(i=0;i<2*mu-7;i++){for(j=0;j<mv-2;j++){tmx[j]=tmpx[j][i];tmy[j]=tmpy[j][i];tmz[j]=tmpz[j][i];}B2SplineControlPoint(mv,V,tmx,uvx[i]);B2SplineControlPoint(mv,V,tmy,uvy[i]);B2SplineControlPoint(mv,V,tmz,uvz[i]);for(k=0;k<2*mv-7;k++){pt[i][k][0]=uvx[i][k];pt[i][k][1]=uvy[i][k];pt[i][k][2]=uvz[i][k];}}}//-------------------------------------------------------------------------------//设置网格数void SetGridCount(int dt,int tu,int tmk[]){int i,tm;tm=tu%dt;for(i=0;i<dt-1;i++)tmk[i]=(tu-tm)/dt;tmk[dt-1]=tmk[0]+tm;}//------------------------------------------------------------------------------//计算双三次(3x3次)或双二次(2x2次)B样条曲面上所有的点并保存在bs[][][]中//nu,mv分别为节点矢量U[],V[]的最大下标//uk,vk分别为B样条曲面(u,v)方向上的网格数//p为曲面的次数void BSplineFace(int p,int nu,float U[],int uk,int mv,float V[],int vk,float px[],float py[],float pz[],float bs[161][161][3]) {int udk[20],vdk[20],i,j,k,l,hu,sv,du,dv;float tp[100][100][3],td[161][161][3];float tmx[4][4],tmy[4][4],tmz[4][4];du=nu-2*p;dv=mv-2*p;SetGridCount(du,uk,udk);SetGridCount(dv,vk,vdk);if(p==3)BS3FaceControlPoint(nu,U,mv,V,px,py,pz,tp);if(p==2)BS2FaceControlPoint(nu,U,mv,V,px,py,pz,tp);for(i=0;i<dv;i++){for(k=0;k<du;k++){for(j=i*p;j<p+1+i*p;j++)for(l=k*p;l<p+1+k*p;l++){tmx[j-i*p][l-k*p]=tp[l][j][0];tmy[j-i*p][l-k*p]=tp[l][j][1];tmz[j-i*p][l-k*p]=tp[l][j][2];}BezierFacePoint(p,udk[k],vdk[i],tmx,tmy,tmz,td);for(sv=i*vdk[0];sv<=vdk[i]+i*vdk[0];sv++)for(hu=k*udk[0];hu<=udk[k]+k*udk[0];hu++){bs[sv][hu][0]=td[sv-i*vdk[0]][hu-k*udk[0]][0];bs[sv][hu][1]=td[sv-i*vdk[0]][hu-k*udk[0]][1];bs[sv][hu][2]=td[sv-i*vdk[0]][hu-k*udk[0]][2];}}}}//-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* Nurbs 样条曲线曲面部分-*-*-*-*-*-*-*-*-*-*-*-*-*-*-//计算Nurbs曲线上的点(u所对应的所有点)保存在Poi[]中//n=m-p-1//p为曲线的次数void NurbsPoint(int n,int p,float U[],float P[],float W[],float Poi[]) {float N[100],tmp,tmw;int i,j;for(i=p+1;i<=n;i++){BasisFunction(i,p,U[i],U,N);tmp=0;tmw=0;for(j=i;j>=i-p;j--){tmp+=N[j]*P[j]*W[j];tmw+=N[j]*W[j];}Poi[i-p]=tmp/tmw;}}//计算Nurbs曲线的1阶导矢(u所对应的所有点)保存在Der[]中//n=m-p-1//p为曲线的次数void NurbsDer(int n,int p,float U[],float P[],float W[],float Der[]) {float N[100],CP[100],NW[100],tmp,tw;int i,j;NurbsPoint(n,p,U,P,W,CP);BSplinePoint(n,p,U,W,NW);for(i=p+1;i<=n;i++){DerBasisFunc(i,p,U[i],U,N);tmp=0;tw=0;for(j=i;j>=i-p;j--){tmp+=N[j]*P[j]*W[j];tw+=N[j]*W[j];}Der[i-p]=(tmp-tw*CP[i-p])/NW[i-p];}}//计算3次Nurbs曲线上的所有控制多边形保存在CP[]中//m为节点矢量U[]的最大下标void Nurbs3ControlPoint(int m,float U[],float P[],float W[],float CP[]) {int n,k,i,cp,p;float Poi[100],Der[100],add;p=3;n=m-p-1;NurbsPoint(n,p,U,P,W,Poi);NurbsDer(n,p,U,P,W,Der);cp=(n-p)*3+p;for(i=0;i<2;i++){CP[i]=P[i];CP[cp-i]=P[n-i];}for(i=3;i<cp-1;i+=3){k=(int)i/3;add=Der[k]/p;CP[i]=Poi[k];CP[i-1]=CP[i]-add;CP[i+1]=CP[i]+add;}}//计算2次Nurbs曲线上的所有控制多边形保存在CP[]中//m为节点矢量U[]的最大下标void Nurbs2ControlPoint(int m,float U[],float P[],float W[],float CP[]) {int n,k,tm,i,cp,p;float Poi[100];p=2;n=m-p-1;NurbsPoint(n,p,U,P,W,Poi);cp=(n-p)*2+p;for(i=0;i<2;i++)CP[i]=P[i];CP[cp]=P[n];tm=2;for(i=2;i<cp-1;i+=2){k=(int)i/2;CP[i]=Poi[k];CP[i+1]=P[tm];tm++;}}//绘制3次Nurbs样条曲线//m为节点矢量U[]的最大下标void Nurbs3L(int m,float U[],float px[],float py[],float pz[],float W[]) {float pcx[100],pcy[100],pcz[100],drx[4],dry[4],drz[4];float pcw[100],drw[4];int i,j,tmcp;Nurbs3ControlPoint(m,U,px,W,pcx);Nurbs3ControlPoint(m,U,py,W,pcy);Nurbs3ControlPoint(m,U,pz,W,pcz);B3SplineControlPoint(m,U,W,pcw);tmcp=m-7;for(i=0;i<=tmcp;i++){for(j=i*3;j<i*3+4;j++){drx[j-i*3]=pcx[j];dry[j-i*3]=pcy[j];drz[j-i*3]=pcz[j];drw[j-i*3]=pcw[j];}NBezier(3,drx,dry,drz,drw,20);}}//绘制2次Nurbs样条曲线//m为节点矢量U[]的最大下标void Nurbs2L(int m,float U[],float px[],float py[],float pz[],float W[]) {float pcx[100],pcy[100],pcz[100],drx[3],dry[3],drz[3];float pcw[100],drw[3];int i,j,tmcp;Nurbs2ControlPoint(m,U,px,W,pcx);Nurbs2ControlPoint(m,U,py,W,pcy);Nurbs2ControlPoint(m,U,pz,W,pcz);B2SplineControlPoint(m,U,W,pcw);tmcp=m-5;for(i=0;i<=tmcp;i++){for(j=i*2;j<i*2+3;j++){drx[j-i*2]=pcx[j];dry[j-i*2]=pcy[j];drz[j-i*2]=pcz[j];drw[j-i*2]=pcw[j];}NBezier(2,drx,dry,drz,drw,20);}}//计算双三次(3x3)Nurbs样条曲面所有控制多边形顶点,并保存在pt[][][]中//mu,mv分别为节点矢量U[],V[]的最大下标值void Nurbs3FControlPoint(int mu,float U[],int mv,float V[],float px[],float py[],float pz[],float W[],float pt[100][100][4]){int i,j,k,dp;float tmx[50],tmy[50],tmz[50],tmw[50];float tmpx[50][100],tmpy[50][100],tmpz[50][100],tmpw[50][100];float uvx[100][100],uvy[100][100],uvz[100][100],uvw[100][100];for(i=0;i<mv-3;i++){dp=i*(mu-3);for(j=dp;j<mu-3+dp;j++){tmx[j-dp]=px[j];tmy[j-dp]=py[j];tmz[j-dp]=pz[j];tmw[j-dp]=W[j];}Nurbs3ControlPoint(mu,U,tmx,tmw,tmpx[i]);Nurbs3ControlPoint(mu,U,tmy,tmw,tmpy[i]);Nurbs3ControlPoint(mu,U,tmz,tmw,tmpz[i]);B3SplineControlPoint(mu,U,tmw,tmpw[i]);}for(i=0;i<3*mu-17;i++){for(j=0;j<mv-3;j++){tmx[j]=tmpx[j][i];tmy[j]=tmpy[j][i];tmz[j]=tmpz[j][i];tmw[j]=tmpw[j][i];}Nurbs3ControlPoint(mv,V,tmx,tmw,uvx[i]);Nurbs3ControlPoint(mv,V,tmy,tmw,uvy[i]);Nurbs3ControlPoint(mv,V,tmz,tmw,uvz[i]);B3SplineControlPoint(mv,V,tmw,uvw[i]);for(k=0;k<3*mv-17;k++){pt[i][k][0]=uvx[i][k];pt[i][k][1]=uvy[i][k];pt[i][k][2]=uvz[i][k];pt[i][k][3]=uvw[i][k];}}}//计算双二次(2x2)Nurbs样条曲面所有控制多边形顶点,并保存在pt[][][]中//mu,mv分别为节点矢量U[],V[]的最大下标值void Nurbs2FControlPoint(int mu,float U[],int mv,float V[],float px[],float py[],float pz[],float W[],float pt[100][100][4]){int i,j,k,dp;float tmx[50],tmy[50],tmz[50],tmw[50];float tmpx[50][100],tmpy[50][100],tmpz[50][100],tmpw[50][100];float uvx[100][100],uvy[100][100],uvz[100][100],uvw[100][100];for(i=0;i<mv-2;i++){dp=i*(mu-2);for(j=dp;j<mu-2+dp;j++){tmx[j-dp]=px[j];tmy[j-dp]=py[j];tmz[j-dp]=pz[j];tmw[j-dp]=W[j];}Nurbs2ControlPoint(mu,U,tmx,tmw,tmpx[i]);Nurbs2ControlPoint(mu,U,tmy,tmw,tmpy[i]);Nurbs2ControlPoint(mu,U,tmz,tmw,tmpz[i]);B2SplineControlPoint(mu,U,tmw,tmpw[i]);}for(i=0;i<2*mu-7;i++){for(j=0;j<mv-2;j++){tmx[j]=tmpx[j][i];tmy[j]=tmpy[j][i];tmz[j]=tmpz[j][i];tmw[j]=tmpw[j][i];}Nurbs2ControlPoint(mv,V,tmx,tmw,uvx[i]);Nurbs2ControlPoint(mv,V,tmy,tmw,uvy[i]);Nurbs2ControlPoint(mv,V,tmz,tmw,uvz[i]);B2SplineControlPoint(mv,V,tmw,uvw[i]);for(k=0;k<2*mv-7;k++){pt[i][k][0]=uvx[i][k];pt[i][k][1]=uvy[i][k];pt[i][k][2]=uvz[i][k];pt[i][k][3]=uvw[i][k];}}}//------------------------------------------------------------------------------//计算双三次(3x3次)或双二次(2x2次)Nurbs样条曲面上所有的点并保存在bs[][][]中//nu,mv分别为节点矢量U[],V[]的最大下标//uk,vk分别为B样条曲面(u,v)方向上的网格数//p为曲面的次数void NurbsFace(int p,int nu,float U[],int uk,int mv,float V[],int vk,float px[],float py[],float pz[],float w[],float bs[161][161][3]){int udk[20],vdk[20],i,j,k,l,hu,sv,du,dv;float tp[100][100][4],td[161][161][3];float tmx[4][4],tmy[4][4],tmz[4][4],tmw[4][4];du=nu-2*p;dv=mv-2*p;SetGridCount(du,uk,udk);SetGridCount(dv,vk,vdk);if(p==3)Nurbs3FControlPoint(nu,U,mv,V,px,py,pz,w,tp);if(p==2)Nurbs2FControlPoint(nu,U,mv,V,px,py,pz,w,tp);for(i=0;i<dv;i++){for(k=0;k<du;k++){for(j=i*p;j<p+1+i*p;j++)for(l=k*p;l<p+1+k*p;l++){tmx[j-i*p][l-k*p]=tp[l][j][0];tmy[j-i*p][l-k*p]=tp[l][j][1];tmz[j-i*p][l-k*p]=tp[l][j][2];tmw[j-i*p][l-k*p]=tp[l][j][3];}NuBezierFacePoint(p,udk[k],vdk[i],tmx,tmy,tmz,tmw,td);for(sv=i*vdk[0];sv<=vdk[i]+i*vdk[0];sv++)for(hu=k*udk[0];hu<=udk[k]+k*udk[0];hu++){bs[sv][hu][0]=td[sv-i*vdk[0]][hu-k*udk[0]][0];bs[sv][hu][1]=td[sv-i*vdk[0]][hu-k*udk[0]][1];bs[sv][hu][2]=td[sv-i*vdk[0]][hu-k*udk[0]][2];}}}}//*-*-*-*-*-*-*-*-*-*-*-*-*-*-* 绘制曲面部分*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*//计算多边形的外法线返回值tmN[]void getN(float x[3],float y[3],float z[3],float tmN[3]){float p1,p2,p3,q1,q2,q3;float nx,ny,nz;p1=x[1]-x[0];p2=y[1]-y[0];p3=z[1]-z[0];q1=x[2]-x[1];q2=y[2]-y[1];q3=z[2]-z[1];nx=p2*q3-q2*p3;ny=q1*p3-p1*q3;nz=p1*q2-p2*q1;tmN[0]=nx;tmN[1]=ny;tmN[2]=nz;}//-----------------------------------------------------------------------------------//显示B样条曲面//fill取值为0或1void ShowSurface(int u,int v,float bs[161][161][3],int fill){int i,j;float x[3],y[3],z[3],tmn[3];for(i=0;i<=v;i++)for(j=0;j<=u;j++){if(fill!=0){x[0]=bs[i][j][0];x[1]=bs[i+1][j][0];x[2]=bs[i+1][j+1][0];y[0]=bs[i][j][1];y[1]=bs[i+1][j][1];y[2]=bs[i+1][j+1][1];z[0]=bs[i][j][2];z[1]=bs[i+1][j][2];z[2]=bs[i+1][j+1][2];getN(x,y,z,tmn);glEnable(GL_NORMALIZE);glBegin(GL_QUADS);glNormal3f(tmn[0],tmn[1],tmn[2]);if(j<u){glVertex3f(bs[i][j][0],bs[i][j][1],bs[i][j][2]);glVertex3f(bs[i][j+1][0],bs[i][j+1][1],bs[i][j+1][2]);}if(i<v){glVertex3f(bs[i+1][j+1][0],bs[i+1][j+1][1],bs[i+1][j+1][2]);glVertex3f(bs[i+1][j][0],bs[i+1][j][1],bs[i+1][j][2]);}glEnd();glDisable(GL_NORMALIZE);}else{glBegin(GL_LINES);if(j<u){glVertex3f(bs[i][j][0],bs[i][j][1],bs[i][j][2]);glVertex3f(bs[i][j+1][0],bs[i][j+1][1],bs[i][j+1][2]);}if(i<v){glVertex3f(bs[i][j][0],bs[i][j][1],bs[i][j][2]);glVertex3f(bs[i+1][j][0],bs[i+1][j][1],bs[i+1][j][2]);}glEnd();}}}#endif#endif建立库文件“myNurbs.h”保存在include目录下,在文件开始处写上#include "myNurbs.h"即可用各函数的功能。

相关文档
最新文档