《计算机图形学课内实验》实验报告
《计算机图形学》实验报告

《计算机图形学》实验报告《实验名称》姓名=学号6010203165专业软件外包班级三班任课教师刘世光天津大学仁爱学院计算机系2012年3 月20 日一、实验目的初步熟悉OpenGL这一图形系统的用法,利用Visual C++编程平台。
学习并掌握常用的三维绘制函数。
二、实验内容准备glut库,并联系使用Visual C++进行最简单的图形处理。
调试并学习Teapot绘制程序。
总结三维绘制和二维绘制的异同点。
三、实验结果程序1程序2程序3四、实验分析和总结五、源代码程序1#include <GL/glut.h>//初始化OpenGLvoid init(void){glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//设置背景颜色glShadeModel(GL_FLAT);//设置明暗处理}//主要的绘制过程void display(void){glClear(GL_COLOR_BUFFER_BIT);//清除颜色缓存glColor3f(0.0f,0.0f,1.0f);glRectf(250.0f,250.0f,400.0f,400.0f);glBegin(GL_LINES);//开始画直线glColor3f(1.0f, 1.0f, 1.0f);//设置颜色为白色glVertex2f(30.0f, 30.0f);//第一根线的两个端点glVertex2f(200.0f, 400.0f);glColor3f(1.0f, 0.0f, 0.0f);//设置第二根线的颜色为红色glVertex2f(25.0f, 350.0f);//第二根线的两个端点glVertex2f(250.0f, 50.0f);glEnd();//画线结束glBegin(GL_TRIANGLES);//开始画三角形,注意,没有设颜色,所以还是红色glVertex2f(400.0f, 100.0f);//三角形的三个顶点glVertex2f(600.0f, 100.0f);glVertex2f(500.0f, 300.0f);glEnd();//结束画三角形glFlush();//开始绘制}//在窗口改变大小时调用void reshape(int width, int height)glViewport(0, 0, width, height);//设置视口glMatrixMode(GL_PROJECTION);//设置当前为投影变换模式glLoadIdentity();//用单位矩阵替换当前变换矩阵gluOrtho2D(0.0, width, 0.0, height);//设置正交投影视图体}//处理键盘void keyboard(unsigned char key, int x, int y){switch (key){case 27://esc键退出exit(0);break;default:break;}}int main(int argc, char** argv){glutInit(&argc, argv);//初始化glutglutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置为单缓存,RGB模式glutInitWindowSize(640, 480); //设置窗口大小glutInitWindowPosition(0, 0);//设置窗口起始位置glutCreateWindow("Basic");//设置窗口标题init();//初始化OpenGLglutDisplayFunc(display);//设置显示回调函数glutReshapeFunc(reshape);//设置reshape回调函数glutKeyboardFunc(keyboard);//设置键盘回调函数glutMainLoop();//进入主循环return 0;}//代码要有详细的注释程序2#include "StdAfx.h"#include <stdlib.h>#include <GL/glut.h>void init(void){glEnable(GL_DEPTH_TEST);GLfloat position[] = {1.0, 1.0, 1.0, 0.0};glLightfv(GL_LIGHT0, GL_POSITION, position);glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);GLfloat ambient[] = {0.0, 0.0, 0.0, 1.0};GLfloat diffuse[] = {0.8, 0.4, 0.3, 0.7};GLfloat specular[] = {0.5, 0.3, 0.3, 0.0};glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);glMaterialfv(GL_FRONT, GL_SPECULAR, specular);glMaterialf(GL_FRONT, GL_SHININESS, 50.0);}void display(void){glClearColor(0.65f, 0.3f, 0.05f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glNewList(1, GL_COMPILE);glutSolidTeapot(0.5);glEndList();glCallList(1);glFlush();}void reshape(GLsizei w, GLsizei h){glViewport(0, 0, w, h);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);glMatrixMode(GL_MODELVIEW);}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowPosition(260, 100);glutInitWindowSize(500, 500);glutCreateWindow(argv[0]);init();glutReshapeFunc(reshape);glutDisplayFunc(display);glutMainLoop();return 0;}程序3#include <GL/glut.h>//初始化OpenGLvoid init(void){glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//设置背景颜色glShadeModel(GL_FLAT);//设置明暗处理}//主要的绘制过程void display(void){glClear(GL_COLOR_BUFFER_BIT);//清除颜色缓存glColor3f(0.0f,0.0f,1.0f);glRectf(250.0f,250.0f,400.0f,400.0f);glBegin(GL_LINES);//开始画直线glColor3f(1.0f, 1.0f, 1.0f);//设置颜色为白色glVertex2f(30.0f, 30.0f);//第一根线的两个端点glVertex2f(200.0f, 400.0f);glColor3f(1.0f, 0.0f, 0.0f);//设置第二根线的颜色为红色glVertex2f(25.0f, 350.0f);//第二根线的两个端点glVertex2f(250.0f, 50.0f);glEnd();//画线结束glBegin(GL_TRIANGLES);//开始画三角形,注意,没有设颜色,所以还是红色glVertex2f(400.0f, 100.0f);//三角形的三个顶点glVertex2f(600.0f, 100.0f);glVertex2f(500.0f, 300.0f);glEnd();//结束画三角形glFlush();//开始绘制}//在窗口改变大小时调用void reshape(int width, int height){glViewport(0, 0, width, height);//设置视口glMatrixMode(GL_PROJECTION);//设置当前为投影变换模式glLoadIdentity();//用单位矩阵替换当前变换矩阵gluOrtho2D(0.0, width, 0.0, height);//设置正交投影视图体}//处理键盘void keyboard(unsigned char key, int x, int y){switch (key){case 27://esc键退出exit(0);break;default:break;}}int main(int argc, char** argv){glutInit(&argc, argv);//初始化glutglutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//设置为单缓存,RGB模式glutInitWindowSize(640, 480); //设置窗口大小glutInitWindowPosition(0, 0);//设置窗口起始位置glutCreateWindow("Basic");//设置窗口标题init();//初始化OpenGLglutDisplayFunc(display);//设置显示回调函数glutReshapeFunc(reshape);//设置reshape回调函数glutKeyboardFunc(keyboard);//设置键盘回调函数glutMainLoop();//进入主循环return 0;}//代码要有详细的注释。
计算机图形学实验报告4

计算机图形学实验报告4一、实验目的本次计算机图形学实验旨在深入了解和掌握计算机图形学中的一些关键概念和技术,通过实际操作和编程实现,提高对图形生成、变换、渲染等方面的理解和应用能力。
二、实验环境本次实验使用的软件环境为_____,编程语言为_____,硬件环境为_____。
三、实验内容1、二维图形的绘制使用基本的绘图函数,如直线、矩形、圆形等,绘制简单的二维图形。
通过设置线条颜色、填充颜色等属性,增强图形的表现力。
2、图形的几何变换实现图形的平移、旋转和缩放操作。
观察不同变换参数对图形的影响。
3、三维图形的生成构建简单的三维模型,如立方体、球体等。
应用光照和材质效果,使三维图形更加逼真。
四、实验步骤1、二维图形的绘制首先,在编程环境中导入所需的图形库和相关模块。
然后,定义绘图窗口的大小和坐标范围。
接下来,使用绘图函数按照指定的坐标和参数绘制直线、矩形和圆形。
最后,设置图形的颜色和填充属性,使图形更加美观。
2、图形的几何变换对于平移操作,通过修改图形顶点的坐标值来实现水平和垂直方向的移动。
对于旋转操作,根据旋转角度计算新的顶点坐标,实现图形的绕中心点旋转。
对于缩放操作,将图形的顶点坐标乘以缩放因子,达到放大或缩小图形的效果。
3、三维图形的生成首先,定义三维模型的顶点坐标和三角形面的连接关系。
然后,设置光照的位置、颜色和强度等参数。
接着,为模型添加材质属性,如颜色、反射率等。
最后,使用渲染函数将三维模型显示在屏幕上。
五、实验结果与分析1、二维图形的绘制成功绘制出了各种简单的二维图形,并且通过颜色和填充的设置,使图形具有了更好的视觉效果。
例如,绘制的矩形和圆形边缘清晰,颜色鲜艳,填充均匀。
2、图形的几何变换平移、旋转和缩放操作都能够准确地实现,并且变换效果符合预期。
在旋转操作中,发现旋转角度的正负会影响旋转的方向,而缩放因子的大小直接决定了图形的缩放程度。
3、三维图形的生成生成的三维模型具有一定的立体感和真实感。
《计算机图形学》实验报告

《计算机图形学》实验报告目录1实验2:直线的生成 (1)1.1实验要求和目的 (1)1.2实验课时 (1)1.3实验环境 (1)1.4实验内容 (1)1.5核心代码 (3)1.6实验结果 (7)1.6.1DDA算法 (10)1.6.2Mid-Bresenham算法 (11)1.7心得与体会 (12)2实验4:BSpline曲线绘制 (13)2.1实验要求和目的 (13)2.2实验课时 (13)2.3实验环境 (13)2.4实验内容 (13)2.5核心代码 (16)2.6实验结果 (18)2.6.1B-样条算法 (19)2.6.2Bezeir算法 (22)2.7心得与体会 (24)附录 (25)BSpline曲线控制点的测试数据 (25)数据1 (25)数据2 (27)数据3 (29)数据4 (30)数据5 (31)数据6 (33)数据7 (36)数据8 (38)1实验2:直线的生成1.1实验要求和目的理解直线生成的原理;掌握典型直线生成算法;掌握步处理、分析实验数据的能力;编程实现DDA算法、Bresenham中点算法;对于给定起点和终点的直线,分别调用DDA算法和Bresenham中点算法进行批量绘制,并记录两种算法的绘制时间;利用excel 等数据分析软件,将试验结果编制成表格,并绘制折线图比较两种算法的性能。
1.2实验课时3学时1.3实验环境本试验提供自带实验平台·开发环境:Visual C++ 6.0·实验平台:Free_Curve(自制平台)1.4实验内容本实验提供名为 Experiment_Frame_One的平台,该平台提供基本绘制、设置、输入功能,学生在此基础上实现·平台界面:如图1.4.1所示·设置:通过view->setting菜单进入,如图1.4.2所示·输入:通过view->input…菜单进入,如图1.4.3所示·实现算法:▪DDA算法:void CExperiment_Frame_OneView::DDA(int X0, int Y0, int X1, int Y1)▪Mid_Bresenham算法:voidCExperiment_Frame_OneView::Mid_Bresenham(int X0, int Y0, int X1, int Y1)图 1.4.1 总界面图 1.4.2 设置界面图 1.4.3 输入界面1.5核心代码本次实验的核心代码如下所示。
计算机图形学实验报告

计算机图形学实验报告
在计算机图形学课程中,实验是不可或缺的一部分。
通过实验,我们可以更好地理解课程中所学的知识,并且在实践中掌握这些
知识。
在本次实验中,我学习了如何使用OpenGL绘制三维图形,并了解了一些基本的图形变换和视图变换。
首先,我们需要通过OpenGL的基本命令来绘制基本图形,例
如线段、矩形、圆等。
这些基本的绘制命令需要首先设置OpenGL 的状态,例如绘制颜色、线段宽度等,才能正确地绘制出所需的
图形。
然后,在实验中我们学习了图形的变换。
变换是指通过一定的
规则将图形的形状、位置、大小等进行改变。
我们可以通过平移、旋转、缩放等变换来改变图形。
变换需要按照一定的顺序进行,
例如先进行旋转再进行平移等。
在OpenGL中,我们可以通过设
置变换矩阵来完成图形的变换。
变换矩阵包含了平移、旋转、缩
放等信息,通过矩阵乘法可以完成图形的复合变换。
最后,视图变换是指将三维场景中的图形投影到二维平面上,
成为我们所见到的图形。
在实验中,我们学习了透视投影和正交
投影两种方式。
透视投影是指将场景中的图形按照视点不同而产
生不同的远近缩放,使得图形呈现出三维感。
而正交投影则是简单地将场景中的图形按照平行投影的方式呈现在屏幕上。
在OpenGL中,我们可以通过设置视图矩阵和投影矩阵来完成视图变换。
通过本次实验,我对于计算机图形学有了更深入的了解,并掌握了一些基本的图形绘制和变换知识。
在今后的学习中,我将继续学习更高级的图形绘制技术,并应用于实际的项目中。
计算机图形学第五次实验报告

《计算机图形学》实验报告实验十一真实感图形一、实验教学目标与基本要求初步实现真实感图形, 并实践图形的造型与变换等。
二、理论基础运用几何造型, 几何、投影及透视变换、真实感图形效果(消隐、纹理、光照等)有关知识实现。
1.用给定地形高程数据绘制出地形图;2.绘制一(套)房间,参数自定。
三. 算法设计与分析真实感图形绘制过程中, 由于投影变换失去了深度信息, 往往导致图形的二义性。
要消除这类二义性, 就必须在绘制时消除被遮挡的不可见的线或面, 习惯上称之为消除隐藏线和隐藏面, 或简称为消隐, 经过消隐得到的投影图称为物体的真实图形。
消隐处理是计算机绘图中一个引人注目的问题, 目前已提出多种算法, 基本上可以分为两大类:即物体空间方法和图象空间方法。
物体空间方法是通过比较物体和物体的相对关系来决定可见与不可见的;而图象空间方法则是根据在图象象素点上各投影点之间的关系来确定可见与否的。
用这两类方法就可以消除凸型模型、凹形模型和多个模型同时存在时的隐藏面。
1).消隐算法的实现1.物体空间的消隐算法物体空间法是在三维坐标系中, 通过分析物体模型间的几何关系, 如物体的几何位置、与观察点的相对位置等, 来进行隐藏面判断的消隐算法。
世界坐标系是描述物体的原始坐标系, 物体的世界坐标描述了物体的基本形状。
为了更好地观察和描述物体, 经常需要对其世界坐标进行平移和旋转, 而得到物体的观察坐标。
物体的观察坐标能得到描述物体的更好视角, 所以物体空间法通常都是在观察坐标系中进行的。
观察坐标系的原点一般即是观察点。
物体空间法消隐包括两个基本步骤, 即三维坐标变换和选取适当的隐藏面判断算法。
选择合适的观察坐标系不但可以更好地描述物体, 而且可以大大简化和降低消隐算法的运算。
因此, 利用物体空间法进行消隐的第一步往往是将物体所处的坐标系转换为适当的观察坐标系。
这需要对物体进行三维旋转和平移变换。
常用的物体空间消隐算法包括平面公式法、径向预排序法、径向排序法、隔离平面法、深度排序法、光线投射法和区域子分法。
计算机图形学实验报告_2

计算机图形学实验报告学号:********姓名:班级:计算机 2班指导老师:***2010.6.19实验一、Windows 图形程序设计基础1、实验目的1)学习理解Win32 应用程序设计的基本知识(SDK 编程);2)掌握Win32 应用程序的基本结构(消息循环与消息处理等); 3)学习使用VC++编写Win32 Application 的方法。
4)学习MFC 类库的概念与结构;5)学习使用VC++编写Win32 应用的方法(单文档、多文档、对话框);6)学习使用MFC 的图形编程。
2、实验内容1)使用WindowsAPI 编写一个简单的Win32 程序,调用绘图API 函数绘制若干图形。
(可选任务)2 )使用MFC AppWizard 建立一个SDI 程序,窗口内显示"Hello,Thisis my first SDI Application"。
(必选任务)3)利用MFC AppWizard(exe)建立一个SDI 程序,在文档视口内绘制基本图形(直线、圆、椭圆、矩形、多边形、曲线、圆弧、椭圆弧、填充、文字等),练习图形属性的编程(修改线型、线宽、颜色、填充样式、文字样式等)。
定义图形数据结构Point\Line\Circle 等保存一些简单图形数据(在文档类中),并在视图类OnDraw 中绘制。
3、实验过程1)使用MFC AppWizard(exe)建立一个SDI 程序,选择单文档;2)在View类的OnDraw()函数中添加图形绘制代码,说出字符串“Hello,Thisis my first SDI Application”,另外实现各种颜色、各种边框的线、圆、方形、多边形以及圆弧的绘制;3)在类视图中添加图形数据point_pp,pp_circle的类,保存简单图形数据,通过在OnDraw()函数中调用,实现线、圆的绘制。
4、实验结果正确地在指定位置显示了"Hello,This is my first SDI Application"字符串,成功绘制了圆,椭圆,方形,多边形以及曲线圆弧、椭圆弧,同时按指定属性改绘了圆、方形和直线。
计算机图形学实验报告

计算机图形学实验二维填充图的生成1. 图元填充利用多种图元填充的方法绘制一面五星红旗。
方法有: 扫描转换多边形的逐点判断法(编码算法), 扫描线算法, 区域填充的扫描线算法, 自创的向内复制边法。
1.1说明:1.1.1 宏定义和类型定义:#define max 400#define pi 3.14159265#define STACK_INIT_SIZE 100#define STACKINCREMENT 10#define false 0#define true 1#define ok 1#define error 0#define infeasible -1#define overflow -2typedef int Status;typedef int bool;typedef struct {int y,xLeft,xRight;}SElemType;typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;typedef struct Edge{int ymax;float x,deltax;struct Edge *nextEdge;}Edge;Edge *EL[max];typedef struct{float x,y;}point;Status SetStackEmpty(SqStack *s){s->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));if(!s->base) return overflow;s->top=s->base;s->stacksize=STACK_INIT_SIZE;return ok;}Status PushStack(SqStack *s,SElemType e){if(s->top-s->base>=s->stacksize){s->base=(SElemType*)(s->base,(s->stacksize+STACKINCREMENT)*sizeof(SElemType));if(!s->base) return error;s->top=s->base+s->stacksize;s->stacksize+=STACKINCREMENT;}*s->top++=e;return ok;}Status PopStack(SqStack *s,SElemType *e){ if(s->top==s->base) return error;*e=*(--s->top);return ok;}Status IsStackEmpty(SqStack *s){if(s->base==s->top) return true;else return false;}1.1.2其他由于要填充五角星, 我们就要得到五角星的十个顶点。
计算机图形学实验报告

《计算机图形学》实验报告学号:0908610211姓名:宋雪英班级:计算机0961项目:1.利用其它两种画直线方法实现放大10陪显示方法,交互式画直线,预先定义直线段的起止端点,每点击一次鼠标左键,画出直线上的一点,直到终点为止。
2.利用方形、线性两种画刷来绘制圆和椭圆。
3.实现交互式二维图形的放缩,旋转和对称变换2012年12月25日基本图形的生成技术一、实验目的在一个图形系统中,基本图形(也称为图元、图素等)的生成技术是最基本的,任何复杂的图形都是由基本图形组成的,基本图形生成的质量直接影响该图形系统绘图的质量。
所以,需要设计出精确的基本图形生成算法,以确保图形系统绘图的精确性。
本次实验的目的就是利用Bresenham 算法和中心画线法两种画直线方法实现放大10陪显示方法,交互式画直线,预先定义直线段的起止端点,每点击一次鼠标左键,画出直线上的一点,直到终点为止。
利用方形、线性两种画刷来绘制圆和椭圆。
实现交互式二维图形的放缩,旋转和对称变换。
二、实验任务1.利用其它两种画直线方法实现放大10陪显示方法,交互式画直线,预先定义直线段的起止端点,每点击一次鼠标左键,画出直线上的一点,直到终点为止。
2.利用方形、线性两种画刷来绘制圆和椭圆。
3.实现交互式二维图形的放缩,旋转和对称变换。
三、画直线的实验内容任务一:利用其它两种画直线方法实现放大10陪显示方法交互式画直线,预先定义直线段的起止端点,每点击一次鼠标左键,画出直线上的一点,直到终点为止。
1、设计思路第一步:建立DDAMouseLine工程文件;第二步:向视图类中添加自定义的成员变量用鼠标右键单击视图类,选择“Add Member Variable…”,添加下面三个成员变量。
proctected :CPoint m_p1; //起点CPoint m_p2; //起点CPoint m_p; //点击鼠标时点的取值第三步:向视图类中添加自定义的成员函数原型:public:V oid DDAMouseLine(CDC *pDC, int x0, int y0, int x1, int y1, COLORREF color);Line()函数以当前位置所在的点为直线的起点,另指定一个点为直线的终点,画出一段直线。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《计算机图形学课内实验》实验报告班级:计算机76班姓名:朱亚坤学号:2176413442日期:2019.10.22一、实验目的及要求中点椭圆算法①熟练掌握中点椭圆算法,能够用C/C++编写程序实现任意大小和位置的中点椭圆的绘画②要求以绘图区域中心为坐标系原点(0,0)③能够输入任意椭圆中心坐标(x,y)和参数rx和ry的值二、实验环境Windows 10 操作系统,Visual C++6.0 IDE,EasyX_2018 春分版三、实验内容用户在控制台输入椭圆中心坐标、长半轴长度和短半轴长度,利用中点椭圆算法,调用画点函数,在以绘图区域中心为坐标系原点(0,0)的图形界面,绘制出相应的中点椭圆。
四、数据结构和算法描述中点椭圆算法将第一象限的部分分成两部分绘制,即在斜率绝对值小于1的区域内在x 方向取单位步长,在斜率绝对值大于1的区域内在y方向取单位步长。
取,可定义椭圆函数为即作为决策参数。
从开始,在方向取单位步长直到区域1和区域2的界限处,然后转换为方向的单位步长,再绘制第一象限中剩余的曲线段。
每一步都要检测曲线斜率值。
在区域1和区域2的交界区,,且因此,移除区域1的条件是2ry2x³2rx2y (3-40)算法过程:1.输入、和椭圆中心,并得到椭圆上的第一个点:2.计算区域1中决策参数的初始值:3.在区域1中的每个位置,从开始,假如,沿中心在的椭圆的下一个点为,并且。
否则,沿椭圆的下一个点为,并且。
其中并且直到。
4.使用区域1中计算的最后点来计算区域2中参数的初始值:5.在区域2的每个位置处,从开始,假如,沿中心为的椭圆的下一个点为,并且否则,沿椭圆的下一个点,并且。
使用与区域1中相同的和增量进行计算,直到。
6.确定其他三个象限中的对称点。
7.将计算出的每个像素位置移动到中心在的椭圆轨迹上,并按坐标值绘制点:五、调试过程及实验结果问题一:电脑没有安装VS Studio怎么办解决方案:由于我通常使用Codeblocks,而MFC只能在VS下使用,所以我就选择了Qt,经网上推荐,我准备直接使用Qt creator进行该实验,但研究了几天,Qt里面的一些槽函数还有信号响应机制是在搞不懂,所以果断放弃;最后在网上找到说给C odeblocks可以配置一个叫做EGE的图形库,可以方便画图,但不知为何,我按照网上的指导配置好后无法使用,一直没有找到解决方案;最后又在网上找到一个简易的易上手的计算机图形学库EasyX,但是这个库也只能在VC环境下使用,可我实在不想下载安装占用空间巨大的VS Studio,最后就找到了老古董Visual C++6.0,并配置了E asyX,这才正式开始了实验。
问题二:坐标轴上的数字是颠倒的解决方案:经过查阅资料,EasyX中绘图界面里插入的文字方向是跟随坐标轴方向的,由于在插入文字前我已经改变了绘图界面的坐标原点和坐标轴方向,所以文字颠倒,因此我在输入文字前利用函数setaspectratio(1, 1)将坐标轴方向改回了原来的方向,在插入文字之后,又改成了我们所需要的Y轴正方向向上的样子。
问题三:绘图函数调用后,图形会立即绘制完成解决方案:在画点函数后添加函数sleep(20),这样每间隔20us才绘制一个点,可以让绘制过程看起来慢一点,更清晰。
问题四:在绘制完一个图形后清屏解决方案:为了可以连续作图,需要对之前绘制的图形进行擦除,可是EasyX自带的清屏函数会把我绘制的坐标轴等标识也擦除掉,所以我索性在每次要绘制新图形之前调用一次void coordinate()我自定义的坐标轴绘制函数,但这样每次绘图屏幕都会闪烁一下,看起来特别怪,又一时间想不到特别好的解决方法,所以又作了一个“绘制成功提示”的界面,在每次绘制完图形后的3秒后出现并关闭绘图界面,这样就避免了绘图界面闪烁的问题。
问题五:颜色选择函数的加入解决方案:我想让绘图变得更漂亮些、更易区分,所以准备添加颜色选择,在EasyX 中,颜色是由16进制的8位数字表示的,同时也有关键字代替,所以我想直接让用户输入颜色名称,即关键字来选择颜色,但是不知为何,他会将输入的关键字当做普通文本处理,发生报错,所以我又试着用switch函数用代表字母来选择相应的16进制数字,但是所选择的16进制数字不会被识别,最后发现我定义的函数的int类型,而在EasyX中,对于颜色有专门的数据类型COLORREF,于是将函数类型修改,问题解决。
问题六:实现连续做图解决方案:实现连续做图,首先想到的当然是用一个while循环,但是while循环的入口和出口,以及在循环体内部的循环条件以及各函数之间的调用搭配关系等都比较难以调控,再考虑到用户的使用方便程度,于是用了if+while+switch+switch多重嵌套到达了效果,还是挺不好整的,逻辑上捋了好久,试了好久才达到想要的效果。
实验结果:绘制中心为(50,10),x方向半轴长为100,y方向半轴长为30,颜色为紫色的椭圆绘制中心为(-10,-80),x方向半轴长为40,y方向半轴长为150,颜色为红色的椭圆六、总结总的来说,本次实验做的还是比较满意的,虽然并没有做出来特别漂亮的UI以及方便的菜单按钮等部件,但花费了很长时间,查阅了很多资料,学习使用了EasyX库,还是有很大收获的,同时也加深理解了这四种基本图元绘制的算法,掌握了其算法内涵,能够用代码将其实现,还是对计算机图形学的学习有很大帮助的。
建议本课程可以适当加长上机学识,并安排实验指导老师,带领同学们学习使用一下OpenGL,做一些小游戏或小项目,可以增加这个课程的趣味性,也可以拓展同学们的技能,同时也是对于以后想继续学习或从事计算机图形学这方面同学的一种引导。
七、附录(源程序清单)Head.h#include <graphics.h> // 这样引用EasyX 图形库#include <conio.h>#include <iostream>#include <windows.h>using namespace std;void coordinate(); //画坐标轴void suc(); //成功提示int Round(float x); //四舍五入COLORREF Color(char i); //选择颜色void Line_DDA(int x1, int y1, int x2, int y2, int color); //DDA直线算法void Line_Bresenham(int x1, int y1, int x2, int y2, int color); //Bresenham直线算法void Circle(int x, int y, int r, int color); //中点圆算法void ellipsePlotPoints(int xCenter, int yCenter, int x, int y, int color); //画椭圆的点void ellipse(int xCenter, int yCenter, int Rx, int Ry, int color); //中点椭圆函数Main.cpp (有省略)#include "head.h"void main(){cout<<"\t\tWelcome!"<<endl;cout<<"**************************************"<<endl;cout<<"press 's' to start, press 'Esc' to end"<<endl;cout<<"**************************************"<<endl;char K;K = getch();if(K == 's'){cout<<"\t-+-+-+-+-+-+-+-+-+-+-+-"<<endl;cout<<"\t press '1' :Bresenham"<<endl<<"\t press '2' :DDA"<<endl<<"\t press '3' :Circle"<<endl<<"\t press '4' :ellipse"<<endl;cout<<"\t-+-+-+-+-+-+-+-+-+-+-+-"<<endl;char t;int x1,y1,x2,y2,r,rx,ry;char color;COLORREF c;while(K != 27) //ESC键的ascll码是27{K = getch();switch(K){case'1': //Bresenham直线算法接收输入,省略break;case'2': //DDA直线算法接收输入,省略break;case'3': //中点圆算法接收输入,省略break;case'4': //中点椭圆算法接收输入{cout<<"Please input the center, x_radius, y_radius and color"<<endl;cout<<"'R':red 'Y':yellow 'B':blue 'P':purple 'G':green other:black"<<endl;cout<<"example: 10 10 40 50 B"<<endl;cin>>x1>>y1>>rx>>ry;cin>>color;c = Color(color);}break;case 27: //退出程序{initgraph(220, 60);setbkcolor(CY AN);cleardevice();setcolor(RED);char w[]="You have exited successfull!";outtextxy(10, 25, w);}break;}initgraph(640, 480);setbkcolor(WHITE);setlinestyle(PS_SOLID, 2);cleardevice();coordinate();t=K;switch(t){case'1': //调用Bresenham直线算法,省略break;case'2': //调用DDA直线算法,省略break;case'3': //调用中点圆算法,省略break;case'4': //调用中点椭圆算法{ellipse(x1,y1,rx,ry,c);suc();K = getch();closegraph();}break;case 27:{initgraph(220, 60);setbkcolor(CY AN);cleardevice();setcolor(RED);char w[]="You have exited successfull!";outtextxy(10, 25, w);}break;}}}else if(K == 27){initgraph(220, 60);setbkcolor(CY AN);cleardevice();setcolor(RED);char w[]="You have exited successfull!";outtextxy(10, 25, w);}_getch();closegraph(); // 关闭图形界面}void coordinate() //建立坐标系{setcolor(BLACK);setorigin(320, 240); //更改坐标系原点setaspectratio(1, -1); //更改坐标轴方向setlinestyle(PS_SOLID, 2);line(-320, 0, 320, 0);line(0, -240, 0, 240);line(320, 0, 315, 5);line(320, 0, 315, -5);line(0, 240, -5, 235);line(0, 240, 5, 235);setfillcolor(BLACK);fillcircle(0, 0, 3);int x[16];int j=0;for(int i = -320; i < 320; i += 40) //画坐标轴上的刻度点{ x[j]=i;fillcircle(x[j], 1, 1);fillcircle(1, x[j], 1);j++;}char a='0';char b[]="40";char c[]="-40";LOGFONT f;gettextstyle(&f); // 获取当前字体设置f.lfHeight = 25; // 设置字体高度为25settextstyle(&f); // 设置字体样式setaspectratio(1, 1);outtextxy(-10, 10, a);outtextxy(-20, -45, b);outtextxy(-45, 10, c);setaspectratio(1, -1);}void suc() //成功输出提示{Sleep(3500);initgraph(200, 60);setbkcolor(LIGHTGRAY);cleardevice();setcolor(LIGHTBLUE);char w1[]="Drawing successfull!";outtextxy(20, 15, w1);char w2[]="Press anykey to continue";outtextxy(15, 35, w2);cout<<"= * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * = * ="<<endl; }int Round(float x) //四舍五入函数{return (int)(x < 0 ? x - 0.5 : x + 0.5);}COLORREF Color(char i) //选择颜色函数{switch(i){case'R': return RED;break;case'Y': return YELLOW;break;case'B': return BLUE;break;case'P': return MAGENTA;break;case'G': return GREEN;break;default: return 0;break;}}void Line_DDA(int x1, int y1, int x2, int y2, int color) //DDA画直线,省略void Line_Bresenham(int x1, int y1, int x2, int y2, int color) //Bresenham画直线,省略void Circle(int x, int y, int r, int color) //中点画圆法,省略void ellipsePlotPoints(int xCenter, int yCenter, int x, int y, int color) //画椭圆的点{putpixel(xCenter + x, yCenter + y, color);putpixel(xCenter - x, yCenter + y, color);putpixel(xCenter + x, yCenter - y, color);putpixel(xCenter - x, yCenter - y, color);Sleep(20);}void ellipse(int xCenter, int yCenter, int Rx, int Ry, int color) //画中点椭圆{int Rx2 = Rx * Rx;int Ry2 = Ry * Ry;int twoRx2 = 2 * Rx2;int twoRy2 = 2 * Ry2;int p;int x = 0;int y = Ry;int px = 0;int py = twoRx2 * y;fillcircle(xCenter, yCenter, 1); //画椭圆中心ellipsePlotPoints(xCenter, yCenter, x, y, color);p = Round(Ry2 - (Rx2 * Ry) + (0.25 * Rx2)); //第一部分while (px < py) {x++;px += twoRy2;if (p < 0) {p += Ry2 + px;}else {y--;py -= twoRx2;p += Ry2 + px - py;}ellipsePlotPoints(xCenter, yCenter, x, y, color);}p=Round(Ry2*(x+0.5)*(x+0.5)+Rx2*(y-1)*(y-1)-Rx2*Ry2); //第二部分while (y > 0) {y--;py -= twoRx2;if (p > 0) {p += Rx2 - py;}else {x++;px += twoRx2;p += Rx2 - py + px;}ellipsePlotPoints(xCenter, yCenter, x, y, color);}}。