计算机图形学实验报告模板

时间:2024.4.8

巢 湖 学 院 计 算 机 图 形 学

实 验 报 告(模板)

本课程实验包括:

以下为实验二和实验三模板

            实验一:基本图元绘制

一、实验目的

  了解OpenGL图形软件包绘制图形的基本过程及其程序框架,并在已有的程序框架中添加代码实现直线和圆的生成算法,演示直线和圆的生成过程,从而加深对直线和圆等基本图形生成算法的理解。

二、实验内容

          

实验操作和步骤:本次实验主要的目的是为了掌握基本画线和画圆算法,对于书上给出的代码,要求通过本次试验来具体的实现。由于实验已经给出大体的框架,所以只需要按照书上的算法思想来设计具体实现代码,对于直线DDA算法,中点Bresenham算法及其改进算法,以及Bresenham画圆算法都有进一步的体会。DDA算法是对每一步都要进行增量处理,然后取整,绘制,而Bresenham通过判断误差函数和求取递推公式来实现。特别是对于整数的选择取舍,以及代码的流程和循环的控制有一个深入的了解。同时也熟练运用OpenGL基本的绘图函数。

三、体会

       通过本次试验,我进一步加深了对于基本画图算法的理解。特别是对于DDA,Bresenham和画圆算法。其中,DDA算法由于每一步都要处理浮点数的四舍五入,所以在绘图时要进行取整,效率较低,但是代码直观好懂,符合原理。而对于Bresenham及其改进算法,都是在理论推导的基础上来实现的,然后经过整数化,形成了一个高效率的画图算法,所以需要适当的理解,特别是对于取整操作判断比较巧妙,实现了避免多次判断计算浮点数的目的,所以比较高效。而绘制圆形的时候,用到的基本思想还是和Bresenham画图算法一样,只不过需要注意的是八分法画圆,这样只需要绘制其中的八分之一就可以利用对称的关系来绘制出整个 图形。而对于是否走下一步,或者是停留,判断的依据还是误差函数,和前面的思想是类似。另外,通过实验训练了自己的编程能力,同时熟悉了OpenGL绘图的函数和流程,也进一步巩固了相关的知识。

五、源程序

注意:代码部分只要给出画图的子函数就可以,不需要向下面一样给出全部代码。

源代码如下:

////////////////////////////////////////////////////////////////////////////

//实验要求:(1)理解glut程序框架                                          //

//          (2)理解窗口到视区的变换                                      //

//          (3)理解OpenGL实现动画的原理                                  //  

//          (4)添加代码实现中点Bresenham算法画直线                       //

//          (5)添加代码实现改进Bresenham算法画直线                       //

//          (6)添加代码实现圆的绘制(可以适当对框架坐标系进行修改)      //

//          (7)适当修改代码实现具有宽度的图形(线刷子或方刷子)          //

////////////////////////////////////////////////////////////////////////////

#include <windows.h>

#include <gl/glut.h>

#include "stdio.h"

int m_PointNumber = 0; //动画时绘制点的数目

int m_DrawMode = 1;    //绘制模式  1    DDA算法画直线

                       //           2    中点Bresenham算法画直线

                       //           3    改进Bresenham算法画直线

                       //           4    八分法绘制圆

                       //           5    四分法绘制椭圆

//绘制坐标线

void DrawCordinateLine(void)

{

         int i = 0 ;

         //坐标线为黑色

         glColor3f(0.0f, 0.0f ,0.0f);

         glBegin(GL_LINES);

        for (i=10;i<=250;i=i+10)

                   {

                            glVertex2f((float)(i), 0.0f);

                            glVertex2f((float)(i), 250.0f);

                            glVertex2f(0.0f, (float)(i));

                            glVertex2f(250.0f, (float)(i));

                   }

         glEnd();

}

//绘制一个点,这里用一个正方形表示一个点。

void putpixel(GLsizei x, GLsizei y)

{

         glRectf(10*x,10*y,10*x+10,10*y+10);

}

///////////////////////////////////////////////////////////////////

//DDA画线算法                                                   //

//参数说明:x0,y0  起点坐标                                     // 

//          x1,y1  终点坐标                                     //

//          num    扫描转换时从起点开始输出的点的数目,用于动画 //

///////////////////////////////////////////////////////////////////

void DDACreateLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num)

{

         //设置颜色

         glColor3f(1.0f,0.0f,0.0f);

        

         //对画线动画进行控制

         if(num == 1)

                   printf("DDA画线算法:各点坐标\n");

         else if(num==0)

                   return;

         //画线算法的实现

         GLsizei dx,dy,epsl,k;

         GLfloat x,y,xIncre,yIncre;

         dx = x1-x0;

         dy = y1-y0;

         x = x0;

         y = y0;

         if(abs(dx) > abs(dy)) epsl = abs(dx);

         else epsl = abs(dy);

         xIncre = (float)dx / epsl ;

         yIncre = (float)dy / epsl ;

         for(k = 0; k<=epsl; k++){

                   putpixel((int)(x+0.5), (int)(y+0.5));

                   if (k>=num-1) {

                            printf("x=%f,y=%f,取整后x=%d,y=%d\n", x, y, (int)(x+0.5),(int)(y+0.5));

                            break;

                   }

                   x += xIncre;

                   y += yIncre;

                   if(x >= 25 || y >= 25) break;

         }

}

///////////////////////////////////////////////////////////////////

//中点Bresenham算法画直线(0<=k<=1)                               //

//参数说明:x0,y0  起点坐标                                     // 

//          x1,y1  终点坐标                                     //

//          num    扫描转换时从起点开始输出的点的数目,用于动画 //

///////////////////////////////////////////////////////////////////

void BresenhamLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num)

{

         glColor3f(1.0f,0.0f,0.0f);

         if(num == 1)

         {

                   printf("中点Bresenham算法画直线:各点坐标及判别式的值\n");

         }

         else if(num==0)

                   return;

         //中点Bresenham划线算法的实现

         GLsizei dx , dy, d, UpIncre, DownIncre, x, y;

         if (x0 > x1){

                   x = x1; x1 = x0; x0 = x;

                   y = y1; y1 = y0; y0 = y;

         }

         x = x0; y = y0;

         dx = x1 - x0; dy = y1 - y0;

         d = dx - 2 * dy;

         UpIncre=2*dx-2*dy;DownIncre=-2*dy;

         while(x<=x1)

         {

                   putpixel(x,y);

                   printf("x = %d , y = %d \n",x,y);

                   x++;

                   if(d<0)

                   {

                            y++;

                            d+=UpIncre;

                   }

                   else

                            d+=DownIncre;

         }

}

///////////////////////////////////////////////////////////////////

//改进的Bresenham算法画直线(0<=k<=1)                             //

//参数说明:x0,y0  起点坐标                                     // 

//          x1,y1  终点坐标                                     //

//          num    扫描转换时从起点开始输出的点的数目,用于动画 //

///////////////////////////////////////////////////////////////////

void Bresenham2Line(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num)

{

         glColor3f(1.0f,0.0f,0.0f);

         if(num == 1)

                   printf("改进的Bresenham算法画直线:各点坐标及判别式的值\n");

         else if(num==0)

                   return;

         //画线算法的实现

         GLsizei x,y,dx,dy,e;

         dx = x1-x0;

         dy = y1-y0;

         e = -dx;x=x0;y=y0;

         while(x<=x1)

         {

                   putpixel(x,y);

                   printf("x = %d , y = %d \n",x,y);

                   x++;

                   e = e+2*dy;

                   if(e>0)

                   {

                            y++;

                            e = e-2*dx;

                   }

         }

}

///////////////////////////////////////////////////////////////////

//Bresenham算法画圆                                             //

//参数说明:x,y    圆心坐标                                     // 

//          R      圆半径                                       //

//          num    扫描转换时从起点开始输出的点的数目,用于动画 //

///////////////////////////////////////////////////////////////////

void BresenhamCircle(GLsizei x, GLsizei y, GLsizei R, GLsizei num)

{

         glColor3f(1.0f,0.0f,0.0f);

         if(num == 1)

                   printf("Bresenham算法画圆:各点坐标及判别式的值\n");

         int d,k=0,xa,ya;

         xa=0;ya=R;d=1-R;

         while(xa<=ya){

                   putpixel(xa+x,ya+y);

                   putpixel(ya+x,xa+y);

                   putpixel(-ya+x,xa+y);

                   putpixel(-xa+x,ya+y);

                   putpixel(-xa+x,-ya+y);

                   putpixel(-ya+x,-xa+y);

                   putpixel(ya+x,-xa+y);

                   putpixel(xa+x,-ya+y);

                   if (k>=num-1) {

                            printf("x=%d , y=%d\n" , xa+x,ya+y);

                            break;

                   }

                   k++;

                   if(d<0) d+=2*xa+3;

                   else{

                            d+=2*(xa-ya)+5;

                            ya--;

                   }

                   xa++;

         }      

}

//初始化窗口

void Initial(void)

{

    // 设置窗口颜色为蓝色

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

}

// 窗口大小改变时调用的登记函数

void ChangeSize(GLsizei w, GLsizei h)

{

         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.0, -1.0);

    else

                   glOrtho (0.0f, 250.0f*w/h, 0.0f, 250.0f, 1.0, -1.0);

}

// 在窗口中绘制图形

void ReDraw(void)

{

         //用当前背景色填充窗口

         glClear(GL_COLOR_BUFFER_BIT);

         //画出坐标线

         DrawCordinateLine();

         switch(m_DrawMode)

         {

         case 1:

                   DDACreateLine(0,0,20,15,m_PointNumber);

                   break;

         case 2:

                   BresenhamLine(0,0,20,15,m_PointNumber);

                   break;

         case 3:

                   Bresenham2Line(1,1,8,6,m_PointNumber);

                   break;

         case 4:

                   BresenhamCircle(12,12,10,m_PointNumber);

                   break;

         default:

                   break;

         }

    glFlush();

}

//设置时间回调函数

void TimerFunc(int value)

{

         if(m_PointNumber == 0)

                   value = 1;

         m_PointNumber = value;

         glutPostRedisplay();

         glutTimerFunc(500, TimerFunc, value+1);

}

//设置键盘回调函数

void Keyboard(unsigned char key, int x, int y)  

{

    if (key == '1')     m_DrawMode = 1;

         if (key == '2')     m_DrawMode = 2;

         if (key == '3')     m_DrawMode = 3;

         if (key == '4')     m_DrawMode = 4;

         m_PointNumber = 0;

         glutPostRedisplay();

}

int main(int argc, char* argv[])

{

         glutInit(&argc, argv);

         //初始化GLUT库OpenGL窗口的显示模式

         glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

         glutInitWindowSize(600,600);

         glutInitWindowPosition(100,100);

         glutCreateWindow("基本图元绘制程序");

         glutDisplayFunc(ReDraw);

    glutReshapeFunc(ChangeSize);

         glutKeyboardFunc(Keyboard);//键盘响应回调函数

         glutTimerFunc(500, TimerFunc, 1);

         // 窗口初始化

    Initial();

         glutMainLoop(); //启动主GLUT事件处理循环

         return 0;

}

更多相关推荐:
计算机图形学实验报告

福建农林大学计算机与信息学院课程名称姓名系专业年级学号指导教师职称实验报告计算机图形学洪世玉计算机计算机科学与技术10级102260010072李小林20xx年11月19日实验项目列表福建农林大学计算机与信息学...

计算机图形学实验(全)

实验1直线的绘制实验目的1通过实验进一步理解和掌握DDA和Bresenham算法2掌握以上算法生成直线段的基本过程3通过编程会在TC环境下完成用DDA或中点算法实现直线段的绘制实验环境计算机TurboC或其他C...

计算机图形学实验报告及代码

第1章概述一教学目标通过本章的学习使学生能够了解计算机图形学的基本概念研究内容当前的发展概况本门课程的特点和应用二教学要求1了解计算机图形学的概念和研究内容2了解本门课程的发展概况三教学内容提要1计算机图形学的...

计算机图形学实验报告

计算机图形学实验报告河南理工大学测绘学院计算机图形学实验报告学号姓名成绩评语交报告日期20xx年6月25日计算机图形学实验报告实验项目一图形学光栅化算法验证实验实验日期20xx年6月5日一实验目的1加强对直线圆...

计算机图形学实验报告

实验报告实验课程计算机图形学学生姓名XXXX学号专业班级软件20xx年12月25日目录i实验一矩阵变换ii实验二图形绘制iii实验三曲线的生成算法实现iv实验四二维基本图形生成的算法v实验五二维填充图的生成算法...

计算机图形学实验报告

班级10计科姓名敖智挺学号20xx30457117实验一直线生成与二次曲线拟合实验内容应用Bresenham画线算法实现一程序完成直线生成实验目的了解掌握VC下D图元的扫描转换原理及VC实现掌握图元属性原理及V...

计算机图形学实验报告

计算机图形学实验报告学号20xx2115姓名班级计算机2班指导老师何太军20xx619实验一Windows图形程序设计基础1实验目的1学习理解Win32应用程序设计的基本知识SDK编程2掌握Win32应用程序的...

计算机图形学 实验报告(4)

怀化学院数学实验中心实验报告学号实验地点姓名指导教师年级班实验时间实验四图形的裁剪一实验目的1掌握二维图形的基本裁剪算法如编码算法中点分割算法LiangBarsky算法2掌握OpenGL中矩阵堆栈函数的使用实现...

计算机图形学实验报告

计算机图形学实验报告姓名学号班级实验地点实验时间谢云飞20xx2497计算机科学与技术112班逸夫楼50720xx03实验1直线的生成1实验目的和要求理解直线生成的原理掌握典型直线生成算法掌握步处理分析实验数据...

1 《大学计算机Ⅰ》实验报告实验二

实验二中文Word20xx实验广东金融学院实验报告课程名称大学计算机第1页共2页实验二中文Word20xx实验神舟八号无人飞行器是中国神舟系列飞船的第八个也是中国神舟系列飞船进入批量生产的代表神八已于20xx年...

《大学计算机Ⅱ》实验报告实验一

广东金融学院实验报告课程名称:大学计算机Ⅱ

太原理工大学 计算机软件技术基础 线形顺序表的插入与删除 实验报告

太原理工大学现代科技学院计算机软件技术基础课程实验报告专业班级学号姓名指导教师太原理工大学现代科技学院实验报告太原理工大学现代科技学院实验报告ifilt1i1forjnjgtijvjvj1vi1bnn1retu...

计算机图形学实验报告(45篇)