华科 图形学 实验报告.docx
《华科 图形学 实验报告.docx》由会员分享,可在线阅读,更多相关《华科 图形学 实验报告.docx(11页珍藏版)》请在冰点文库上搜索。
华科图形学实验报告
计算机图形学上机实验报告
计算机科学与技术学院
班级:
CS1210
学号:
U201215079
姓名:
候宝峰
指导教师:
何云峰
完成日期:
2014、12、4
实验一Kock曲线的生成
一、实验目的与要求
1.1实验目的
①、理解glut程序框架;
②、理解窗口到视区的变换;
③、理解OpenGL实现动画的原理;
④、掌握用迭代算法生成Kock雪花曲线的方法。
2.实验要求
①、生成6次迭代后的Kock曲线;
②、生成一个完整的雪花。
1.2实验内容
1.实验原理
Kock曲线的初始生成元是一条直线段,生成规则是将直线段均分为三等分,首尾两段保持不变,中间用两段等长且互成60°角的直线段代替,如下图1所示。
图1Kock雪花生成规则
这样,直线段被分成四段,每段长度只有原来的1/3,根据下面给出的方程组可以求出这种Kock曲线的分形维数
假设原直线的首尾点是
(
,
),
(
,
),则新的4段直线段的5个端点坐标分别为
其中,第三个点坐标公式中的正负号表示两条新直线处于原直线段的哪一侧。
根据这一规则(取正号)迭代6次后产生的结果如下图2所示。
当然,也可以改变原始图形以获得其他的形状,例如,初始图形改为等边三角形,此时产生的曲线形状类似于雪花,如下图3所示,这种曲线被称为Kock雪花曲线。
图2迭代6次的Kock曲线图3迭代6次的Kock雪花曲线
二、实验内容
①、添加代码生成6次迭代后的Kock曲线;
2、添加代码生成一个完整的雪花。
(1)、生成6次迭代后的Kock曲线
添加实现迭代生成Kock曲线算法的代码,如下:
voidDelta(doublex0,doubley0,doublex1,doubley1,intn)
{
if(n!
=1)
{
Delta(x0,y0,x0+(x1-x0)/3,y0+(y1-y0)/3,n-1);
Delta(x0+(x1-x0)/3,y0+(y1-y0)/3,(x1+x0)/2+(y0-y1)*1.732/6,(y1+y0)/2+(x1-x0)*1.732/6,n-1);
Delta((x1+x0)/2+(y0-y1)*1.732/6,(y1+y0)/2+(x1-x0)*1.732/6,x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,n-1);
Delta(x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,x1,y1,n-1);
}
else
{
glBegin(GL_LINE_STRIP);
glVertex3f(x0,y0,0.0f);
glVertex3f(x0+(x1-x0)/3,y0+(y1-y0)/3,0.0f);
glVertex3f((x1+x0)/2+(y0-y1)*1.732/6,(y1+y0)/2+(x1-x0)*1.732/6,0.0f);
glVertex3f(x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,0.0f);
glVertex3f(x1,y1,0.0f);
glEnd();
}
}
在调用该函数时,n的值可以根据需要随便定义,n的值决定了迭代的次数,n越大,生成的图形越复杂。
在本次实验中,要求迭代的次数为6次,则定义n的值为n=6。
在该算法中用到的公式即为实验原理中给出的生成的新直线的5个端点的坐标。
(2)、生成一个完整的雪花
相对于生成Kock曲线而言,要生成雪花,只需要加入Delta(x0,y0,x1,y1,n);
Delta(x1,y1,x2,y2,n);Delta(x2,y2,x0,y0,n);语句即可。
即加入生成等边三角形的步骤,使得经过三次分别处理得到的迭代6次的Kock曲线按首尾相接的方式连接成等边三角形。
当然,这就要注意给定端点的坐标值的选择,使得最后的图形为一个比较规范的等边三角形。
三、实验结果
1.生成6次迭代后的Kock曲线
如下图4所示:
图46次迭代后的Kock曲线
2.生成一个完整的雪花
如下图5所示:
图5迭代6次的Kock雪花曲线
四、心得体会
这是图形学的第一次实验,对于实验用的编程环境——VisualC++,我们并不陌生,以前有过接触。
但是对于代码中要用到的各种函数,倒觉得很新鲜,听老师讲解的时候,大致能明白它们的使用规则与实现的功能,而到了具体实践的时候,发现用起来还是有一定难度的……
五、源程序
1.生成6次迭代后的Kock曲线
//PointAndLine.c
#include
#include
#include
voidDelta(doublex0,doubley0,doublex1,doubley1,intn)
{
if(n!
=1)
{
Delta(x0,y0,x0+(x1-x0)/3,y0+(y1-y0)/3,n-1);
Delta(x0+(x1-x0)/3,y0+(y1-y0)/3,(x1+x0)/2+(y0-y1)*1.732/6,(y1+y0)/2+(x1-x0)*1.732/6,n-1);
Delta((x1+x0)/2+(y0-y1)*1.732/6,(y1+y0)/2+(x1-x0)*1.732/6,x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,n-1);
Delta(x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,x1,y1,n-1);
}
else
{
glBegin(GL_LINE_STRIP);
glVertex3f(x0,y0,0.0f);
glVertex3f(x0+(x1-x0)/3,y0+(y1-y0)/3,0.0f);
glVertex3f((x1+x0)/2+(y0-y1)*1.732/6,(y1+y0)/2+(x1-x0)*1.732/6,0.0f);
glVertex3f(x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,0.0f);
glVertex3f(x1,y1,0.0f);
glEnd();
}
}
voidRenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);//用当前背景色填充窗口
glColor3f(0.0f,0.0f,0.0f);//设置当前的绘图绘图RGB颜色
GLfloatsizes[2];//保存绘制点的尺寸范围
GLfloatstep;//保存绘制点尺寸的步长
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);//获得点的尺寸范围
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);//获得点尺寸的步长
//绘制一条宽度为1的直线
glLineWidth
(1);//设置线宽
doublex0=50.0,y0=100.0,x1=300.0,y1=100.0;
intn=6;
Delta(x0,y0,x1,y1,n);
glDisable(GL_LINE_STIPPLE);
glFlush();//刷新OpenGL命令队列
}
voidChangeSize(GLsizeiw,GLsizeih)
{
if(h==0)h=1;
glViewport(0,0,w,h);//设置视区尺寸
//重置坐标系统
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//建立修剪空间的范围
if(w<=h)
glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0f,-1.0f);
else
glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0f,-1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
voidSetupRC(void)
{
glClearColor(1.0f,1.0f,1.0f,1.0f);//设置窗口的背景色
}
voidmain(void)
{
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("点与线");
glutDisplayFunc(RenderScene);//设置当前窗口的显示回调函数
glutReshapeFunc(ChangeSize);//为当前窗口设置窗口再整形回调函数
SetupRC();
glutMainLoop();//启动主GLUT事件处理循环
}
2.生成一个完整的雪花
//PointAndLine.c
#include
#include
#include
//递归进行画线
voidDelta(doublex0,doubley0,doublex1,doubley1,intn)
{
if(n!
=1)
{
Delta(x0,y0,x0+(x1-x0)/3,y0+(y1-y0)/3,n-1);
Delta(x0+(x1-x0)/3,y0+(y1-y0)/3,(x1+x0)/2-(y0-y1)*1.732/6,(y1+y0)/2-(x1-x0)*1.732/6,n-1);
Delta((x1+x0)/2-(y0-y1)*1.732/6,(y1+y0)/2-(x1-x0)*1.732/6,x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,n-1);
Delta(x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,x1,y1,n-1);
}
else
{
glBegin(GL_LINE_STRIP);
glVertex3f(x0,y0,0.0f);
glVertex3f(x0+(x1-x0)/3,y0+(y1-y0)/3,0.0f);
glVertex3f((x1+x0)/2-(y0-y1)*1.732/6,(y1+y0)/2-(x1-x0)*1.732/6,0.0f);
glVertex3f(x0+2*(x1-x0)/3,y0+2*(y1-y0)/3,0.0f);
glVertex3f(x1,y1,0.0f);
glEnd();
}
}
voidRenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);//用当前背景色填充窗口
glColor3f(0.0f,0.0f,0.0f);//设置当前的绘图绘图RGB颜色
GLfloatsizes[2];//保存绘制点的尺寸范围
GLfloatstep;//保存绘制点尺寸的步长
//GLfloatcurSize;//当前绘制的点的大小
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);//获得点的尺寸范围
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);//获得点尺寸的步长
//绘制一条宽度为1的直线
glLineWidth
(1);//设置线宽
doublex0=60.0,y0=70.0,x1=260.0,y1=70.0,x2=160.0,y2=243.2;
intn=6;
//画三角形(构造等边三角形)
Delta(x0,y0,x1,y1,n);
Delta(x1,y1,x2,y2,n);
Delta(x2,y2,x0,y0,n);
glDisable(GL_LINE_STIPPLE);
glFlush();//刷新OpenGL命令队列
}
voidChangeSize(GLsizeiw,GLsizeih)
{
if(h==0)h=1;
glViewport(0,0,w,h);//设置视区尺寸
//重置坐标系统
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//建立修剪空间的范围
if(w<=h)
glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0f,-1.0f);
else
glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0f,-1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
voidSetupRC(void)
{
glClearColor(1.0f,1.0f,1.0f,1.0f);//设置窗口的背景色
}
voidmain(void)
{
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("点与线");
glutDisplayFunc(RenderScene);//设置当前窗口的显示回调函数
glutReshapeFunc(ChangeSize);//为当前窗口设置窗口再整形回调函数
SetupRC();
glutMainLoop();//启动主GLUT事件处理循环
}