OpenGL 实验2直线生成算法实现

更新时间:2024-06-09 08:23:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实验2 直线生成算法实现

1. 实验目的

理解基本图形元素光栅化的基本原理, 掌握一种基本图形元素光栅化算法, 利用0penGL实现直线光栅化的 DDA算法。

2. 实验内容

(1)根据所给的直线光栅化的示范源程序, 在计算机上编译运行, 输出正确结果。

(2)指出示范程序采用的算法, 以此为基础将其改造为中点线算法或 Bresenham算法,写入实验报告。

(3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告。 (4)了解和使用 OpenGL的生成直线的命令,来验证程序运行结果。

3. 实验原理

示范代码原理DDA算法。下面介绍 OpenGL画线的一些基础知识和glutReshapeFunc()函数。

(1)数学上的直线没有宽度,但0penGL的直线则是有宽度的。同时, OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。可以认为, OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。这里的线由一系列顶点顺次连接而成, 有闭合和不闭合两种。

前面的实验已经知道如何绘“点”,那么 OpenGL是如何知道拿这些顶点来做什么呢? 是依次画出来,还是连成线? 或者构成一个多边形? 或是做其他事情? 为了解决这一问题, OpenGL要求:指定顶点的命令必须包含在 glBegin函数之后, glEnd函数之前(否则指定的顶点将被忽略),并由 glBegin来指明如何使用这些点。 例如:

glBegin(GL P0INTS) , glVertex2f(0.0f, 0.0f);

glVertex2f(0.5f, 0.0f); glEnd();

则这两个点将分别被画出来。如果将 GL_POINTS替换成 GL_LINES,则两个点将被认为是直线的两个端点, OpenGL将会画出一条直线。还可以指定更多的顶点, 然后画出更复杂的图形。另一方面, glBegin支持的方式除了 GL_POINTS和 GL_LINES,还有GL LINE STRIP、 GL LINE L0〇P、 GL TRIANGLES、 GL TRIANGLE STRIP、 GL TRIANGLE_FAN等几何图元。

(2) 首次打开窗口、移动窗口和改变窗口大小时, 窗口系统都将发送一个事件, 以通知程序员。如果使用的是 GLUT,通知将自动完成,并调用向 glutReshapeFunc注册的函数。该函数必须完成下列工作:

①重新建立用作新渲染画布的矩形区域。 ②定义绘制物体时使用的坐标系。 如:

void Reshape(int w, int h) {

glViewport(0, 0, (GLsizei) w,(GLsizei) h);

glMatrixMode(GL_PROJECTION) ; glLoadIdentity() ;

gluOrtho2D(0.0, (GLdouble) w,0.0,(Gldouble)h); }

在 GLUT内部, 将给该函数传递两个参数: 窗口被移动或修改大小后的宽度和高度, 单位为像素。 glViewport()调整像素矩形,用于绘制整个窗口。接下来三个函数调整绘图坐标系,使左下角坐标为(0,0),右上角坐标为(w,h)。

4. 实验代码

#include

void SetPixel(int x,int y){//画点 glBegin(GL_POINTS); glVertex2i(x,y);//设置点坐标 glEnd(); }

void swap(int *a,int *b)//交换函数 { int temp=*a; *a=*b; *b=temp; }

int abs(int a,int b){ if(a>b) return (a-b); else return (b-a); }

void Bres_Line(int x0,int y0,int x1,int y1)//Bresenham算法 { glColor3f(1.0f,0.0f,0.0f); SetPixel(x0,y0); int dx=abs(x1,x0);//200 int dy=abs(y1,y0);//300 if(dx==0&&dy==0) return ; int flag=0; if(dx0?1:-1; int ty=(y1-y0)>0?1:-1;

int curx=x0; int cury=y0; int dS=2*dy; int dT=2*(dy-dx); int d=dS-dx; while(curx!=x1) { if(d<0) d+=dS; else { cury+=ty; d+=dT; } glPointSize(2); if(flag){ SetPixel(cury,curx); }else{ SetPixel(curx,cury); } curx+=tx; } }

void LineDDA(int x0,int y0,int x1,int y1/*,int color*/){ float x,y; float m,dy,dx; dx=x1-x0; dy=y1-y0; m=dy/dx; y=y0; glColor3f(1.0f,1.0f,1.0f); glPointSize(2); for(x=x0;x<=x1;x++){ SetPixel(x,(y+0.5)); y+=m; } }

void Cirpot(int x0,int y0,int x,int y){ SetPixel((x0+x),(y0+y)); SetPixel((x0+y),(y0+x)); SetPixel((x0+y),(y0-x));

SetPixel((x0+x),(y0-y)); SetPixel((x0-x),(y0-y)); SetPixel((x0-y),(y0-x)); SetPixel((x0-y),(y0+x)); SetPixel((x0-x),(y0+y)); }

void BresCricle(int x0,int y0,double r){ glColor3f(0.0f,0.0f,1.0f); int x,y,d; x=0; y=(int) r; d=int(3-2*r); while(x

void myDisplay(void){ glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,0.0f,1.0f); glRectf(25.0,25.0,75.0,75.0); glPointSize(1); glBegin(GL_POINTS); glColor3f(0.0f,1.0f,0.0f);glVertex2f(100.0f,200.0f); glEnd(); LineDDA(0,0,200,300);//点线 BresCricle(100,200,100); Bres_Line(0,0,300,100); glBegin(GL_LINES); glColor3f(1.0f,0.0f,0.0f);glVertex2f(100.0f,0.0f);

glColor3f(0.0f,1.0f,0.0f);glVertex2f(180.0f,240.0f); glEnd(); glFlush(); }

void Init(){ glClearColor(0.0,0.0,0.0,0.0); glShadeModel(GL_SMOOTH); }

void Reshape(int w,int h){ glViewport(0,0,(GLsizei) w,(GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0,(GLdouble) w,0.0,(GLdouble) h);//坐标系定义 }

int main(int argc,char *argv[]){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); glutInitWindowPosition(100,100); glutInitWindowSize(400,400); glutCreateWindow(\ Init(); glutDisplayFunc(myDisplay); glutReshapeFunc(Reshape); glutMainLoop(); return 0; }

5. 实验结果

6. 实验分析

在书本中代码呈现出的直线是一条斜率为1的线,而按照数据,线条斜率为1.5,分析其原因是在LineDDA函数中,m,x,y等值的类型都为int型,造成了数据的丢失,所以斜率发生了变化。

本文来源:https://www.bwwdw.com/article/ulo6.html

Top