直线生成算法的实现

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

实验二:直线生成算法
班级 13软件+道铁1班学号 20132110050115姓名丁益
1.实验目的
a)通过实验,进一步理解直线段扫描转换的DDA算法、中点画线自算法
及bresenham算法的基本原理,掌握以上算法生成直线段的基本过程。

b)通过编程,掌握在C/C++环境下完成用DDA算法、中点画线算法及
bresenham算法对任意直线段的扫描转换,以及在C/C++环境下完成用中
点画圆及椭圆的绘制方法。

2.实验内容
c)阅读《openGL三维程序设计》(电子书)第二部分第四章,掌握OpenGL
基本建模方法,并调试其中程序。

d)参考教材第6章,编程实现整数DDA算法、中点画线法和Bresenham
画线法,绘制直线(直线宽度和线型可自定)。

2.1 DDA直线生成
2.1.1算法原理
已知过端点P0(x0,y0),P1(x1,y1)的直线段L(P0,P1),斜率为k=(y1-y0)/(x1-x0),画线过程从x的左端点x0开始,向x右端点步进,步长为1个像素,计算相应的y坐标为y=kx+B。

计算y i+1 = kx i+B
=kx i +B+kx
=y i +kx
当x=1,y i+1=y i+k,即当x每递增1,y递增k。

由计算过程可知,y与k可能为浮点数,需要取y整数,源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。

2.1.2 算法流程
2.1.3 算法实现关键代码
#include<GL/glut.h>
#include<math.h>
void Init()
{
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,200.0,0.0,150.0);
}
void lineDDA(int x0,int y0,int xEnd,int yEnd)
{
int dx=xEnd-x0,dy=yEnd-y0,steps,k;
float xIncrement, yIncrement, x=x0, y=y0;
if(fabs(dx)>fabs(dy))
steps=fabs(dx);
else
steps=fabs(dy);
xIncrement=float(dx)/float(steps);
yIncrement=float(dy)/float(steps);
for(k=0;k<steps;k++)
{
x+=xIncrement;
y+=yIncrement;
glBegin(GL_POINTS);
glVertex2i(x,(int)(y+0.5));
glEnd();
}
glFlush();
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
lineDDA(50,50,100,120);
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(100,100);
glutInitWindowSize(400,400);
glutCreateWindow("Hello World");
Init();
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
2.1.4算法运行示例及中间结果
2.2 Brese nham直线生成
2.2.1算法原理
Bresenham算法的基本原理是:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。

2.2.2算法流程
2.2.3算法实现关键代码
#include<stdlib.h>
#include<GL/glut.h>
#include<math.h>
void init(void)
{
glClearColor(1.0,1.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0,200,0.0,200);
}
void lineBres(int x0,int y0,int xEnd,int yEnd) {
int dx=fabs(xEnd-x0),dy=fabs(xEnd-y0);
int p=2*dy-dx;
int twoDy=2*dy,twoDyMinusDx=2*(dy-dx); int x, y;
if(x0>xEnd)
{
x=xEnd;
y=yEnd;
xEnd=x0;
}
else
{
x=x0;
y=y0;
}
while(x<xEnd)
{
x++;
if(p<0)
p+=twoDy;
else
{
y++;
p+=twoDyMinusDx;
}
glBegin(GL_POINTS);
glVertex2i(x,(int)(y+0.5));
glEnd();
}
glFlush();
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
lineBres(40,40,150,150);
}
void main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowPosition(50,100);
glutInitWindowSize(400,400);
glutCreateWindow("Hello");
init();
glutDisplayFunc(myDisplay);
glutMainLoop();
}
2.2.4算法运行示例及中间结果
2.4算法分析与比较
(1)DDA算法画线算法也称数值微分法,是一种增量算法。

它的算法实质上是用数值方法解微分方程,同时对x和y各增加一个小增量来计算下一步的x、y值。

DDA算法画线比较直观可行,逻辑简单,但是每一步都需要一个浮点乘法与一个round函数进行舍入运算,效率不高。

(2)Bresenham画线算法是计算机图形学领域使用最广泛的直线生成方法,该方法类似于中点画线算法,由误差项符号决定下一个像素正右方还是右上方点。

2.5实验总结
通过本次实验,我学会了很多。

学会掌握了Win32 Application的典型“Hello World”程序编程的基本方法,初步了解了计算机图形学在计算机图像处理,工程制图,平面设计上面的应用,掌握了计算机绘制圆和直线的几种算法,DDA直线和圆的生成算法,Bresenham直线和圆的生成算法,和圆的参数生成方法,并且理解和掌握了他们的优缺点,在以后的实验中会努力学习,争取把这门计算机图形学课学好。

在本次实验开始之前,了解vc画图知识不多,所以前期准备工作量很大,加之刚开始接触图形学的知识,应用不是很熟练。

经过大致一周的算法研究和相关的准备工作,才使得实验得以完成。

印象深刻的是在Bresenham 算法画圆中将视区的坐标原点移到了视区中间,而且做默认的坐标做了变换。

本次实验收获颇多,理论与实际相结合,帮助我更好地掌握了上课知识,也为以后图形学相关实验打下坚实基础。

相关文档
最新文档