计算机图形学实验一
计算机图形学实验一报告
计算机图形学实验一报告————————————————————————————————作者:————————————————————————————————日期:ﻩ计算机科学与通信工程学院实验报告课程计算机图形学实验题目二维图形绘制学生姓名学号专业班级指导教师日期成绩评定表评价内容具体内容权重得分论证分析方案论证与综合分析的正确、合理性20%算法设计算法描述的正确性与可读性20%编码实现源代码正确性与可读性30%程序书写规范标识符定义规范,程序书写风格规范20%报告质量报告清晰,提交准时10%总分指导教师签名二维图形的绘制1.实验内容(1)绘制金刚石图案金刚石图案的成图规则是:把一个圆周等分成n份,然后每两点之间连线。
当n取奇数时,该图案可一笔连续绘成,即用MoveTo函数确定一个当前点,然后连续用LineTo函数连点成线。
请设计连线规则并编程实现。
(2)绘制魔术三角形绘制下图所示的魔术三角形图案,采用三种可明显区分的颜色填充。
(3)绘制递归圆应用递归的方法绘制如下所示的图案。
2.实验环境软硬件运行环境:Windows XP开发工具:visual studio 20083. 问题分析根据实验需求,需要在MFC环境中建立一个由“文件”、“绘图”和“帮助”这3个菜单项目组成的菜单,其中“文件”的子菜单为“退出”,完成退出应用程序的工作,“绘图”,的子菜单为“Diamond”,用于绘制金刚石图案等,“帮助”的子菜单为“关于”,用于显示开发人员信息;定义一个输人对话框类,提供个两个参数的输入界面。
最后在客户区输出图案。
1.金刚石图案:为把一个半径为300的圆,等分绘制金刚石图案;设计该算法为避免直线段的重复连接,需设计一个二重循环,代表起点索引号的外层整型变量i从i=0循环到i=n-2,代表终点索引号的内层整型变量j从j=i+1循环到j=n-1。
以(p[i].x,p[i].y)为起点,以(p[j].x,p[j].y)为终点依次连接各线段形成金刚石图案。
计算机图形学实验报告实验1
签名:年月日
1.根据算法原理依次编写算法;
2.将实验数据输入编写好的程序;
3.将不同算法绘制的直线进行对比;
实验结果
Bresenham:
中点算法:
DDA算法:
实验总结
通过本次实验,让我了解了图形学一些基本知识,并利用编程实现了不同的算法生成一些直线,加深了对这些算法的理解和应用,通过实现这些算法生成直线,自己获得了对这门课程的兴趣,对以后的后续学习有着很大的帮助。
实验总结通过本次实验让我了解了图形学一些基本知识并利用编程实现了不同的算法生成一些直线加深了对这些算法的理解和应用通过实现这些算法生成直线自己获得了对这门课程的兴趣对以后的后续学习有着很大的帮助
贵州大学实验报告
学院:计算机科学与信息专业:计科班级:101
姓名
吕杨
学号
1008060040
同组成员
实验时间
(1).输入直线的起点坐标P0(x0.y0)和终点坐标P1(x1.y2)。
(2).定义直线当前点坐标x和y,定义中点偏差判别式d,定义直线斜率k,定义像素点颜色rgb。
(3).x=x0,y=y0,计算d=0.5-k,k=(y1-y0)/(x1-x0),rgb=RGB(0,0,255).
(4).绘制点(x,y),判断点d的符号。若d<0,则(x,y)更新为(x+1,y+1),d更新为d+1-k;否则(x,y)更新为(x+1,y),d更新为d-k。
if(abs(k)<1)
{
for(x=x0;x<=x1;x++)
{
pDC->SetPixel (x,int(y+0.5),c);
计算机图形学实验报告-实验1直线段扫描转换
计算机图形学实验报告班级计算机工硕班学号2011220456姓名王泽晶实验一:直线段扫描转换实验目的通过本次试验,学生可以掌握直线段的扫描转换算法及其程序设计方法。
实验内容1. 绘制20*20的网格线,格子X 和Y 方向间隔均为20像素,网格起始坐标在(20,20)。
我们使用此网格模拟像素矩阵(019,019x y ≤≤≤≤),格子交叉点是像素中心。
2. 输入直线段两端点,可使用以下两种方法之一:a) 对话框输入b) 鼠标在网格内以鼠标左键按下-拖动-抬起方式输入。
注意:直线段两端点要自动取整到模拟的像素中心位置3. 进行直线段扫描转换,通过点击鼠标右键调用方式或者菜单调用的方式执行。
计算完成后,将扫描转换结果,在模拟的像素矩阵中,使用圆形显示出来。
方法一:直线的中点算法算法的主要思想:讨论斜率k ∈[1,+∞)上的直线段的中点算法。
对直线01p p ,左下方的端点为0p (x0,y0),右上方的端点为1p (x1,y1)。
直线段的方程为:y mx B =+⇔y y x B xy yx xB x∆=+⇔∆=∆+∆∆ (,)0F x y xy yx xB ⇔=∆-∆-∆=现在假定已求得像素(,,i r i x y ),则如图得,,11(,]22i i r i r x x x ∈-+ 由于直线的斜率k ∈[1,+∞),故m=1/k ∈(0,1],则1,,13(,]22i i r i r x x x +∈-+ 在直线1i y y =+上,区间,,13(,]22i r i r x x -+内存在两个像素NE 和E 。
根据取整原则,当11(,)i i x y ++在中点M 11(,)2i i x y ++右方时,取像素NE ,否则取像素E ,即 ,11,,1()()01()()0i r i i r i r i x E F M x x x NE F M x +++⎧⇔≤=⎨+⇔>⎩i i 点当(,y +1)在左方时点当(,y +1)在右方时若取2()i d F M =,则上式变为,1,,()01(0i r i i r i r i x E d x x NE d +⎧≤=⎨+>⎩点当点)当计算i d 的递推公式如下:,11,12[(2)()]0122(,2)0122[(2)(1)]2i i r i i i i i i i r x y y x xB d d F x y d x y y x xB ++⎧∆+-∆+-∆⎪≤⎪=++=⎨>⎪∆+-∆++-∆⎪⎩ =202()0i i i i d x d d x y d +∆≤⎧⎨+∆-∆>⎩算法的初始条件为:00,00,0(,)(0,0)12(,1)22r r x y x y d F x y x y =⎧⎪⎨=++=∆-∆⎪⎩ 相应的程序示例:public function drawLine(pixelDrawer:Function, x0:int,y0:int,x1:int,y1:int):void{var dx:Number = x1 - x0;var dy:Number = y1 - y0;var x:Number;var y:Number;if ((dx == 0) && (dy == 0) ){// 两点重合时,直接绘制重合的点pixelDrawer( x0, y0 );return;}else if ( dx==0 ){// 第二点落在X轴上,直接绘制直线上的点var step:Number = dy / Math.abs(dy);for (y=y0; y!=y1; y+=step )pixelDrawer( x0, y );}else if ( dy==0 ){// 第二点落在Y轴上,直接绘制直线上的点step = dx / Math.abs(dx);for (x=x0; x!=x1; x+=step )pixelDrawer( x, y0 );var stepX:Number = dx / Math.abs(dx);var stepY:Number = dy / Math.abs(dy);x = x0, y = y0;pixelDrawer( x, y ); // 绘制起点var k:Number = dy / dx;if ( Math.abs(k)<1.0 ) // 斜率<1的情形,以X为自变量递增{var a:Number = -Math.abs(dy);var b:Number = Math.abs(dx);var d:Number = 2 * a + b;var d1:Number = 2 * a;var d2:Number = 2 * (a + b);while ( x!=x1 ){if ( d<0 ) { x += stepX; y += stepY; d += d2; }else { x += stepX; d += d1; }pixelDrawer( x, y );}}else// 斜率>=1的情形,以Y为自变量递增a = -Math.abs(dx);b = Math.abs(dy);d = 2 * a + b, d1 = 2 * a, d2 = 2 * (a + b);while ( y!=y1 ){if ( d<0 ) { x += stepX; y += stepY; d += d2; }else { y += stepY; d += d1; }pixelDrawer( x, y );}}pixelDrawer( x1, y1 ); // 绘制终点}编译运行程序得到如下结果:方法二:直线的数值微分法算法的主要思想:由于课本上已经给出了斜率m ∈[-1,1]上的算法,故此处给出斜率m ∈[1,+∞〕上的算法,m ∈(-∞,-1]上的可同理推导。
计算机图形学实验报告一
计算机图形学实验报告⼀实验⼀直线、圆、椭圆的⽣成算法⼀、实验⽬的与内容⽬的:利⽤实验使我对所学的图形⽣成算法加深印象,并且练习书写规范的实验报告格式。
1、了解VC编程环境中常⽤控件命令和绘图函数,掌握处理图形的基本⽅法;2、实现直线⽣成算法:数值微分法、中点画线法、Bresenham画线法;3、实现圆的⽣成算法:简单画圆法、中点画圆法、Bresenham画圆法;4、实现椭圆⽣成算法:中点画椭圆法。
⼆、实验前准备:算法分析使⽤开发环境VC++6.0,建⽴⼯程MFC AppWizard exe,选择单⽂档。
进⼊IDR_MAINFRAME,编辑菜单栏,对需要处理的菜单项标题“建⽴类向导”,添加消息映射函数,在映射的函数处添加相应算法的程序代码,就可以完成整个程序。
算法的学习和理解是图形学学习的重要部分,以下对各种算法进⾏分析和总结:1、DDA算法⽣成直线斜率是DDA算法的关键,⽤两点坐标很容易可以得到斜率k,但这⾥要注意k是float。
如果k的绝对值在0和1之间,每次画点x++,y+k再进⾏四舍五⼊(因为x此时⽐y的变化快)。
否则,y++。
也就是为了保持每次+k(或1/k)要⼩于1。
不⽤对k的正负有太多考虑,例如point1(100,100),point2(200,200),可能得到k=-1,这时我们就从point1开始画点,所得的结果是相同的。
2、中点画线法判别式是中点画线法的关键,(0<=k<=1)判别式是为了判断下⼀个点是在当前点正右边还是右上⽅,是和中点⽐较的结果。
d的含义下⼀个点到中点的垂直距离,它的正负可以做下⼀个位置的判断。
初值:d = 2*a + b,增量:上⼀个点d>=0,则d+2*a,上⼀个点d<=0,则d+2*(a+b)。
3、Bresenham算法⽣成直线由误差d的符号来决定下⼀个像素是在正右⽅合适右上⽅。
d的实际意义是实际点到模拟点的垂直距离,我们让它保持在1以内(>=1时,做-1)。
计算机图形学实验内容
计算机图形学实验内容计算机图形学实验肖加清实验一图形学实验基础一、实验目的(1)掌握VC++绘图的一般步骤;(2)掌握OpenGL软件包的安装方法;(3)掌握OpenGL绘图的一般步骤;(4)掌握OpenGL的主要功能与基本语法。
二、实验内容1、VC++绘图实验(1)实验内容:以下是绘制金刚石图案。
已给出VC++参考程序,但里面有部分错误,请改正,实现以下图案。
N=3N=4N=5N=10CP2();virtual ~CP2();CP2(double,double);double x;double y;};CP2::CP2(){this->x=0.0;this->y=0.0;}CP2::~CP2(){}CP2::CP2(double x0,double y0) {this->x=x0;this->y=y0;}//视图类的一个成员函数,这个成员函数可以放在OnDraw函数里调用。
//在视图类的头文件(.h)里定义此函数void Diamond();//在视图类的实现文件(.cpp)里实现此函数void CTestView::Diamond(){CP2 *P;int N;double R;R=300;N=10;P=new CP2[N];CClientDC dc(this);CRect Rect;GetClientRect(&Rect);double theta;theta=2*PI/N;for(int i=0;i<N;i++){P[i].x=R*cos(i*theta);P[i].y=R*sin(i*theta);}for(i=0;i<=N-2;i++){for(int j=i+1;j<=N-1;j++){//其中ROUND函数需要自己实现,实现四舍五入的功能。
dc.MoveTo(ROUND(P[i].x+Rect.right/2),RO UND(P[i].y+Rect.bottom/2));dc.LineTo(ROUND(P[j].x+Rect.right/2),RO UND(P[j].y+Rect.bottom/2));}}delete []P;}2、OpenGL绘图(1)以下是用OpenGL绘制茶壶的代码,请在OpenGL环境下运行,分析OpenGL程序的结构#include <windows.h>#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>//定义输出窗口的大小#define WINDOW_HEIGHT 300#define WINDOW_WIDTH 500//用户初始化函数void myninit(void);//窗口大小变化时的回调函数void CALLBACK myReshape(GLsizei w,GLsizei h);//每帧OpenGL都会调用这个函数,应该把显示代码放在这个函数中void CALLBACK display(void);int window_width=WINDOW_WIDTH;int window_height=WINDOW_HEIGHT;//视点离物体的距离float distance=3.6f;//初始化,此时为空,可以在这里进行初始化操作void myinit(void){}void CALLBACK display(void){//设置清屏的颜色,并清屏和深度缓冲glClearColor(0.0f,0.0f,0.0f,0.0f);glClear(GL_COLOR_BUFFER_BIT|GL_ DEPTH_BUFFER_BIT);//设置成模型矩阵模式glMatrixMode(GL_MODELVIEW);//载入单位化矩阵glLoadIdentity();//坐标中心向Z轴平移-distance,这样使坐标中心位于视点前方glTranslatef(0.0,0.0,-distance);//在坐标中心显示一个茶壶auxWireTeapot(1.0);//等待现有的OpenGL命令执行完成glFlush();//交换前后缓冲区auxSwapBuffers();}void CALLBACK myReshape(GLsizei w,GLsizei h){if(!h) return ;//这定视区glViewport(0,0,w,h);//设定透视方式glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(60.0,1.0*(GLfloat)w/(GLflo at)h,1.0,30.0);window_width=w;window_height=h;}//移近移远的回调函数void CALLBACK MoveNear(void){distance-=0.3f;}void CALLBACK MoveFar(void){distance +=0.3f;}//主函数int main(int argc,char **argv){//初始化OpenGL的显示方式auxInitDisplayMode(AUX_DOUBLE|AUX _RGB|AUX_DEPTH16);//设定OpenGL窗口位置和大小auxInitPosition(0,0,WINDOW_WIDTH,W INDOW_HEIGHT);//打开窗口auxInitWindow("OpenGL的一个简单的例子!");//调用初始化函数myinit();//设定窗口大小变化的回调函数auxReshapeFunc(myReshape);//设定移动视点的回调函数auxKeyFunc('A',MoveNear); //按A键变大auxKeyFunc('a',MoveFar); //按a键变小//使display函数一直被调用auxIdleFunc(display);//开始OpenGL的循环auxMainLoop(display);//结束程序return (0);}其运行结果如图所示:(2)OPENGL绘制矩形的简单例子参考程序:#include <gl/glut.h>void Initial(void){glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //设置窗口背景颜色为白色glMatrixMode(GL_PROJECTION);//设置投影参数gluOrtho2D(0.0,200.0,0.0,150.0);}void Display(void){glClear(GL_COLOR_BUFFER_BIT); //用当前背景色填充窗口glColor3f(1.0f, 0.0f, 0.0f); //设置当前的绘图颜色为红色glRectf(50.0f, 100.0f, 150.0f, 50.0f); //绘制一个矩形glFlush(); //处理所有的OpenGL程序}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //初始化窗口的显示模式glutInitWindowSize(400,300);//设置窗口的尺寸glutInitWindowPosition(100,120);//设置窗口的位置glutCreateWindow("矩形"); //创建一个名为矩形的窗口glutDisplayFunc(Display);//设置当前窗口的显示回调函数Initial();//完成窗口初始化glutMainLoop();//启动主GLUT事件处理循环return 0;}三、实验结果分析实验二直线生成算法与用户接口与交互式技术一、实验目的1、掌握直线生成算法(1)DDA算法(2)Bresenham算法2、掌握交互式技术(1)鼠标(2)键盘数字键、字母键、功能键和特殊键3、实现拾取操作二、实验内容1、以下给出了DDA算法的C++代码,请参考用Visual C++实现Bresenham算法。
计算机图形学 实验一直线生成算法报告
实验一直线生成算法一、实验目的及要求:1.学习C语言的基本绘图方法;2. 实习直线基本生成算法;3.了解光栅图形显示器的工作原理和特点;4.掌握课本所介绍的图形算法的原理和实现。
5. 基于光栅图形显示器,在c环境中使用基本图形生成算法画根粗细不同的直线。
1.)写出完整的DDA画线算法程序,使其可以画任意直线;2.)写出完整的中点画线算法程序,使其可以画任意直线;3.)写出完整的Breaenham画线程序,使其可以画任意直线;二、理论基础:1、DDA算法:实现的关键是如何步进和步进的方向:步进的正或负,决定能否正确的到达终点。
步进的大小:它控制了变化最大的步进,令其为单位步进,而另一个方向的步进必小于1 ,这样不论斜率|m|≤1否,都会使直线的亮度均匀。
依公式:则下一点坐标为:2、中点画法:假设x坐标为xp的各像素点中,与直线最近者已确定,为(xp,yp)。
那么,下一个与直线最近的像素只能是正右方的P1(xp+1,yp)或右上方的P2(xp+1,yp+1)两者之一。
再以M表示P1与P2的中点,即M=(xp+1,yp+0.5)。
又设Q是理想直线与垂直线x=xp+1的交点。
若M在Q的下方,则P2离直线近,应取为下一个像素;否则应取P1。
3、Bresenham算法:假设我们需要由 (x0, y0) 这一点,绘画一直线至右下角的另一点(x1, y1),x,y分别代表其水平及垂直座标。
在此我们使用电脑系统常用的座标系,即x座标值沿x轴向右增长,y座标值沿y轴向下增长。
因此x及y之值分别向右及向下增加,而两点之水平距离为x1 − x0且垂直距离为y1-y0。
由此得之,该线的斜率必定介乎于1至0之间。
而此算法之目的,就是找出在x0与x1之间,第x行相对应的第y列,从而得出一像素点,使得该像素点的位置最接近原本的线。
三、算法设计与分析:1、DDA算法:(1)已知过端点P0 (x0, y0), P1(x1, y1)的直线段L :y=kx+b(2)直线斜率为 :k=(y1-y0)/(x1-x0)(3)Xi+1=Xi+ε*ΔXYi+1=Yi+ε*ΔY 其中,ε=1/max(|ΔX|,|ΔY|)max(|ΔX|,|ΔY|)= |ΔX| (|k|<=1)|ΔY| (|k|>1)(4)|k|<=1时:Xi+1=Xi+(或-)1Yi+1=Yi+(或-)k|k|>1时:Xi+1=Xi+(或-)1/kYi+1=Yi+(或-)1这种方法直观,但效率太低,因为每一步需要一次浮点乘法和一次舍入运算。
《计算机图形学》课内实验报告(实验一)
PFNGLUNIFORM1FARBPROC glUniform1fARB;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
#ifndef __APPLE__
PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f;
{
GLbyte infoLog[MAX_INFO_LOG_SIZE];
glGetInfoLogARB(progObj, MAX_INFO_LOG_SIZE, NULL, infoLog);
fprintf(stderr, "Error in program linkage!\n");
fprintf(stderr, "Info log: %s\n", infoLog);
// Demonstrates high-level shaders
// Program by Benjamin Lipchak
#include "../../Common/OpenGLSB.h" // System and OpenGL Stuff
#include "../../Common/GLTools.h" // System and OpenGL Stuff
// Initially set the blink parameter to 1 (no flicker)
if (flickerLocation != -1)
glUniform1fARB(flickerLocation,1.0f);
// Program object has changed, so we should revalidate
计算机图形学作业实验报告
计算机图形学实验报告班级:学号:姓名:指导教师:完成日期:实验一:多边形填充一、实验目的了解多边形属性,熟悉相关函数的调用。
二、实验内容步骤和实现:首先进行初始化工作,进行显示模式(单缓冲区)和窗口等设定,主要实现根据两个函数,一个是指定场景绘制函数,glutDisplayFunc(Paint),paint函数中设置了两个三角形,一个填充,一个不填充。
用到了启用多边形点画模式glEnable(GL_POL YGON_STIPPLE)的函数,和指定多边形点画模式(填充) glPolygonStipple(fly)的函数。
另外一个就是循环执行OpenGl命令的glutMainLoop()函数。
三、实验结果四、源程序// POL Y_STIPPLE.C#include <gl/glut.h>void makeObject() // 定义一个三角形{ glBegin(GL_TRIANGLES); // 开始定义三角形// 按逆时针方向指定三角形的顶点坐标glVertex2f(-0.95, -0.95);glVertex2f(0.95, -0.95);glVertex2f(0, 0.95);glEnd(); // 三角形定义结束}void display(){ GLsizei w = glutGet(GLUT_WINDOW_WIDTH); // 程序窗口宽度GLsizei h = glutGet(GLUT_WINDOW_HEIGHT); // 程序窗口高度GLubyte fly[] = // 第二个三角形点画模式的mask值{ 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, // 0X03, 0X80, 0X01, 0XC0, 0X06, 0XC0, 0X03, 0X60, //0X04, 0X60, 0X06, 0X20, 0X04, 0X30, 0X0C, 0X20, //0X04, 0X18, 0X18, 0X20, 0X04, 0X0C, 0X30, 0X20, //0X04, 0X06, 0X60, 0X20, 0X44, 0X03, 0XC0, 0X22, //0X44, 0X01, 0X80, 0X22, 0X44, 0X01, 0X80, 0X22, //0X44, 0X01, 0X80, 0X22, 0X44, 0X01, 0X80, 0X22, //0X44, 0X01, 0X80, 0X22, 0X44, 0X01, 0X80, 0X22, //0X66, 0X01, 0X80, 0X66, 0X33, 0X01, 0X80, 0XCC, //0X19, 0X81, 0X81, 0X98, 0X0C, 0XC1, 0X83, 0X30, //0X07, 0XE1, 0X87, 0XE0, 0X03, 0X3F, 0XFC, 0XC0, //0X03, 0X31, 0X8C, 0XC0, 0X03, 0X33, 0XCC, 0XC0, //0X06, 0X64, 0X26, 0X60, 0X0C, 0XCC, 0X33, 0X30, //0X18, 0XCC, 0X33, 0X18, 0X10, 0XC4, 0X23, 0X08, //0X10, 0X63, 0XC6, 0X08, 0X10, 0X30, 0X0C, 0X08, //0X10, 0X18, 0X18, 0X08, 0X10, 0X00, 0X00, 0X08 };glClear(GL_COLOR_BUFFER_BIT); // 清除颜色缓冲区glViewport(0, 0, w / 2, h); // 第一个视口,显示第一个三角形glColor3f(1, 1, 1); // 设置颜色,白色,默认值makeObject(); // 第一个三角形glViewport(w / 2, 0, w / 2, h); // 第二个视口,显示第二个三角形glColor3f(1, 0, 0); // 设置颜色,红色glEnable(GL_POL YGON_STIPPLE); // 启用多边形点画模式glPolygonStipple(fly); // 指定多边形点画模式(填充)makeObject(); // 第二个三角形glDisable(GL_POL YGON_STIPPLE); // 关闭多边形点画模式glFlush(); // 强制OpenGL命令序列在有限的时间内完成执行}int main(){ glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);// 设置程序窗口的显示模式(单缓冲区、RGBA颜色模型)glutInitWindowPosition(100, 100); // 程序窗口的位置glutInitWindowSize(300, 150); // 程序窗口的大小glutCreateWindow("一个填充多边形的例子!"); // 窗口的标题glutDisplayFunc(display); // 指定场景绘制函数glutMainLoop(); // 开始循环执行OpenGL命令}实验二:基本图元绘制二、实验目的了解OpenGL图形软件包绘制图形的基本过程及其程序框架,并在已有的程序框架中添加代码实现直线和圆的生成算法,演示直线和圆的生成过程,从而加深对直线和圆等基本图形生成算法的理解。
计算机图形学实验报告(一).doc
实验一OpenGL开发环境及扫描转换算法1、实验目的与要求1.通过实验掌握OpenGL中编程环境的设置,了解相关函数用途及设置步骤;2.通过实验掌握基本图形元素的生成,给出相关代码和运行结果;3.用WINDOWS GDI函数编写生成直线或区域填充的程序(选DDA或Bresenham直线算法,活性边表算法填充多边形),演示算法过程。
4.画矩形,调用一个函数画一个矩形。
画椭圆,调用一个函数画一个椭圆。
画Bezier 曲线。
2、实验方案请描述为达到实验的需要完成哪些方面的实验,列举出实验的基本要点和重点。
在工程WinAPIEX加入void createLine(HDC tmpDC)和void Polyline (tmpDC)在void createLine(HDC tmpDC)用DDA直线算法或Bresenham直线算法生成直线在void Polyline (tmpDC)添加活泩边表填充算法,生成填充四边形和八边形加入Rectangle(tmpDC,x0,y0,x1,y1);加入Ellipse (tmpDC, x0,y0,a,b) ;加入PolyBezier(tmpDC,arr_vertex,4) ;3、实验结果和数据处理1)生成直线的DDA直线算法在createLine(tmpDC)中加入以下代码int x0,y0,x1,y1,color; //自定义直线的起点(x0,y0)和终点(x1,y1),及颜色colorfloat dx,dy,x,y;int length,i;x0=50;y0=160;x1=900;y1=200;//此处修改了color=1000; color=1;if(abs(x1-x0)>=abs(y1-y0))length=abs(x1-x0);elselength=abs(y1-y0);dx=(x1-x0)/(float)length;dy=(y1-y0)/(float)length;i=1;x=(float)x0;y=(float)y0;while(i<=length){SetPixel(tmpDC,int(x+0.5),int(y+0.5),color);x+=dx;y+=dy;i++;}2)区域填充的程序在void Polyline (tmpDC) 添加活性边表填充void Polyline (HDC tmpDC) //多边形边数.{const int POINTNUM=4;//或者是八边形8/******定义结构体用于活性边表AET和新边表NET***************************** ******/typedef struct XET{float x;float dx,ymax;XET* next;}AET,NET;/******定义点结构体point**************************** **************************/struct point{float x;float y;}polypoint[POINTNUM]={100,10 0,400,100,400,400,100,400};//正方形//polypoint[POINTNUM]={600,10 0,700,100,800,200,800,300,700,400,600, 400,500,300,500,200};//八边形顶点/******计算最高点的y坐标(扫描到此结束)****************************** **********/int MaxY=0;int i;for(i=0;i<POINTNUM;i++)if(polypoint[i].y>MaxY) MaxY=(int)polypoint[i].y;/*******初始化AET表********************************* **************************/AET *pAET=new AET;pAET->next=NULL;/******初始化NET表********************************* ***************************/NET *pNET[1024];for(i=0;i<=MaxY;i++){pNET[i]=new NET;pNET[i]->next=NULL;}/******扫描并建立NET表********************************* ************************/for(i=0;i<=MaxY;i++){for(intj=0;j<POINTNUM;j++)if(polypoint[j].y==i){if(polypoint[(j-1+POINTNUM)%POINT NUM].y>polypoint[j].y){NET*p=new NET;p->x=polypoint[j].x;p->ymax=polypoint[(j-1+POINTNUM) %POINTNUM].y;p->dx=(polypoint[(j-1+POINTNUM)%P OINTNUM].x-polypoint[j].x)/(polypoint [(j-1+POINTNUM)%POINTNUM].y-po lypoint[j].y);p->next=pNET[i]->next;pNET[i]->next=p;}if(polypoint[(j+1+POINTNUM)%POIN TNUM].y>polypoint[j].y){NET*p=new NET;p->x=polypoint[j].x;p->ymax=polypoint[(j+1+POINTNUM) %POINTNUM].y;p->dx=(polypoint[(j+1+POINTNUM)% POINTNUM].x-polypoint[j].x)/(polypoint[(j+1+POINTNUM)%POINTNUM].y-polypoint[j].y);p->next=pNET[i]->next;pNET[i]->next=p;}}}/******建立并更新活性边表AET***************************** ************************/for(i=0;i<=MaxY;i++){//计算新的交点x,更新AET***************************** ***************************/NET *p=pAET->next;while(p){p->x=p->x + p->dx;p=p->next;}//更新后新AET先排序********************************* ****************************///断表排序,不再开辟空间AET *tq=pAET;p=pAET->next;tq->next=NULL;while(p){while(tq->next && p->x >= tq->next->x)tq=tq->next;NET *s=p->next;p->next=tq->next;tq->next=p;p=s;tq=pAET;}//(改进算法)先从AET表中删除ymax==i的结点********************************* *******/AET *q=pAET;p=q->next;while(p){if(p->ymax==i){q->next=p->next;delete p;p=q->next;}else{q=q->next;p=q->next;}}//将NET中的新点加入AET,并用插入法按X值递增排序********************************* */p=pNET[i]->next;q=pAET;while(p){while(q->next && p->x >= q->next->x)q=q->next;NET *s=p->next;p->next=q->next;q->next=p;p=s;q=pAET;}/******配对填充颜色********************************* ******************************/p=pAET->next;while(p && p->next){for(floatj=p->x;j<=p->next->x;j++){SetPixel(tmpDC,static_cast<int>(j),i,RG B(255,200,0));//此处我改变了颜色,八边形的为黄色//SetPixel(tmpDC,static_cast<int>(j),i,RG B(255,0,0));//还有四边形的红色}p=p->next->next;//考虑端点情况}} }//画矩形Rectangle(tmpDC,20,20,80,80); //左上顶点,右下顶点//画椭圆Ellipse (tmpDC, 20,20,160,360) ;//画Bezier 曲线,利用已有的顶点数据PolyBezier(tmpDC,arr_vertex,4) ;实验截图:1.DDA算法的直线2.四边形和八边形3.正方形4.椭行5.Bezier 曲线实习总结:通过本次实验,我掌握了opengl绘图的一些基本知识,会在vc里面加入opengl的基本库。
计算机图形学实验1报告
设计和实现一个图形函数库一、实验要求设计和实现一个图形函数库,具有绘制直线段、任意圆弧、椭圆弧、多边形区域的阴影填充和颜色填充等功能。
(仅调用画点函数)Windows API:setpixel(hdc,x,y,color)二、实验平台编程环境:Visual Studio 2008编程语言:C#操作系统:Windows 7三、实验目的在理解画直线段,圆弧,椭圆,多边形的画法,以及阴影填充和颜色填充算法的基础上,编程实现出一个简单的画图工具,加深对个算法的理解。
四、算法基本原理1、画直线段(1)算法思想本程序采用Bresenham直线算法,基本思想为:(以斜率在0~1之间的直线段为例)这种情况下,选择X方向为计长方向,即增量dx=1。
如图3。
2所示,设P i (x i,y i)是已选定的离直线最近的像素, 现在要决定P i+1是T还是S。
显然,若d〈0.5, 则S比较靠近直线, 应选S;若d〉=0.5, 则应选T。
(m= △y/△x)令e=d-0.5(初值为—0。
5), 即有:e 〈0时,选P i+1(x i+1, y i), 更新e=e+m;e >=0时, 选P i+1(x i+1,y i+1),更新e=e+m—1;2、画圆弧(1)算法思想本程序采用Bresenham圆弧算法,基本思想为:与Bresenham直线生成算法一样,其基本方法是从一个起点出发,利用判别式选择下一个显示点。
判别式的值通过简单计算获得,其符号用作判断。
此算法在每一步都选择一个离开理想圆周最近的点P i(x i, y i), 使其误差项|D(P i)|=|x i2+y i2—R2|在每一步都是极小值。
设P i—1(x i—1, y i-1)已被选定为最靠近圆弧的点,下一步x=x i-1+1时,要决定T还是S更接近理想的圆弧,令D(S)=(x i—1+1)2+ (y i—1)2 -R2D(T)=(x i-1+1)2+ (y i—1—1)2-R2显然, |D(S)|>=|D(T)|时, 应该取T点; 反之则取S点(2)算法流程(3)实现效果3、画椭圆弧(1)算法思想椭圆生成算法与圆形生成算法类似,都是先生成八分之一圆弧,然后根据对称原则生成图形,所不同的是椭圆有长轴和短轴之分,故需要提前求出45°方向椭圆焦点的坐标.然后再根据公式进行画点。
计算机图形学划线实验报告
计算机图形学划线实验报告《计算机图形学》实验报告实验⼀直线、圆(弧)⽣成算法⼀、实验⽬的及要求1. 了解光栅图形显⽰器的⼯作原理和特点;2. 学习C/VC环境下的基本绘图⽅法;3. 实践与巩固直线的基本⽣成算法。
4. 掌握直线扫描转换算法的原理及实现;5. 学习圆(弧)的基本⽣成算法;6. 实践圆(弧)的基本⽣成算法;7. 掌握圆弧扫描转换算法的原理及实现;⼆、理论基础1、有关直线⽣成算法有DDA(数值微分)、中点画线线算法、Bresenham⽣成算法数值微分法先算出直线的斜率,然后从起点开始,确定最佳逼近于直线的y坐标。
假设起点的坐标为整数。
让x递增1,y相应递增k。
中点划线算法中若直线在x⽅向增加⼀个单位,y的增量只能在0、1之间。
假设当前像素点已经确定,下⼀像素点就只可能有两种情况,将这两点的中点带⼊直线⽅程中,通过中点在直线的上、下⽅来判断下⼀点的坐标。
Bresenham算法是通过各⾏、各列像素中⼼构造⼀组虚拟⽹络格线,按直线从起点到中点的顺序计算直线与各垂直⽹格线的交点,然后确定该列像素中与此交点最近的像素。
2、有关画圆的算法圆的扫描转换(中点画圆法)、Bresenham画圆算法圆的扫描转换算法同中点画线类似,将圆分为8份,先讨论圆的第⼀象限上半部分,从(0,R)点顺时针确定最佳逼近于该圆弧的像素序列。
之后通过对称画出全部圆。
Bresenham画圆算法考虑圆在第⼀象限上的点,每确定⼀像素,则下⼀像素有三种可能,通过判断右下⽅的像素与圆的位置关系再分为三种情况,之后通过这三个点与圆的距离远近确定最佳逼近像素。
三、算法设计与分析1、数值微分法int x0=0,y0=0,x1=800,y1=400; //数值微分法,|k|<=1float dx,dy,k,x,y;dx=x1-x0;dy=y1-y0;k=dy/dx;y=y0;for(x=x0;x<=x1;x++){pDC->SetPixel(x,int(y+0.5),color);y=y+k;}该程序中每⼀步的x、y值是⽤前⼀步的值加上⼀个增量来获得的。
计算机图形学实验报告
实验一 3D模型的加载、渲染与三维操作学院:专业班级:指导老师:学号:姓名:完成日期:目录一、实验目的 (3)二、使用的工具软件及环境 (3)三、实验内容 (3)四、实验步骤 (3)五、思考 (12)一、实验目的1、掌握在Microsoft Visual Studio环境中使用OpenGL、GLUT和GLUI;2、了解计算机图形学固定流水线;3、了解OpenGL编程基础;4、掌握三维观察的数学表达和程序实现;5、掌握多边形网格的绘制;二、使用的工具软件及环境Microsoft Visual Studio 2010、OpenGL、Glut、Glui三、实验内容1、在VS 2010中配置OpenGL环境;2、编译简单的GLUT程序;3、编译GLUI源代码,并在调试模式下执行6个示例程序;4、在给定的工程中添加绘制简单几何体的代码;5、在给定的工程中添加读取、绘制三维模型的代码;6、在给定的工程中添加旋转、平移和缩放的控制代码;四、实验步骤1、安装Microsoft Visual Studio软件版本选择:Microsoft Visual Studio 2010以上版本2、VS2010中配置GLUT1)下载GLUT。
Windows环境下的GLUT下载地址:/resources/libraries/glut/glutdlls37beta.zip2)将下载的压缩包解开,将得到5个文件:glut.h、glut.lib、glut32.lib、glut.dll、glut32.dll。
3)将glut.h放到"%WinDir%\ProgramFiles(x86)\Microsoft SDKs\Windows\v7.0A\Include\gl\"文件夹中。
4)将glut.lib和glut32.lib放到"%WinDir%\ProgramFiles(x86)\Microsoft Visual Studio 10.0\VC\lib\"文件夹中。
计算机图形学实验一
计算机图形学实验一文档编制序号:[KKIDT-LLE0828-LLETD298-POI08]实验一二维基本图元的生成与填充实验目的1.了解并掌握二维基本图元的生成算法与填充算法。
2.实现直线生成的DDA算法、中点算法和Bresenham算法。
3.实现圆和椭圆生成的DDA和中点算法, 对几种算法的优缺点有感性认识。
二.实验内容和要求1.选择自己熟悉的任何编程语言, 建议使用VC++。
2.创建良好的用户界面,包括菜单,参数输入区域和图形显示区域。
3.实现生成直线的DDA算法、中点算法和Bresenham算法。
4.实现圆弧生成的中点算法。
5.实现多边形生成的常用算法, 如扫描线算法,边缘填充算法。
6.实现一般连通区域的基于扫描线的种子填充算法。
7.将生成算法以菜单或按钮形式集成到用户界面上。
8.直线与圆的坐标参数可以用鼠标或键盘输入。
6. 可以实现任何情形的直线和圆的生成。
实验报告1.用户界面的设计思想和框图。
2.各种实现算法的算法思想。
3.算法验证例子。
4.上交源程序。
直线生成程序设计的步骤如下:为编程实现上述算法,本程序利用最基本的绘制元素(如点、直线等),绘制图形。
如图1-1所示,为程序运行主界面,通过选择菜单及下拉菜单的各功能项分别完成各种对应算法的图形绘制。
图1-1 基本图形生成的程序运行界面2.创建工程名称为“基本图形的生成”单文档应用程序框架(1)启动VC,选择“文件”|“新建”菜单命令,并在弹出的新建对话框中单击“工程”标签。
(2)选择MFC AppWizard(exe),在“工程名称”编辑框中输入 “基本图形的生成”作为工程名称,单击“确定”按钮,出现Step 1对话框。
(3)选择“单个文档”选项,单击“下一个”按钮,出现Step 2对话框。
(4)接受默认选项,单击“下一个”按钮,在出现的Step 3~Step 5对话框中,接受默认选项,单击“下一个”按钮。
(5)在Step 6对话框中单击“完成”按钮,即完成“基本图形的生成”应用程序的所有选项,随后出现工程信息对话框(记录以上步骤各选项选择情况),如图1-2所示,单击“确定”按钮,完成应用程序框架的创建。
计算机图形学实验1报告
设计和实现一个图形函数库一、实验要求设计和实现一个图形函数库,具有绘制直线段、任意圆弧、椭圆弧、多边形区域的阴影填充和颜色填充等功能。
(仅调用画点函数)Windows API: setpixel(hdc,x,y,color)二、实验平台编程环境:Visual Studio 2008编程语言:C#操作系统:Windows 7三、实验目的在理解画直线段,圆弧,椭圆,多边形的画法,以及阴影填充和颜色填充算法的基础上,编程实现出一个简单的画图工具,加深对个算法的理解。
四、算法基本原理1、画直线段(1)算法思想本程序采用Bresenham直线算法,基本思想为:(以斜率在0~1之间的直线段为例)这种情况下, 选择X方向为计长方向,即增量dx=1。
如图3.2所示,设P i (x i,y i)是已选定的离直线最近的像素, 现在要决定P i+1是T还是S。
显然, 若d<0.5, 则S比较靠近直线, 应选S;若d>=0.5, 则应选T。
(m= △y/△x)令e=d-0.5(初值为-0.5), 即有:e <0时, 选P i+1(x i+1, y i), 更新e=e+m;e >=0时, 选P i+1(x i+1, y i+1), 更新e=e+m-1;2、画圆弧(1)算法思想本程序采用Bresenham圆弧算法,基本思想为:与Bresenham直线生成算法一样, 其基本方法是从一个起点出发, 利用判别式选择下一个显示点。
判别式的值通过简单计算获得, 其符号用作判断。
此算法在每一步都选择一个离开理想圆周最近的点P i(x i, y i), 使其误差项|D(P i)|=|x i2+y i2-R2|在每一步都是极小值。
设P i-1(x i-1, y i-1)已被选定为最靠近圆弧的点,下一步x=x i-1+1时, 要决定T还是S更接近理想的圆弧,令D(S)=(x i-1+1)2+ (y i-1)2 -R2D(T)=(x i-1+1)2+ (y i-1-1)2-R2显然, |D(S)|>=|D(T)|时, 应该取T点; 反之则取S点3、画椭圆弧(1)算法思想椭圆生成算法与圆形生成算法类似,都是先生成八分之一圆弧,然后根据对称原则生成图形,所不同的是椭圆有长轴和短轴之分,故需要提前求出45°方向椭圆焦点的坐标。
计算机图形学OpenGL实验一
实验报告
学院(系)名称:\
姓名
学号
专业
班级
实验项目
实验一:绘制基本图形
课程名称
计算机图形学
课程代码
实验时间
实验地点
批改意见
成绩
教师签字:
一、实验目的
1.理解图形元素显示的基本原理,掌握扫描转换直线段的常用算法原理,扫描转换圆弧的常用算法原理。
2.分别实现港口起重机、工程车、等设备的绘制。
3.颜色的设置要合适,且易于更换。
#include <math.h>
#include <gl/glut.h>
int SCREEN_HEIGHT = 480;//屏幕高度
//跟踪鼠标点击次数,达到3次后绘制Bezier曲线
int NUMPOINTS = 0;
Point POld = abc[0];
//绘制Bezier曲线段,控制t的增量可以控制曲线精度
for(double t = 0.0;t <= 1.0; t += 0.1) {
Point P = drawBezier(abc[0], abc[1], abc[2], t);
drawLine(POld, P);
2.熟悉glut常用几个功能函数
3.熟悉glut的函数回调机制
4.掌握绘制不同大小和颜色的点的方法
5.掌握绘制不同线型和颜色的直线的方法(直线,折线,环线)
6.掌握绘制彩色多边形边框的方法(各种设备)
7.熟悉OpenGL的编程环境(OpenGL+GlUT/SDK/MFC+C++)
计算机图形学实验(全)
计算机图形学实验(全)实验1 直线的绘制实验目的1、通过实验,进一步理解和掌握DDA和Bresenham算法;2、掌握以上算法生成直线段的基本过程;3、通过编程,会在TC环境下完成用DDA或中点算法实现直线段的绘制。
实验环境计算机、Turbo C或其他C语言程序设计环境实验学时2学时,必做实验。
实验内容用DDA算法或Besenham算法实现斜率k在0和1之间的直线段的绘制。
实验步骤1、算法、原理清晰,有详细的设计步骤;2、依据算法、步骤或程序流程图,用C语言编写源程序;3、编辑源程序并进行调试;4、进行运行测试,并结合情况进行调整;5、对运行结果进行保存与分析;6、把源程序以文件的形式提交;7、按格式书写实验报告。
实验代码:DDA:# include abs(dy))epsl=abs(dx);elseepsl=abs(dy);xIncre=(float)dx/(float)epsl;yIncre=(float)dy/(float)epsl;for(k=0;k#includevoid BresenhamLine(int x0,int y0,int x1,int y1,int color) {int x,y,dx,dy,e;dx=x1-x0;dy=y1-y0;e=-dx;x=x0;y=y0;while(x0){y++;e=e-2*dx;}}}main(){int gdriver ,gmode ; gdriver = DETECT;initgraph( BresenhamLine(0, 0 , 120, 200,5 );getch ( );closegraph ( );}实验2 圆和椭圆的绘制实验目的1、通过实验,进一步理解和掌握中点算法;2、掌握以上算法生成椭圆或圆的基本过程;3、通过编程,会在TC环境下完成用中点算法实现椭圆或圆的绘制。
实验环境计算机、Turbo C或其他C语言程序设计环境实验学时2学时,必做实验。
计算机图形学实验[1]
2013-7-24
23
Computer Graphics
College of Computer Science and Technology
三.鼠标消息函数的应用:
2013-7-24
45
Computer Graphics
College of Computer Science and Technology
{ CPaintDC dc(this);
}
2013-7-24 17
Computer Graphics
College of Computer Science and Technology
CPaintDC dc(this);创建一个名为dc的设 备环境对象,而this指向当前的对话框。这样 就可以在对话框画图了。 注意:由于视图类窗口也是窗口的一类,所以 视图窗口要绘制时,也收到WM_PAINT 的消 息,但是当CView的派生类没有OnPaint函数 消 息 处 理 函 数 时 , 将 执 行 CView 提 供 的 OnPaint函数,生成和准备设备环境对象,然 后将对象传入OnDraw函数。只有不从视图类 派生的窗口类才需要提供自己的OnPaint函数 做各种窗口绘图工作。
OnPrint(&dc); } }
2013-7-24
19
Computer Graphics
College of Computer Science and Technology
③.CClientDC 这个设备环境对象仅仅代表了 当前窗口区域。它的构造函数调用GetDC函数, 它的析构函数调用ReleaseDC 函数。 对于在OnDraw和OnPaint消息处理函数之外 的函数中显示图形,必须生成CClientDC类成 员的设备环境对象。
计算机图形学实验报告
实验一:二维图形的绘制和变换一、实验目的掌握基本的图形学算法,熟悉VC下图形学的编程,初步了解并使用OpenGL 绘制图形。
二、实验内容二维图形的绘制和变换,绘制包括直线、三角形、矩形,变换包括平移、旋转、缩放。
三、实验原理二维图形的绘制和变换:在图形系统中,矩阵是实现变换的标准方法。
平移变换、旋转变换和缩放变换的矩阵表示形式如下。
平移变换:P’=P+T。
旋转变换:P’=R*P。
缩放变换:P’=S*P。
引入齐次坐标后,平移、旋转和缩放变换的矩阵表示形式如下所示。
(1)平移变换:[1 0 0][x’, y’, 1] = [x, y, 1] [0 1 0][tx ty 1](2)旋转变换:[cosɵsinɵ0][x’, y’, 1] = [x, y, 1] [-sinɵcosɵ0][0 0 1](3)缩放变换:[s x0 0][x’, y’, 1] = [x, y, 1] [0 s y0][0 0 1]四、实验代码及结果1.编写对一个三角形分别实现平移、缩放、旋转等变化的源码及效果图。
实验核心代码void display(void){glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glLoadIdentity ();glColor3f (1.0, 1.0, 1.0);glTranslatef(-100.0,-50.0,1.0);draw_triangle ();glLoadIdentity ();glTranslatef (0.0, 100.0, 1.0);draw_triangle ();glLoadIdentity ();glRotatef (90.0, 0.0, 0.0, 1.0);draw_triangle ();glLoadIdentity ();glScalef (0.5, 0.5, 1.0);draw_triangle ();glFlush ();}2. 实现如图功能#include<windows.h>#include <GL/glut.h>#include <stdlib.h>void init(void){glClearColor (0.0, 0.0, 0.0, 0.0);glShadeModel (GL_SMOOTH); }void draw_triangle(void){glShadeModel(GL_SMOOTH);glColor3f(0.2,0.7,0.30);glBegin (GL_TRIANGLES);//画出三角形,为混合色填充方式glVertex2f(50.0, 25.0);glColor3f(0.4,0.5,0.60);glVertex2f(150.0, 25.0);glColor3f(0.9,0.7,0.8);glVertex2f(100.0, 100.0);glEnd();}void display(void){glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glLoadIdentity ();glColor3f (1.0, 1.0, 1.0);glTranslatef(-100.0,-50.0,1.0);draw_triangle ();glLoadIdentity ();glTranslatef (0.0, 100.0, 1.0);glRotatef (90.0, 0.0, 0.0, 1.0);glScalef (0.5, 0.5, 1.0);draw_triangle ();//经过三种变换后画出图形glFlush ();}void reshape (int w, int h){glViewport (0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode (GL_PROJECTION);glLoadIdentity ();if (w <= h)gluOrtho2D (-200.0, 250.0, -100.0*(GLfloat)h/(GLfloat)w,200.0*(GLfloat)h/(GLfloat)w);//调整裁剪窗口elsegluOrtho2D (-200.0*(GLfloat)w/(GLfloat)h,250.0*(GLfloat)w/(GLfloat)h, -50.0, 200.0);glMatrixMode(GL_MODELVIEW);int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);glutInitWindowSize (600, 600);glutInitWindowPosition (100, 100);glutCreateWindow (argv[0]);init ();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoop();return 0;}实验二:使用中点扫描算法绘制直线和圆一、实验目的掌握基本的图形学算法,熟悉VC下图形学的编程,初步了解并使用OpenGL 绘制图形。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一二维基本图元的生成与填充实验目的1.了解并掌握二维基本图元的生成算法与填充算法。
2.实现直线生成的DDA算法、中点算法和Bresenham算法。
3.实现圆和椭圆生成的DDA和中点算法, 对几种算法的优缺点有感性认识。
二.实验内容和要求1.选择自己熟悉的任何编程语言, 建议使用VC++6.0。
2.创建良好的用户界面,包括菜单,参数输入区域和图形显示区域。
3.实现生成直线的DDA算法、中点算法和Bresenham算法。
4.实现圆弧生成的中点算法。
5.实现多边形生成的常用算法, 如扫描线算法,边缘填充算法。
6.实现一般连通区域的基于扫描线的种子填充算法。
7.将生成算法以菜单或按钮形式集成到用户界面上。
8.直线与圆的坐标参数可以用鼠标或键盘输入。
6. 可以实现任何情形的直线和圆的生成。
实验报告1.用户界面的设计思想和框图。
2.各种实现算法的算法思想。
3.算法验证例子。
4.上交源程序。
直线生成程序设计的步骤如下:为编程实现上述算法,本程序利用最基本的绘制元素(如点、直线等),绘制图形。
如图1-1所示,为程序运行主界面,通过选择菜单及下拉菜单的各功能项分别完成各种对应算法的图形绘制。
图1-1 基本图形生成的程序运行界面2.创建工程名称为“基本图形的生成”单文档应用程序框架(1)启动VC,选择“文件”|“新建”菜单命令,并在弹出的新建对话框中单击“工程”标签。
(2)选择MFC AppWizard(exe),在“工程名称”编辑框中输入“基本图形的生成”作为工程名称,单击“确定”按钮,出现Step 1对话框。
(3)选择“单个文档”选项,单击“下一个”按钮,出现Step 2对话框。
(4)接受默认选项,单击“下一个”按钮,在出现的Step 3~Step 5对话框中,接受默认选项,单击“下一个”按钮。
(5)在Step 6对话框中单击“完成”按钮,即完成“基本图形的生成”应用程序的所有选项,随后出现工程信息对话框(记录以上步骤各选项选择情况),如图1-2所示,单击“确定”按钮,完成应用程序框架的创建。
图1-2 信息程序基本3.编辑菜单资源设计如图1-1所示的菜单项。
在工作区的ResourceView标签中,单击Menu项左边“+”,然后双击其子项IDR_MAINFRAME,并根据表1-1中的定义编辑菜单资源。
此时VC已自动建好程序框架,如图1-2所示。
表1-1菜单资源表菜单标题菜单项标题标示符ID直线DDA算法生成直线ID_DDALINE Bresenham算法生成直线ID_BRESENHAMLINE 中点算法生成直线ID_MIDPOINTLINE4.添加消息处理函数利用ClassWizard(建立类向导)为应用程序添加与菜单项相关的消息处理函数,ClassName栏中选择CMyView,根据表1-2建立如下的消息映射函数,ClassWizard会自动完成有关的函数声明。
表1-2菜单项的消息处理函数菜单项ID消息消息处理函数ID_DDALINE CONMMAN OnDdalineID_MIDPOINTLINE CONMMAN OnMidpointlineID_BRESENHAMLINE CONMMAN OnBresenhamline5.程序结构代码,在CMyView.cpp文件中相应位置添加如下代码:// DDA算法生成直线void CMyView:: OnDdaline(){CDC* pDC=GetDC();//获得设备指针int xa=100,ya=300,xb=300,yb=200,c=RGB(255,0,0);//定义直线的两端点,直线颜色 int x,y;float dx, dy, k;dx=(float)(xb-xa), dy=(float)(yb-ya);k=dy/dx, y=ya;if(abs(k)<1){for (x=xa;x<=xb;x++){pDC->SetPixel (x,int(y+0.5),c);y=y+k;}}if(abs(k)>=1){for (y=ya;y<=yb;y++){pDC->SetPixel (int(x+0.5),y,c);x=x+1/k;}}ReleaseDC(pDC);}说明:(1)以上代码理论上通过定义直线的两端点,可得到任意端点之间的一直线,但由于一般屏幕坐标采用右手系坐标,屏幕上只有正的x, y值,屏幕坐标与窗口坐标之间转换知识请参考第3章。
(2)注意上述程序考虑到当k 1的情形x每增加1,y最多增加1;当k>1时,y每增加1,x相应增加1/k。
在这个算法中,y与k用浮点数表示,而且每一步都要对y进行四舍五入后取整。
//中点算法生成直线void CMyView::OnMidpointline(){CDC* pDC=GetDC();int xa=300, ya=200, xb=450, yb=300,c=RGB(0,255,0);float a, b, d1, d2, d, x, y;a=ya-yb, b=xb-xa, d=2*a+b;d1=2*a, d2=2* (a+b);x=xa, y=ya;pDC->SetPixel(x, y, c);while (x<xb){ if (d<0) {x++, y++, d+=d2; }else {x++, d+=d1;}pDC->SetPixel(x, y, c);}ReleaseDC(pDC);}说明:(1)其中d是x p, y p的线性函数。
为了提高运算效率,程序中采用增量计算。
具体算法如下:若当前像素处于d>0情况,则取正右方像素P1(x p+1, y p),判断下一个像素点的位置,应计算d1=F(x p+2, y p+0.5)=a(x p+2)+b(y p+0.5)=d+a;,其中增量为a。
若d<0时,则取右上方像素P2(x p+1, y p+1)。
再判断下一像素,则要计算d2 = F(x p+2, y p+1.5)=a(x p+2)+b(y p+1.5) + c=d+a+b,增量为a+b。
(2)画线从(x0, y0)开始,d的初值d0=F(x0+1, y0+0.5)=F(x0, y0)+a+0.5b,因F(x0, y0)=0,则d0=a+0.5b。
(3)程序中只利用d的符号,d的增量都是整数,只是初始值包含小数,用2d代替d,使程序中仅包含整数的运算。
//Bresenham算法生成直线void CMyView::OnBresenhamline(){CDC* pDC=GetDC();int x1=100, y1=200, x2=350, y2=100,c=RGB(0,0,255);int i,s1,s2,interchange;float x,y,deltax,deltay,f,temp;x=x1;y=y1;deltax=abs(x2-x1);deltay=abs(y2-y1);if(x2-x1>=0) s1=1; else s1=-1;if(y2-y1>=0) s2=1; else s2=-1;if(deltay>deltax){temp=deltax;deltax=deltay;deltay=temp;interchange=1;}else interchange=0;f=2*deltay-deltax;pDC->SetPixel(x,y,c);for(i=1;i<=deltax;i++){if(f>=0){if(interchange==1) x+=s1;else y+=s2;pDC->SetPixel(x,y,c);f=f-2*deltax;}else{if(interchange==1) y+=s2;else x+=s1;f=f+2*deltay;}}}说明:(1)以上程序已经考虑到所有象限直线的生成。
(2)Bresenham算法的优点如下:①不必计算直线的斜率,因此不做除法。
②不用浮点数,只用整数。
③只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。
④Bresenham算法的运算速度很快。
圆弧生成程序设计的步骤如下:(1)创建应用程序框架,以上面建立的单文档程序框架为基础。
(2)编辑菜单资源。
在工作区的ResourceView标签中,单击Menu项左边“+”,然后双击其子项IDR_MAINFRAME,并根据表1-3中的定义添加编辑菜单资源。
此时建好的菜单如图1-3所示。
表1-3菜单资源表菜单标题菜单项标题标示符ID圆中点画圆ID_MIDPOINTCIRCLE Bresenham画圆ID_BRESENHAMCIRCLE(3)添加消息处理函数。
利用ClassWizard(建立类向导)为应用程序添加与菜单项相关的消息处理函数,ClassName栏中选择CMyView,根据表1-4建立如下的消息映射函数,ClassWizard会自动完成有关的函数声明。
表1-4菜单项的消息处理函数菜单项ID消息消息处理函数ID_MIDPOINTCIRCLE CONMMAN OnMidpointcircleID_BRESENHAMCIRCLE CONMMAN OnBresenhamcircle(4)程序结构代码,在CMyView.cpp文件中的相应位置添加如下代码。
void CMyView::OnMidpointcircle() //中点算法绘制圆,如图1-4所示{// TODO: Add your command handler code hereCDC* pDC=GetDC();int xc=300, yc=300, r=50, c=0;int x,y;float d;x=0; y=r; d=1.25-r;pDC->SetPixel ((xc+x),(yc+y),c);pDC->SetPixel ((xc-x),(yc+y),c); pDC->SetPixel ((xc+x),(yc-y),c); pDC->SetPixel ((xc-x),(yc-y),c); pDC->SetPixel ((xc+y),(yc+x),c); pDC->SetPixel ((xc-y),(yc+x),c); pDC->SetPixel ((xc+y),(yc-x),c);图1-4 中点算法绘制圆图1-3 程序主菜单pDC->SetPixel ((xc-y),(yc-x),c);while(x<=y){ if(d<0) d+=2*x+3;else { d+=2*(x-y)+5; y--;}x++;pDC->SetPixel ((xc+x),(yc+y),c);pDC->SetPixel ((xc-x),(yc+y),c);pDC->SetPixel ((xc+x),(yc-y),c);pDC->SetPixel ((xc-x),(yc-y),c);pDC->SetPixel ((xc+y),(yc+x),c);pDC->SetPixel ((xc-y),(yc+x),c);pDC->SetPixel ((xc+y),(yc-x),c);pDC->SetPixel ((xc-y),(yc-x),c);}}void CMyView::OnBresenhamcircle() //// Bresenham算法绘制圆,如图1-5所示{CDC* pDC=GetDC();int xc=100, yc=100, radius=50, c=0;int x=0,y=radius,p=3-2*radius;while(x<y){pDC->SetPixel(xc+x, yc+y, c);pDC->SetPixel(xc-x, yc+y, c);图1-5 Bresenham算法绘制圆pDC->SetPixel(xc+x, yc-y, c);pDC->SetPixel(xc-x, yc-y, c);pDC->SetPixel(xc+y, yc+x, c);pDC->SetPixel(xc-y, yc+x, c);pDC->SetPixel(xc+y, yc-x, c);pDC->SetPixel(xc-y, yc-x, c);if (p<0)p=p+4*x+6;else{p=p+4*(x-y)+10;y-=1;}x+=1;}if(x==y)pDC->SetPixel(xc+x, yc+y, c);pDC->SetPixel(xc-x, yc+y, c);pDC->SetPixel(xc+x, yc-y, c);pDC->SetPixel(xc-x, yc-y, c);pDC->SetPixel(xc+y, yc+x, c);pDC->SetPixel(xc-y, yc+x, c);pDC->SetPixel(xc+y, yc-x, c);pDC->SetPixel(xc-y, yc-x, c);}多边形填充程序设计的步骤如下:(1)创建应用程序框架,以上述单文档程序框架为基础,创建如图1-17所示应用程序界面。