计算机图形学实验一_画直线
VS中直线的绘制—计算机图形学实验报告一
Else
k += 2 * (dy - dx)
y = y + 1
Enห้องสมุดไป่ตู้If
x = x + 1
EndWhile
Else
k = 2 * dx - dy
Whiley < y2
g.DrawEllipse(p,CInt(x),CInt(y), 1, 1)
Ifk < 0Then
k += 2 * dx
08地信
学号
200875000203
姓名
指导老师
课程名称
计算机图形学
实验题目
直线的绘制
成绩
一、实验目的:
熟练掌握绘制直线的DDA算法、中点画线算法和Bresenham画线算法。
二、实验准备:
学习绘制直线的DDA算法、中点画线算法和Bresenham画线算法,注意考虑不同斜率条件下算法的变化。
三、实验内容:
MessageBox.Show("请输入正确的坐标!", "警告!", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
x1 =CDbl(TextBox1.Text)
y1 =CDbl(TextBox2.Text)
x2 =CDbl(TextBox3.Text)
Dimx1, y1, x2, y2, dx, dy, x, y, k, a, bAsDouble
DimgAsGraphics = PictureBox1.CreateGraphics
DimpAsPen =NewPen(Color.Green, 1)
计算机图形学实验报告
图 2-3 填充线与边界的交点
将填充线与图形边界的交点按照一定顺序排序。根据进出边界的顺序,可以 算出哪些部分是显示的哪些部分是隐藏的。一般的,填充线从基数的交点进入图 形,从偶数的交点离开图形,所以只需要将排好序的交点两两分组,作端点绘制 填充线,如图 2-3 只需绘制点 1 与点 2 之间的部分和点 3 与点 4 之间的填充线。 2.6 多边形区域填充的原理
多边形区域的颜色填充可以使用漫水法填充,针对一行进行区域判断绘点。 其实可以将漫水法理解为特殊的填充线绘制,在漫水法中,填充线的斜率退化为 1,填充线的间隔退化为 0,就是截距只增加 1。
三、程序结果
绘制直线部分没有单独展示,因为在用多边形逼近法绘制椭圆和多边形填充 线绘制会大量使用,只有在直线绘制成功的前提下,才能完成多边形的绘制,在 程序中,不同斜率的直线颜色也会有区别。在这里也没有展示多边形区域的颜色 填充。
在程序中体现为横纵坐标的对换。 F.绘制斜率 m<0 的直线段
通过作 x 轴的对称线段,把斜率小于 0 的直线段转成斜率大于 0 的直线段。 随后按照斜率是否大于 1 继续判断用不用再对直线 y=x 作对称线段。最终转化为 斜率在[0,1]上直线段的绘制。
2.3 绘制圆弧的原理
圆是具有高度对称性的图元,所以可以利用对称性实现画圆算法的简化,现 在可以只考虑第一象限 y>x 的区域的部分。算法每一步都要寻找到离理想圆周最 近 的 点 ( 尽 量 保 证 到 圆 心 的 距 离 是 R ), 所 以 对 每 一 点 来 说 误 差 为 |D(Pi)|=|xi^2+yi^2-R^2|,如下图:
degree += t; xk = longaxis*cos(degree); yk = shortaxis*sin(degree); lineBres(hdc, centra_x + xi, centra_y + yi, centra_x + xk, centra_y + yk); xi = xk; yi = yk; }
计算机图形学-设计算法绘制直线与圆
信息与计算科学专业基础课ComputerReport Of course 计算机图形学课程实验报告实验题目设计算法绘制直线与圆班级姓名学号指导教师日期实验说明 试验目的: 掌握直线和圆的基本生成算法思想,并上机编程实现相应的算法。
试验地点: 教九楼401 数学系机房实验要求(Direction): 1. 每个学生单独完成;2.开发语言为TurboC 或C++,也可使用其它语言;3.请在自己的实验报告上写明姓名、学号、班级;4.每次交的实验报告内容包括:题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;5. 自己保留一份可执行程序,考试前统一检查和上交。
实验内容实验题一实验题目1).用DDA 法在屏幕上画一条具有三个像素宽的直线段L1。
要求:(1)直线段L1的两个端点坐标和画线颜色都要求可以随机输入;(2)要求输出直线段L1上的各点坐标;(3)画出直线的同时要求标明两端点坐标。
2).将课堂所讲的斜率0<K<1的中点画线算法推广到斜率K>1、-1<K<0和K<-1的情况,编写一通用的中点画线算法。
实验目的和意义1.了解如何利用C 语言和图形函数进行绘图;2. 熟悉并掌握C 语言的图形模式控制函数,图形屏幕操作函数,以及基本图形函数;3. 通过对Turbo C 进行图形程序设计的基本方法的学习,能绘制出简单的图形;4. 熟悉并掌握DDA 法在屏幕上画一条具有三个像素宽的直线段L1以及通用的中点画线算法。
通过DDA 法及用的中点画线算法,了解图形系统初始化、图形系统关闭和图设计算法绘制直线与圆实验2形模式的控制,并熟练运用图形坐标的设置,包括定点、读取光标以及图形颜色的设置。
程序制作步骤(包括算法思想、算法流程图等)1.自动搜索显示器类型和显示模式,初始化图形系统,通过printf 、scanf 语句控制线段的端点坐标和画线颜色的自由输入;2. DDAline:设直线之起点为(x1,y1),终点为(x2,y2),则斜率k 为: 则有:⑴.可通过计算由x 方向的增量x ∆引起y 的改变生成直线。
《计算机图形学》实验指导书
计算机图形学实验指导书袁科计算机技术实验中心目录实验一实现DDA、中点画线算法和Bresenham画线算法 (24)实验二实现Bezier曲线 (25)实验三实现B样条曲线 (26)实验四实现多边形填充的边界标志算法 (27)实验五实现裁剪多边形的Cohen-Sutherland算法 (28)实验六二维图形的基本几何变换 (30)实验七画图软件的编制 (31)实验一实现DDA、中点画线算法和Bresenham画线算法【实验目的】1、掌握直线的多种生成算法;2、掌握二维图形显示原理。
【实验环境】VC++6.0/ BC【实验性质及学时】验证性实验,2学时,必做实验【实验内容】利用任意的一个实验环境,编制源程序,分别实现直线的三种生成算法,即数字微分法(DDA)、中点画线法以及Bresenham画线算法。
【实验原理】1、数字微分法(Digital Differential Analyzer,DDA)算法思想:基于直线的微分方程来生成直线。
ε=1/max(|△x|,|△y|)max(|△x|,|△y|)=|△x|,即|k|≤1 的情况:max(|△x|,|△y|)=|△y|,此时|k|≥1:2、中点画线法算法思想:每次在最大位移方向上走一步,另一方向是否走步取决于误差项的判断。
3、Bresenham画线算法算法思想:其基本思想同中点算法一样,即每次在最大位移方向上走一步,而另一个方向是否走步取决于误差项的判断。
【实验要求】1.上交源程序;2.上交实验报告,实验报告内容如下:(1) 实验名称(2) 实验目的(3) 算法实现的设计方法及程序流程图(4) 程序结果分析【分析与思考】(1) 上述所阐述的三个算法,其基本算法只能适用于直线的斜率(|K|<=1) 的情形,如何将上述算法进行推广,使其能够处理任意斜率的直线?(2) 计算机显示屏幕的坐标圆心在哪里,与我们平时的习惯有什么差异,如何协调二者?实验二 实现Bezier 曲线【实验目的】1、掌握Bezier 曲线的定义;2、能编程实现N 次Bezier 曲线的绘制与显示。
计算机图形学实验一画直线
贵州大学实验报告
学院:计算机科学与技术专业:计算机科学与技术班级:计科131
算法原理:
与DDA算
法相似,
Bresenham
画线算法也
要在每列象
素中找到与
理想直线最逼近的象素点。
根据直线的斜率来确定变量在x或y方向递增一个单位。
另一个方向y或x的增量为0或1,它取决于实际直线与最接近网格点位置的距离。
这一距离称为误差。
算法的巧妙构思,使每次只需检查误差项(增量)的符号即可。
定义决策变量:d =d+k (0<k<1)设0<k<1,如直线上的一点为(x,y),则下一点为:(x+1,y) (d< 或(x+1,y+1)(d>=当d>1时,让d=d-1,以保证0<=d<1,d0=0
令e = (0<k<1),则e0 =
则下一点为:
(x+1,y),(e<0)
(x+1,y+1)(e>=0)
当e >0时, 让e =e-1,(重新初始化误差项)由于算法只用到误差项的符号,为了改用整数以避免除法,可以作如下替换:
e = 2*e*dx定义决策变量e= 2*e*dx,则e0 = -dx,e=e +2*dy
printf("输入有误,请重新输入\n");
break;
}
}
return 0;
}
实
验
结
果
实
验总结
通过这次试验我对于中点生成算法和Bresenham生成算法有了进一步的了解,在平时上课的基础上对计算机图形学有了更深的认识,同时对课程内容也更加了解。
计算机图形学实验报告-实验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]上的可同理推导。
华中科技大学计算机图形学实验报告——画直线、日地月模型
华中科技大学计算机图形学实验报告——画直线、日地月模型计算机图形学基础实验报告专业:班级:姓名:学号:日期:OpenGL简介(1)OpenGL作为一个性能优越的图形应用程序设计界面(API),它独立于硬件和窗口系统,在运行各种操作系统的各种计算机上都可用,并能在网络环境下以客户/服务器模式工作,是专业图形处理、科学计算等高端应用领域的标准图形库。
它具有以下功能。
1. 模型绘制2. 模型观察在建立了三维景物模型后,就需要用OpenGL描述如何观察所建立的三维模型。
3. 颜色模式的指定OpenGL应用了一些专门的函数来指定三维模型的颜色。
4. 光照应用用OpenGL绘制的三维模型必须加上光照才能更加与客观物体相似。
5. 图象效果增强OpenGL提供了一系列的增强三维景观的图象效果的函数,这些函数通过反走样、混合和雾化来增强图象的效果。
6. 位图和图象处理OpenGL还提供了专门对位图和图象进行操作的函数。
7. 纹理映射8. 实时动画9. 交互技术应用软件OpenGL窗口系统操作系统图形硬件图1.1 OpenGL图形处理系统的层次结构(2)OpenGL的操作步骤在OpenGL中进行的图形操作直至在计算机屏幕上渲染绘制出三维图形景观的基本步骤如下:1. 根据基本图形单元建立景物模型,得到景物模型的数学描述(OpenGL 中把点、线、多边形、图像和位图都作为基本图形单元);2. 把景物模型放在三维空间中的合适的位置,并且设置视点(Viewpoint)以观察所感兴趣的景观;3. 计算模型中所有物体的色彩,同时确定光照条件、纹理粘贴方式等;4. 把景物模型的数学描述及其色彩信息转换至计算机屏幕上的像素,这个过程也就是光栅化(rasterization)。
在这些步骤的执行过程中,OpenGL可能执行其他的一些操作,例如自动消隐处理等。
另外,景物光栅化之后被送入帧缓冲器之前还可以根据需要对象素数据进行操作。
(3)OpenGL的组成OpenGL不是一种编程语言,而是一种API(应用程序编程接口),它实际上是一种图形与硬件的接口,包括了多个图形函数。
计算机图形学实验一:画直线
大学实验报告学院:计算机科学与技术专业:计算机科学与技术班级:计科131如果d>0,则M在理想直线上方,选正右方P2点;如果d<0,则M在理想直线下方,选右上方P1点;如果d=0,则M在理想直线上,选P1/ P2点。
由于d是xi和yi的线性函数,可采用增量计算提高运算效率。
1.如由pi点确定在是正右方P2点(d>0).,则新的中点M仅在x方向加1,新的d值为:d new=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c而d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+cd new=d old+a= d old-dy2.如由pi点确定是右上方P1点(d<0),则新的中点M在x和y方向都增加1,新的d值为d new=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c而d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+cd new=d old+a+b= d old-dy+dx在每一步中,根据前一次第二迭中计算出的d值的符号,在正右方和右上方的两个点中进行选择。
d的初始值: d0=F(x0+1,y0+0.5)=F(x0,y0)+a+b/2=a+b/2=-dy+dx/2 F(x0,y0)=0,(x0,y0)在直线上。
为了消除d的分数,重新定义F(x,y)=2(ax+by+c)则每一步需要计算的d new 是简单的整数加法dy=y1-y0,dx=x1-x0d0=-2dy+dxd new=d old-2*dy,当d old>=0d new=d old-2(dy-dx),当d old<0Bresenham画线算法算法原理:与DDA算法相似,Bresenham画线算法也要在每列象素中找到与理想直线最逼近的象素点。
根据直线的斜率来确定变量在x或y方实验容#include"stdafx.h"#include<glut.h>#include<iostream>#include<cmath>#include<stdio.h>using namespace std;void init(){glClearColor(1.0, 1.0, 1.0, 1.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, 200.0, 0.0, 150.0);}void IntegerBresenhamline(){int x1 = 10, y1 = 10, x2 = 150, y2 = 100;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int x, y;int e = -dx;if (x1 > x2){x = x2;y = y2;x2 = x1;}else{x = x1;y = y1;}glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glBegin(GL_LINES);glVertex2i(x, y);while (x < x2){if (e >= 0){y++;e = e - 2 * dx;}glVertex2i(x, y);x++; e += 2 * dy;}glEnd();glFlush();}void MidPointLine(){int x, y, x1 = 10, y1 = 10, x2 = 150, y2 = 100;int dy = y1 - y2;int dx = x2 - x1;int d = 2 * dy + dx;int dx1 = 2 * dy;int dx2 = 2 * (dx + dy);if (x1 > x2){x = x2;y = y2;x2 = x1;}else{x = x1;y = y1;}glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glBegin(GL_LINES);glVertex2i(x, y);while (x < x2){if (d<0){y++; x++;d += dx2;}else{x++, d += dx1;}glVertex2i(x, y);}glEnd();glFlush();}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowPosition(50, 100);glutInitWindowSize(400, 300);int choice;printf("输入你想画的直线0代表Bresenham 1代表中点画线\n");while (1){scanf("%d", &choice);switch (choice){case 0:glutCreateWindow("Bresenham Draw Line");init();glutDisplayFunc(IntegerBresenhamline);glutMainLoop();break;case 1:glutCreateWindow("middle Point Line");init();glutDisplayFunc(MidPointLine);glFlush();glutMainLoop();break;default:printf("输入有误,请重新输入\n");break;}}return 0;}实验结果实验总结通过这次试验我对于中点生成算法和Bresenham生成算法有了进一步的了解,在平时上课的基础上对计算机图形学有了更深的认识,同时对课程容也更加了解。
计算机图形学基础实验指导书
计算机图形学基础实验指导书目录实验一直线的生成 ............................................................... -..2.-实验二圆弧及椭圆弧的生成........................................................ -..3 -实验三多边形的区域填充 ......................................................... - (4)-实验四二维几何变换 ............................................................. -..5.-实验五裁剪算法 ................................................................. -..6.-实验六三维图形变换 ............................................................. -..7.-实验七BEZIER 曲线生成......................................................... -..8.-实验八交互式绘图技术实现........................................................ -..10-实验一直线的生成一、实验目的掌握几种直线生成算法的比较,特别是Bresenham 直线生成算法二、实验环境实验设备:计算机实验使用的语言: C 或Visual C++ 、OpenGL三、实验内容用不同的生成算法在屏幕上绘制出直线的图形,对不同的算法可设置不同的线形或颜色表示区别。
四、实验步骤直线Bresenham 生成算法思想如下1)画点(x i, y i), dx=x2-x i, dy=y2-y i,计算误差初值P i=2dy-dx , i=1;2)求直线下一点位置x i+i=x i+i 如果P i>0,贝U y i+i=y i+i,否则y i+i=y i;3)画点(x i+i ,y i+i );4)求下一个误差P i+i 点,如果P i>0,贝U P i+i=P i+2dy-2dx,否则P i+i=P i+2dy;i=i+i ,如果i<dx+i 则转步骤2,否则结束操作。
《计算机图形学》实验报告
《计算机图形学》实验报告一、实验目的计算机图形学是一门研究如何利用计算机生成、处理和显示图形的学科。
通过本次实验,旨在深入理解计算机图形学的基本原理和算法,掌握图形的生成、变换、渲染等技术,并能够运用所学知识解决实际问题,提高对图形学的应用能力和编程实践能力。
二、实验环境本次实验使用的编程语言为 Python,使用的图形库为 Pygame。
开发环境为 PyCharm。
三、实验内容1、直线的生成算法DDA 算法(Digital Differential Analyzer)Bresenham 算法DDA 算法是通过计算直线的斜率来确定每个像素点的位置。
它的基本思想是根据直线的斜率和起始点的坐标,逐步计算出直线上的每个像素点的坐标。
Bresenham 算法则是一种基于误差的直线生成算法。
它通过比较误差值来决定下一个像素点的位置,从而减少了计算量,提高了效率。
在实验中,我们分别实现了这两种算法,并比较了它们的性能和效果。
2、圆的生成算法中点画圆算法中点画圆算法的核心思想是通过判断中点的位置来确定圆上的像素点。
通过不断迭代计算中点的位置,逐步生成整个圆。
在实现过程中,需要注意边界条件的处理和误差的计算。
3、图形的变换平移变换旋转变换缩放变换平移变换是将图形在平面上沿着指定的方向移动一定的距离。
旋转变换是围绕一个中心点将图形旋转一定的角度。
缩放变换则是改变图形的大小。
通过矩阵运算来实现这些变换,可以方便地对图形进行各种操作。
4、图形的填充种子填充算法扫描线填充算法种子填充算法是从指定的种子点开始,将相邻的具有相同颜色或属性的像素点填充为指定的颜色。
扫描线填充算法则是通过扫描图形的每一行,确定需要填充的区间,然后进行填充。
在实验中,我们对不同形状的图形进行了填充,并比较了两种算法的适用情况。
四、实验步骤1、直线生成算法的实现定义直线的起点和终点坐标。
根据所选的算法(DDA 或Bresenham)计算直线上的像素点坐标。
贵州大学计算机图形学实验报告----直线生成算法
贵州大学计算机图形学实验报告学院:计算机科学与信息学院专业:软件工程班级:102班优点:用整数加法代替了DDA数值微分法中的浮点数加法及取整运算,大大提高了算法的效率。
缺点:在计算d的符号时,需要做4个加法和2个乘法改进:因为d是x和y的线性函数,因此可采用增量计算。
通过计算可得对于|k|<=1的情况d的初值为a+0.5b,当d>=0,M在L上方,增量d1为a;当d<0,M在L下方,增量d2为a+b。
对于|k|>1的情况d的初值为0.5a+b,当d>=0,M在L下方,增量d1为b;当d<0,M在L上方,增量d2为a+b。
三、Bresenham划线算法该算法是计算机图形学领域中使用最为广泛的直线扫描转换算法,该划线算法类似与中点划线算法,也是由误差项符号决定下一个像素右边点还是右上点。
基本原理:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
该算法的优点在于增量计算,使得对于每一列只要检查一个误差项的符号,就可以确定该列所求的像素。
根据直线的斜率来确定变量在x 或y方向递增一个单位。
另一个方向y或x的增量为0或1,它取决于实际直线与最接近网格点位置的距离。
这一距离称为误差。
由以上原理,为方便计算,令e = d-0.5,e的初值为-0.5,增量为k。
当 e>=0时,取当前像素(xi,yi)的右上方像素(xi+1,yi+1),e减小1,而当e<0时,更接近于右方像素(xi+1,yi)。
Bresenham算法的分析:优点:高效,巧妙地采用了e = d-0.5,e的初值为-0.5来简化运算,把e和0.5的比较转化成了e和0的比较,使得每次画点只需考虑误差项增量的符号即可。
斜率显示:中点划线算法斜率显示: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这种方法直观,但效率太低,因为每一步需要一次浮点乘法和一次舍入运算。
计算机图形学--Bresenham完整算法-画直线、椭圆和圆
#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 = -250 ;//坐标线为黑色glColor3f(0.0f, 0.0f ,0.0f);glBegin(GL_LINES);for (i=-250;i<=250;i=i+10){glVertex2f((float)(i), -250.0f);glVertex2f((float)(i), 250.0f);glVertex2f(-250.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画线算法 //// //// //// /////////////////////////////////////////////////////////////////////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) //// //// //// /////////////////////////////////////////////////////////////////////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;//画线算法的实现GLsizei p=0;GLfloat UpIncre,DownIncre,x,y,d,k,dx,dy;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;k=dy/dx;if(k>=0&&k<=1){d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=-2*dy;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;if(d<0){y++;d+=UpIncre;}else d+=DownIncre;}}if(k>1){d=dy-2*dx;UpIncre=2*dy-2*dx;DownIncre=-2*dx;while(y<=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y++;if(d<0){x++;d+=UpIncre;}else d+=DownIncre;}}if(k<0&&k>=-1){d=dx-2*dy;UpIncre=-2*dy;DownIncre=-2*dx-2*dy;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;if(d>0){y--;d+=DownIncre;}else d+=UpIncre;}}if(k<-1){d=-dy-2*dx;UpIncre=-2*dx-2*dy;DownIncre=-2*dx;while(y>=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y--;if(d<0){x++;d+=UpIncre;}else d+=DownIncre;}}}/////////////////////////////////////////////////////////////////////改进的Bresenham算法画直线(0<=k<=1) //// //// x1,y1 终点坐标 //// /////////////////////////////////////////////////////////////////////void Bresenham2Line(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);GLsizei x,y,dx,dy,e,k;if(num == 1)printf("改进的Bresenham算法画直线各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei p=0;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}dx=x1-x0;dy=y1-y0;k=dy/dx;if(k>=0&&k<=1){e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}if(k>1){e=-dy;x=x0;y=y0;while(y<=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y++;e=e+2*dx;if(e>0){x++;e=e-2*dy;}}}if(k<0&&k>=-1){e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;e=e+2*dy;if(e<0){y--;e=e+2*dx;}}}if(k<-1){e=-dy;x=x0;y=y0;while(y>=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y--;e=e-2*dx;if(e<0){x++;e=e-2*dy;}}}}///////////////////////////////////////////////////////////Bresenham算法画圆 //// //// //// ///////////////////////////////////////////////////////////void CirclePoint(GLsizei x,GLsizei y){ putpixel(x,y);putpixel(x,-y);putpixel(y,-x);putpixel(-y,-x);putpixel(-x,-y);putpixel(-x,y);putpixel(-y,x);putpixel(y,x);}void BresenhamCircle(GLsizei x, GLsizei y, GLsizei R, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);GLsizei d;x=0;y=R;d=1-R;if(num == 1)printf("Bresenham算法画圆:各点坐标及判别式的值\n");else if(num==0)return;while(x<=y){CirclePoint(x,y);if (x>=num-1) {printf("x=%d,y=%d,d=%d\n", x, y,d);break;}if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}x++;}}void Bresenham2Circle(GLsizei a,GLsizei b,GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num==1)printf("Bresenham算法画椭圆:各点坐标及判别式的值\n");else if(num==0)return;GLsizei x,y;float d1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.5);putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);while(b*b*(x+1)<a*a*(y-0.5)){if (x>=num-1) {printf("x=%d,y=%d,d1=%d\n", x, y,d1);break;}if(d1<=0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);x++;y--;}putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);}//while上半部分d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;while(y>0){if (x>=num-1) {printf("x=%d,y=%d,d2=%d\n", x, y,d2);break;}if(d2<=0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);}}//初始化窗口void Initial(void){// 设置窗口颜色为蓝色glClearColor(0.0f, 0.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 (-250.0f, 250.0f, -250.0f, 250.0f*h/w, 1.0, -1.0);elseglOrtho (-250.0f, 250.0f*w/h, -250.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(0,0,20,m_PointNumber);break;case 5:Bresenham2Circle(10,8,m_PointNumber);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;if (key == '5') m_DrawMode = 5;m_PointNumber = 0;glutPostRedisplay();}//void main(void)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(); //启动事件处理循环return 0;}。
计算机图形学实验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°方向椭圆焦点的坐标.然后再根据公式进行画点。
计算机图形学实验一:画直线
贵州大学实验报告学院:计算机科学与技术专业:计算机科学与技术班级:计科131如果 d<0,则M在理想直线下方,选右上方P1点;如果 d=0,则M在理想直线上,选P1/ P2点。
由于d是xi和yi的线性函数,可采用增量计算提高运算效率。
1.如由pi点确定在是正右方P2点(d>0).,则新的中点M仅在x方向加1,新的d值为:d new=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+cd new=d old+a= d old-dy2.如由pi点确定是右上方P1点(d<0),则新的中点M在x和y方向都增加1,新的d值为d new=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+cd new=d old+a+b= d old-dy+dx在每一步中,根据前一次第二迭中计算出的d值的符号,在正右方和右上方的两个点中进行选择。
d的初始值: d0=F(x0+1,y0+0.5)=F(x0,y0)+a+b/2=a+b/2=-dy+dx/2 F(x0,y0)=0,(x0,y0)在直线上。
为了消除d的分数,重新定义 F(x,y)=2(ax+by+c)则每一步需要计算的d new 是简单的整数加法dy=y1-y0,dx=x1-x0d0=-2dy+dxd new=d old-2*dy,当 d old>=0d new=d old-2(dy-dx),当d old<0Bresenham画线算法算法原理:与DDA算法相似,Bresenham画线算法也要在每列象素中找到与理想直线最逼近的象素点。
根据直线的斜率来确定变量在x或y方向递增一个单实验内容#include"stdafx.h"#include<glut.h>#include<iostream>#include<cmath>#include<stdio.h>using namespace std;void init(){glClearColor(1.0, 1.0, 1.0, 1.0);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, 200.0, 0.0, 150.0);}void IntegerBresenhamline(){int x1 = 10, y1 = 10, x2 = 150, y2 = 100;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int x, y;int e = -dx;if (x1 > x2){x = x2;y = y2;x2 = x1;}else{x = x1;y = y1;}glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glBegin(GL_LINES);glVertex2i(x, y);while (x < x2){if (e >= 0){y++;e = e - 2 * dx;}glVertex2i(x, y);x++; e += 2 * dy;}glEnd();glFlush();}void MidPointLine(){int x, y, x1 = 10, y1 = 10, x2 = 150, y2 = 100;int dy = y1 - y2;int dx = x2 - x1;int d = 2 * dy + dx;int dx1 = 2 * dy;int dx2 = 2 * (dx + dy);if (x1 > x2){x = x2;y = y2;x2 = x1;}else{x = x1;y = y1;}glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glBegin(GL_LINES);glVertex2i(x, y);while (x < x2){if (d<0){y++; x++;d += dx2;}else{x++, d += dx1;}glVertex2i(x, y);}glEnd();glFlush();}int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowPosition(50, 100);glutInitWindowSize(400, 300);int choice;printf("输入你想画的直线 0代表Bresenham 1代表中点画线\n");while (1){scanf("%d", &choice);switch (choice){case 0:glutCreateWindow("Bresenham Draw Line");init();glutDisplayFunc(IntegerBresenhamline);glutMainLoop();break;case 1:glutCreateWindow("middle Point Line");init();glutDisplayFunc(MidPointLine);glFlush();glutMainLoop();break;default:printf("输入有误,请重新输入\n");break;}}return 0;}实验总结通过这次试验我对于中点生成算法和Bresenham生成算法有了进一步的了解,在平时上课的基础上对计算机图形学有了更深的认识,同时对课程内容也更加了解。
计算机图形学实验报告
目录实验一直线的DDA算法一、【实验目的】1.掌握DDA算法的基本原理。
2.掌握DDA直线扫描转换算法。
3.深入了解直线扫描转换的编程思想。
二、【实验内容】1.利用DDA的算法原理,编程实现对直线的扫描转换。
2.加强对DDA算法的理解和掌握。
三、【测试数据及其结果】四、【实验源代码】GLsizei winWidth=500;GLsizei winHeight=500;void Initial(void){glMatrixMode(GL_PROJECTION);}void DDALine(int x0,int y0,int x1,int y1){int dx,dy,epsl,k;float 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/(float)epsl;yIncre=(float)dy/(float)epsl;for(k=0;k<=epsl;k++){glPointSize(3);glBegin(GL_POINTS);glEnd();x+=xIncre;y+=yIncre;}}void Display(void){glClear(GL_COLOR_BUFFER_BIT);DDALine(100,100,200,180);glFlush();}void winReshapeFcn(GLint newWidth, GLint newHeight) {glMatrixMode(GL_PROJECTION);glLoadIdentity();glClear(GL_COLOR_BUFFER_BIT);winWidth=newWidth;winHeight=newHeight;}int main(int argc,char*argv[]){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowSize(400,300); glutInitWindowPosition(100,120); glutCreateWindow("line");Initial();glutDisplayFunc(Display);glutReshapeFunc(winReshapeFcn);glutMainLoop();return 0;}实验二Bresenham绘制直线和圆一、【实验目的】1.掌握Bresenham算法扫描转换圆和直线的基本原理。
计算机图形学画直线——制作过程
cs.lpszName = _T( "绘制任意直线" );
cs.style = WS_OVERLAPPEDWINDOW;
cs.cx=500;
cs.cy=400;
return TRUE;
修改static UINT indicators[] =
{
int x=-(rt.Width()/2)/10;
int y=(int)(k*x+c+0.5);
float e=k*x+c-y-0.5;
for(int i=0;i<=rt.Width()/10;i++)
{
pDC->Ellipse(rt.Width()/2+x*10-3,rt.Height()/2-y*10-3,rt.Width()/2+x*10+3,rt.Height()/2-y*10+3);
{
pDC->Ellipse(rt.Width()/2+x*10-3,rt.Height()/2-y*10-3,rt.Width()/2+x*10+3,rt.Height()/2-y*10+3);
x++;
e+=k;
if(e<0)
{
y--;
e++;
}
}
}
else if(k>1)//斜率大于1
{
int y=-(rt.Height()/2)/10;
}
pDC->SelectObject(pOldPen);
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
大学实验报告
学院:计算机科学与技术专业:计算机科学与技术班级:计科131
如果 d<0,则M在理想直线下方,选右上方P1点;
如果 d=0,则M在理想直线上,选P1/ P2点。
由于d是xi和yi的线性函数,可采用增量计算提高运算效率。
1.如由pi点确定在是正右方P2点(d>0).,则新的中点M仅在x方向加1,新的d值为:
d new=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c
而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c
d new=d old+a= d old-dy
2.如由pi点确定是右上方P1点(d<0),则新的中点M在x和y方向都增加1,新的d值为
d new=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c
而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c
d new=d old+a+b= d old-dy+dx
在每一步中,根据前一次第二迭中计算出的d值的符号,在正右方和右上方的两个点中进行选择。
d的初始值: d0=F(x0+1,y0+0.5)=F(x0,y0)+a+b/2=a+b/2=-dy+dx/2 F(x0,y0)=0,(x0,y0)在直线上。
为了消除d的分数,重新定义 F(x,y)=2(ax+by+c)
则每一步需要计算的d new 是简单的整数加法
dy=y1-y0,dx=x1-x0
d0=-2dy+dx
d new=d old-2*dy,当 d old>=0
d new=d old-2(dy-dx),当d old<0
Bresenham画线算法
算法原理:
与DDA算法
相似,Bresenham
画线算法也要在
每列象素中找到
与理想直线最逼
近的象素点。
根据直线的
斜率来确定变量
在x或y方向递
增一个单位。
另
一个方向y或x
实验容#include"stdafx.h"
#include<glut.h>
#include<iostream>
#include<cmath>
#include<stdio.h>
using namespace std;
void init()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 200.0, 0.0, 150.0);
}
void IntegerBresenhamline()
{
int x1 = 10, y1 = 10, x2 = 150, y2 = 100;
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
int x, y;
int e = -dx;
if (x1 > x2)
{
x = x2;
y = y2;
x2 = x1;
}
else{
x = x1;
y = y1;
}
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex2i(x, y);
while (x < x2)
{
if (e >= 0)
{
y++;
e = e - 2 * dx;
}
glVertex2i(x, y);
x++; e += 2 * dy;
}
glEnd();
glFlush();
}
void MidPointLine()
{
int x, y, x1 = 10, y1 = 10, x2 = 150, y2 = 100;
int dy = y1 - y2;
int dx = x2 - x1;
int d = 2 * dy + dx;
int dx1 = 2 * dy;
int dx2 = 2 * (dx + dy);
if (x1 > x2)
{
x = x2;
y = y2;
x2 = x1;
}
else{
x = x1;
y = y1;
}
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex2i(x, y);
while (x < x2)
{
if (d<0)
{
y++; x++;
d += dx2;
}
else
{
x++, d += dx1;
}
glVertex2i(x, y);
}
glEnd();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(50, 100);
glutInitWindowSize(400, 300);
int choice;
printf("输入你想画的直线 0代表Bresenham 1代表中点画线\n");
while (1)
{
scanf("%d", &choice);
switch (choice)
{
case 0:
glutCreateWindow("Bresenham Draw Line");
init();
glutDisplayFunc(IntegerBresenhamline);
glutMainLoop();
break;
case 1:
glutCreateWindow("middle Point Line");
init();
glutDisplayFunc(MidPointLine);
glFlush();
glutMainLoop();
break;
default:
printf("输入有误,请重新输入\n");
break;
}
}
return 0;
}
实验结果
实
验总结
通过这次试验我对于中点生成算法和Bresenham生成算法有了进一步的了解,在平时上课的基础上对计算机图形学有了更深的认识,同时对课程容也更加了解。
指
导
教
师
意
见签名:年月日。