实验四 自由曲线曲面算法实验(2)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四 自由曲线曲面算法实验
实验项目性质:设计性实验
所属课程名称:3D 游戏图形学
实验计划学时:3学时
一、 实验目的和要求
1. 了解自由曲线和曲面的生成原理;
2. 掌握并实现Bezier 曲线和B 样条曲线的生成算法;
3. 实现Bezier 曲面的生成算法。
二、 实验原理
1. Bezier 曲线是通过一组多边形折线的顶点来定义的。如果折线的顶点固定不变,则由其定义的Bezier 曲线是唯一的。在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始处和终止处,其他的点用于控制曲线的形状及阶次。曲线的形状趋向于多边形折线的形状,要修改曲线,只要修改折线的各顶点就可以了。因此,多边形折线又称Bezier 曲线的控制多边形,其顶点称为控制点。
三次多项式,有四个控制点,如图1所示,
其数学表示如下:
,300.31 1.32 2.33 3.30
()()()()()()i i i Q t PB t P B t PB t P B t P B t ===+++∑
32230123(1)3(1)3(1),[0,1]t P t t P t t P t P t =-+-+-+∈
(1)
其矩阵形式为
01322313313630()(1),[0,1]33001000P P Q t t t t t P P --⎡⎤⎡⎤⎢⎥⎢⎥-⎢⎥⎢⎥=∈⎢⎥⎢⎥-⎢⎥⎢⎥⎣⎦⎣⎦
(2)
2. B 样条曲线保留了Bezier 曲线的优点,对Bezier 曲线进行了拓广,用B 样条基代替Bernstein 基,克服了Bezier 曲线由于整体表示带来的不具备局部性质的缺点。B 样条曲线的数学定义为
0n k k,m k p(t)P B (t)
==∑
(3)
式中,(0,1
,,)k P k n = 为n+1个控制点,由控制点顺序连成的折线称为B 样条控制多边形。m 是一个阶参数,可以取2到控制顶点个数n+1之间的任一整数,m-1是B 样条曲线的次数。参数t 的选取取决于B 样条结点矢量的选取。k,m B (t)是B 样条基函数,
()()k 1,1,,11,111
1 ()0 ()k k k k m k m k m k m k m k k m k t t t B t t t t t B t B t B t t t t t ++-+-+-++≤<⎧=⎨⎩--=+--若其它 (4) k t 是结点值,01(,,,)n m T t t t += 构成了m-1次B 样条函数的结点矢量,其中的结点是非减序列,所生成的B 样条曲线定义在从结点值1m t -到结点值1n t +的区间上,而每个基函数定义在t 的取值范围内的k t 到k+m t 的子区间内。
从式(3)和(4)可以看出,仅仅给定控制点和参数m 还不足以完全表达B 样条曲线,还需要给定结点矢量并使用公式(4)来获得基函数。
对于三次均匀周期性B 样条曲线,m=4,如果用4个控制点来拟合三次曲线,则n=3。假设结点矢量(0,1,2,3,4,5,6,7)T =,于是得到基函数计算式为:
()(),1,,11,11 1()0 ()11
k k m k m k m k t k B t t k k m t B t B t B t m m -+-≤<+⎧=⎨⎩-+-=+--其他 (5)
最终得到该B 样条曲线的矩阵形式为
,0010414243423013223()1331363011
303061
410 t [0,1)
n
k k m
k ,,,,B B p t P B P P B (t)B (t)B (t)B (t)P P P P t t t P P T M G ==⎡⎤⎢⎥⎢⎥=⋅⎡⎤⎣⎦⎢⎥⎢⎥⎣⎦
--⎡⎤⎡⎤⎢⎥⎢⎥-⎢⎥⎢⎥⎡⎤=⋅⋅⋅⎣⎦⎢⎥⎢⎥-⎢⎥⎢⎥⎣⎦⎣⎦=⋅⋅∈∑ (6) 三、 实验内容
1.下面的代码用来生成三次Bezier 曲线,将代码补充完整,编译运行;修改代码,利用OpenGL 函数生成三次Bezier 曲线。
参考代码:
#include
#include
#include
#include
using namespace std;
struct Point{
int x, y;
};
Point pt[4],bz[11];
vector
bool bDraw;
int nInput;
void CaleBZPoints()
{
添加代码;生成Bezier 曲线上的点;
}
void ControlPoint(vector
{
glPointSize(2);
for(int i=0;i { glBegin(GL_POINTS); glColor3f(1.0f,0.0f,0.0f); glVertex2i(vpt[i].x,vpt[i].y); glEnd(); } } void PolylineGL(Point * pt, int num) { glBegin(GL_LINE_STRIP); for(int i=0;i { glColor3f(1.0f,1.0f,1.0f); glVertex2i(pt[i].x,pt[i].y); } glEnd(); } void myDisplay() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,1.0f,1.0f); if(vpt.size()>0) { ControlPoint(vpt); } if(bDraw) { PolylineGL(pt, 4); CaleBZPoints(); PolylineGL(bz,11); } glFlush(); } void Init() { glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_SMOOTH);