实验四 自由曲线的绘制(OpenGL版)

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

南昌大学实验报告四

学生姓名:张鑫维学号:6100407234 专业班级:计算机072 实验类型:□验证□综合■设计□创新实验日期:2010-12-3 实验成绩:

自由曲线的绘制(OpenGL版)

1. 实验目的

1、掌握Bezier曲线的定义生成算法、离散生成算法;

2、掌握B样条曲线的定义生成算法。

2. 实验内容

假设窗口的宽高分别是600 , 600 个像素单位,定义的裁剪窗口由函数

gluOrtho2D(-50.0,50.0,-50.0,50.0)决定。

曲线控制点数据:

1、已知空间四点P0(-40.0,-40.0,0.0)、P1(-10.0,200.0,0.0)、P2(10.0,-200.0,0.0)、P3(40.0,40.0,0.0),根据Bezier曲线的定义编程绘制曲线。

2、已知空间四点P0(-40.0,-40.0,0.0)、P1(-10.0,200.0,0.0)、P2(10.0,-200.0,0.0)、P3(40.0,40.0,0.0),根据Bezier曲线的离散生成算法绘制曲线。

3、已知空间四点P0(-40.0,-40.0,0.0)、P1(-10.0,200.0,0.0)、P2(10.0,-200.0,0.0)、P3(40.0,40.0,0.0),根据B样条曲线的定义绘制曲线。

3.实验指导

由于几何外形设计的要求越来越高,传统的曲线曲面表示方法,已不能满足用户的需求。1962 年,法国雷诺汽车公司的P.E.Bezier 构造了一种以逼近为基础的参数曲线和曲面的设计方法,并用这种方法完成了一种称为UNISURF 的曲线和曲面设计系统,1972年,该系统被投入了应用。Bezier方法将函数逼近同几何表示结合起来,使得设计师在计算机上就象使用作图工具一样得心应手。

4. 实验结果

按照定义画出的Bezier曲线(101个点) 按照de Casteljau算法画出的Bezier曲线(1001个点)

三次Bezier曲线的自由生成确定三次B样条曲线的控制点

所有控制点确定后画出B样条曲线拖拽第四个控制点,调整曲线

5. 实验心得

这个实验考查的是自由曲线的绘制,要求熟练掌握好Bezier曲线和B样条曲线的原理和编程。我首先按照实验要求,完成了对已知四个控制点的Bezier曲线生成,采用了定义和de Casteljau两种算法编程。在掌握好Bezier曲线的两种算法后,我尝试着扩展实验,利用鼠标响应函数mouse(),选取用户左击鼠标确定的控制点,在取得了四个控制点后,打印出四个控制点、控制多边形线段以及生成的Bezier曲线。这样可以通过鼠标点击,自由绘制三次Bezier曲线了。

B样条曲线的关键是deBoor算法。我之前按照书上的编写了程序,结果四个控制点只打出一个点,而不见曲线。后来老师说书上的有问题,我又参考了他给的资料后才正确完成了程序。后来,我又进一步完善了程序。先是让程序能从鼠标接收任意多个控制点,按照控制点的个数动态算出对应的开放节点矢量,接着调用deBoor算法,算出每段曲线上的点的坐标。随后,我又将橡皮筋技术应用到了该程序,让程序在绘制了曲线后能通过鼠标左键的拖拽控制点实现B样条曲线的调整,进一步提高了程序的可用性。

通过这个实验,我不仅深入了解了自由曲线绘制的算法,还熟练了OpenGL编程。特别是

鼠标响应函数的处理,让我收获颇大,对交互式的OpenGL编程能力有了很大的提高。

6. 程序源码

float deboor(int degree,float coeff[],float knot[],float u,int i) { //deboor算法

int k,j;

float t1,t2,coeffa[30];

for(j=i-degree; j<=i; j++)

coeffa[j]=coeff[j];

for(k=1; k<=degree; k++){

for(j=i; j>=i-degree+k; j--){ t1=(float)(knot[j+degree-k+1]-u)/ (knot[j+degree-k+1]-knot[j]);

t2=1.0-t1;

coeffa[j]=t1*coeffa[j-1]+t2*coeff a[j];}}

return coeffa[i];}

void bspToPoints(int degree,int L,float coeff[],float knot[],int dense,float points[],int &pointNum)

{ //控制点生成曲线点坐标

int i,j;

float u;

pointNum=0;

for(i=degree; i<=L+degree;i++){

if(knot[i+1]>knot[i]){

for(j=0; j

points[pointNum++]=deboor(degree, coeff,knot,u,i);}}}}

void calKnot(float knot[])

{ //计算节点矢量

int i,j,l;

for(i=0; i<3; i++) knot[i]=0.0;

for(j=0; j<=controlNum-3; j++,i++) knot[i]=j;

for(l=0; l<3; l++,i++) knot[i]=j-1; }

bool isDot(int x,int y)

{ //判断是否为控制点

int i;

y=600.0-y;

for(i=0; i

if((x-Vertex_X[i])*(x-Vertex_X[i] )+(y-Vertex_Y[i])*(y-Vertex_Y[i])<=25 ){controlIndex=i; return true;} return false;}

void displayImage(void)

{ //画出包含控制点的B样条曲线

int i;

glClear(GL_COLOR_BUFFER_BIT);

glPointSize(1.0);

glColor3f(1.0, 0.0, 0.0);

glEnable (GL_LINE_STIPPLE);

glLineStipple (1, 0xF0F0);

glBegin(GL_LINE_STRIP);

for(i=0; i

glEnd();

glDisable(GL_LINE_STIPPLE);

glColor3f(1.0, 1.0, 1.0);

glBegin(GL_POINTS);

for(i=0; i

glPointSize(5.0);

glColor3f (1.0, 1.0, 0.0);

glBegin(GL_POINTS);

for(i=0; i

glVertex2f(Vertex_X[i],Vertex_Y[i ]);

glEnd();}

void displayInit(void)

{ //初始状态下的绘制函数

glClear(GL_COLOR_BUFFER_BIT);

glFlush();}

void displayOnDraw(void)

{ //生成曲线过程中的绘制函数

int i;

glClear(GL_COLOR_BUFFER_BIT);

glPointSize(1.0);

相关文档
最新文档