直线的生成
计算机图形学实验二:直线的生成算法的实现

实验二: 直线的生成算法的实现班级 08信计2班学号 20080502055 姓名分数一、实验目的和要求:1.理解直线生成的原理;2.掌握几种常用的直线生成算法;3.利用C实现直线生成的DDA算法。
二、实验内容:1.了解直线的生成原理2、掌握几种基本的直线生成算法: DDA画线法、中点画线法、Bresenham画线法。
3、仿照教材关于直线生成的DDA算法, 编译程序。
4.调试、编译、运行程序。
三、实验过程及结果分析1.直线DDA算法:算法原理:已知过端点P0(x0,y0), P1(x1,y1)的直线段L(P0,P1), 斜率为k=(y1-y0)/(x1-x0), 画线过程从x的左端点x0开始, 向x右端点步进, 步长为1个像素, 计算相应的y坐标为y=kx+B。
计算y i+1 = kx i+B=kx i +B+kx=y i +kx当x=1,yi+1=yi+k, 即当x每递增1, y递增k。
由计算过程可知, y与k可能为浮点数, 需要取y整数, 源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。
(1)程序代码:#include"stdio.h"#include"graphics.h"void linedda(int x0,int y0,int x1,int y1,int color){int x,dy,dx,y;float m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color);y+=m;setbkcolor(7);}}main(){int a,b,c,d,e;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode,"");a=100;b=100;c=200;d=300;e=5;linedda(a,b,c,d,e);getch();closegraph();}运行结果:2.中点画线算法:假定所画直线的斜率为k∈[0,1], 如果在x方向上增量为1, 则y方向上的增量只能在0~1之间。
快速直线生成算法

2 aj gUnvrt f rn ui .N ni iesyo Ae at s& A t n ui , nig2 0 1 , hn ; n i o c s o at s Naj 10 6 C ia r c n 3 Naj gUnvri f eo ats& A t nui , mig20 1 , hn ) . ni ie t o rnui n sy A c sr ats Na n 10 6 C ia o c
20 0 7年 9月
快 速 直 线 生 成 算 法
刘 晶 ,李 俊2 孙 涵2 , ,贾银 亮。
( . 陵科 技 学 院 信 息 技 术 学 院 , 苏 南 京 2 0 0 ; . 京 航 空 航 天 大 学 信 息 科 学 与技 术学 院 , 苏 南 京 2 0 1 ; 1金 江 10 1 2 南 江 10 6
Fa t Al o ihm o ne Dr wi s g r t f r Li a ng
LI Jn U ig ,LIJ n ,SUN n ,J A n 1 n 。 u 2 Ha I Yi. a g i
分别解释直线生成算法dda法,中点画线法和bresenham法的基本原理

分别解释直线生成算法dda法,中点画线法和
bresenham法的基本原理
直线生成算法DDA法、中点画线法和Bresenham法的基本原理如下:
1. DDA直线生成算法:基于差分运算的直线生成算法。
通过将直线分割成
若干个相邻的像素点,并按照一定的步长进行逐点绘制,实现直线的绘制。
算法主要涉及到线性插值的思想,即根据已知的两点坐标,通过计算它们之间的差值,然后根据这个差值和步长来确定新的像素点的位置。
2. 中点画线法:一种线段绘制算法,从线段的起点和终点出发,按照一定的规则向终点逐步逼近,并在途中以控制变量的方式得出每个像素点的坐标,从而绘制出所需的线条。
具体实现中,通过计算线段斜率的变化情况,分为斜率小于1和大于等于1两种情况,并采用Bresenham的对称性原理,以中点的颜色来控制每个像素点的生长方向,从而获得较高的绘制效率和图像质量表现。
3. Bresenham算法:通过一系列的迭代来确定一个像素点是否应该被绘制。
对于一条从点(x1,y1)到点(x2,y2)的直线,首先计算出斜率k。
然后,通过比较每个像素点的y值到直线上的y值,来决定哪些像素点应该被绘制。
当斜率k大于等于1时,在x方向上迭代,而对于每个x值,计算出y值,并将像素点(x,y)绘制。
当斜率k小于1时,在y方向上迭代,而对于每个y值,计算出x值,并将像素点(x,y)绘制。
以上内容仅供参考,如需更多信息,建议查阅相关文献或咨询数学专业人士。
第2讲直线的绘制

第2讲直线绘制本讲要点:直线的绘制方式工具点的拾取矩形的绘制多边形的绘制2.1直线【功能】直线是图形构成的基本要素。
直线功能提供了两点线、平行线、角度线、切线/法线、角等分线和水平/铅垂线六种方式。
1、单击主菜单“造型”,指向“曲线生成”,单击“直线”,或者单击按钮。
2、在立即菜单中选取画线方式,根据状态栏提示,完成操作。
2.1.1两点线【功能】两点线就是在屏幕上按给定两点画一条直线段或按给定的连续条件画连续的直线段。
图2-1两点线示例图1、单击直线按钮,在立即菜单中选择两点线。
2、按状态栏提示,给出第一点和第二点,两点线生成。
【参数】连续:是指每段直线段相互连接,前一段直线段的终点为下一段直线段的起点。
单个:是指每次绘制的直线段相互独立,互不相关。
非正交:可以画任意方向的直线,包括正交的直线。
正交:是指所画直线与坐标轴平行。
点方式:指定两点来画出正交直线。
长度方式:按指定长度和点来画出正交直线。
2.1.2平行线【功能】平行线:按给定距离或通过给定的已知点绘制与已知线段平行、且长度相等的平行线段。
过点方式等距方式图2-2平行线示例图1、单击按钮,在立即菜单中选择平行线,距离或点方式。
2、若为距离方式,输入距离值和条数。
按状态栏提示拾取直线,给出等距方向,平行线生成。
3、若为点方式,按状态栏提示拾取直线,拾取点,平行线生成。
【参数】过点:是指过一点做已知直线的平行线。
距离:是指按照固定的距离做已知直线的平行线。
条数:可以同时做出的多条平行线的数目。
2.1.3角度线【功能】角度线:生成与坐标轴或一条直线成一定夹角的直线。
图2-3角度线示例图1、单击按钮,在立即菜单中选择角度线,直线夹角或X轴夹角或Y轴夹角,输入角度值。
2、若为直线夹角,拾取直线,给出第一点,给出第二点或长度,角度线生成。
3、若为X或Y轴夹角,给出第一点,给出第二点或长度,角度线生成。
【参数】夹角类型包括与X轴夹角、与Y轴夹角和与直线夹角。
计算机图形学第3章 基本图形生成算法

例题:有点P0(4,3);P1(6,5);P2(10,
6 );P3(12,4),用以上4点构造2次B样条曲线。
2.1.7 非均匀有理B样条
非均匀有理B样条NURBS(Non Uniform Rational BSpline);
3.2.2
Bresenham画圆法
该算法是最有效的算法之一。
不失一般性,假设圆心(xc,yc) ,圆上的点(x′,y′),则:
x' x xc
y ' y yc
圆心为原点,半径为R的位于第一象限1/8圆弧的画法,即(0, R)~( R , R )。
2 2
yi ), 思想:每一步都选择一个距离理想圆周最近的点P( xi , 使其误差项最小。
画其他曲线。
3.3
自由曲线的生成
正弦函数曲线
指数函数曲线
多项式函数曲线
自 由 曲 线
概率分布曲线及样条函数曲线
3.3.1 曲线的基本理论
基本概念
2.1.4
规则曲线:可用数学方程式表示出来的,如抛物 线等。
自由曲线:很难用一个数学方程式描述的,如高
速公路等。可通过曲线拟合(插值、逼近)的方法来
例题: 利用Bresenham算法生成P (0,0)到Q(6,5)的直 线所经过的像素点。要求先 列出计算式算出各点的坐标 值,然后在方格中标出各点。
(1,1)
3.1.5 双步画线法 原理
模式1:当右像素位于右下角时,中间像素位于底线 模式4:当右边像素位右上角时,中间像素位于中线 模式2和模式3:当右像素位于中线时,中间像素可能位于底线 上,也可能位于中线上,分别对应于模式2和模式3,需进一步 判断。 当0≤k≤1/2时,模式4不可能出现,当1/2≤k≤1时,模式1不 可能出现。
计算机图形学实验二 直线的生成算法的实现

实验二直线的生成算法的实现班级 08信计二班学号 20080502086 姓名分数一、实验目的和要求:1、理解直线生成的基本原理2、熟悉直线的生成算法,掌握直线的绘制3、实现直线生成的DDA 中点画法 Bresenham算法4、了解Visual C++等编程环境中常用控件命令与绘图函数,初步掌握在试验设计集成下进行图形处理程序的设计方法二、实验内容:1、了解直线生成的原理直线DDA算法,中点画线算法,Bresenham画线算法2、编程实现DDA算法、Bresenham算法、中点画法绘制直线段三、实验结果分析1.DDA算法// 程序名称:基于 DDA 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 四舍五入int Round(float x){return (int)(x < 0 ? x - 0.5 : x + 0.5);}// 使用 DDA 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_DDA(int x1, int y1, int x2, int y2, int color){float x, y; // 当前坐标点float cx, cy; // x、y 方向上的增量int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);x = (float)x1;y = (float)y1;cx = (float)(x2 - x1) / steps;cy = (float)(y2 - y1) / steps;for(int i = 0; i < steps; i++){putpixel(Round(x), Round(y), color); // 在坐标 (x, y) 处画一个 color 颜色的点x += cx;y += cy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_DDA(100, 1, 1, 478, GREEN);Line_DDA(1, 478, 638, 1, GREEN);// 按任意键退出getch();closegraph();}2.中点算法// 程序名称:基于中点算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Midpoint(int x1, int y1, int x2, int y2, int color){int x = x1, y = y1;int a = y1 - y2, b = x2 - x1;int cx = (b >= 0 ? 1 : (b = -b, -1));int cy = (a <= 0 ? 1 : (a = -a, -1));putpixel(x, y, color);int d, d1, d2;if (-a <= b) // 斜率绝对值 <= 1{d = 2 * a + b;d1 = 2 * a;d2 = 2 * (a + b);while(x != x2){if (d < 0)y += cy, d += d2;elsed += d1;x += cx;putpixel(x, y, color);}}else // 斜率绝对值 > 1{d = 2 * b + a;d1 = 2 * b;d2 = 2 * (a + b);while(y != y2){if(d < 0)d += d1;elsex += cx, d += d2;y += cy;putpixel(x, y, color);}}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Midpoint(100, 1, 1, 478,YELLOW);Line_Midpoint(1, 478, 638, 1, YELLOW);// 按任意键退出getch();closegraph();}3. Bresenham 算法// 程序名称:基于 Bresenham 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用 Bresenham 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Bresenham(int x1, int y1, int x2, int y2, int color){int x = x1;int y = y1;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int s1 = x2 > x1 ? 1 : -1;int s2 = y2 > y1 ? 1 : -1;bool interchange = false; // 默认不互换 dx、dyif (dy > dx) // 当斜率大于 1 时,dx、dy 互换{int temp = dx;dx = dy;dy = temp;interchange = true;}int p = 2 * dy - dx;for(int i = 0; i < dx; i++){putpixel(x, y, color);if (p >= 0){if (!interchange) // 当斜率 < 1 时,选取上下象素点y += s2;else // 当斜率 > 1 时,选取左右象素点x += s1;p -= 2 * dx;}if (!interchange)x += s1; // 当斜率 < 1 时,选取 x 为步长elsey += s2; // 当斜率 > 1 时,选取 y 为步长p += 2 * dy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Bresenham(100, 1, 1, 478, RED);Line_Bresenham(1, 478, 638, 1, RED);// 按任意键退出getch();closegraph();}实验结果分析三种算法运算结果比较:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法。
《计算机图形学》实验指导书

计算机图形学实验指导书袁科计算机技术实验中心目录实验一实现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 曲线的绘制与显示。
计算机图形学基础实验指导书

计算机图形学基础实验指导书目录实验一直线的生成 ............................................................... -..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,否则结束操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一: 直线数学上,理想的直线是由无数个点构成的集合,没有宽度。
计算机绘制直线是在显示器所给定的有限个像素组成的矩阵中,确定最佳逼近该直线的一组像素,并且按扫描线顺序,对这些像素进行写操作,实现显示器绘制直线,即通常所说的直线的扫描转换,或称直线光栅化。
由于一图形中可能包含成千上万条直线,所以要求绘制直线的算法应尽可能地快。
本节介绍一个像素宽直线的常用算法:数值微分法(DDA)、中点画线法、Bresenham 算法。
一. DDA(数值微分)算法DDA算法原理:如图1-1所示,已知过端点的直线段;直线斜率为,从的左端点开始,向右端点步进画线,步长=1(个像素),计算相应的坐标;取像素点[ , round(y)] 作为当前点的坐标。
计算,当,即当x每递增1,y递增k(即直线斜率)。
1的情形。
在这种情况下,x每增加1, y最多增加1。
当时,必须把x,y地位互换,y每增加1,x相应增加1/k(请参阅后面的Visual C++程序)。
注意:上述分析的算法仅适用于k二. 生成直线的中点画线法中点画线法的基本原理如图1-2所示。
在画直线段的过程中,当前像素点为P,下一个像素点有两种选择,点P1或P2。
M为P1与P2中点,Q为理想直线与X=Xp+1垂线的交点。
当M在Q的下方时,则P2应为下一个像素点;当M在Q的上方时,应取P1为下一点。
中点画线法的实现:令直线段为L[ p0(x0,y0), p1(x1, y1)],其方程式F(x, y)=ax+by+c=0。
其中,a=y0–y1, b=x1–x0, c=x0y1–x1y0;点与L的关系如下。
在直线上,F(x, y)=0;在直线上方,F(x, y)>0;在直线下方,F(x, y)<0。
把M代入F(x, y),判断F的符号,可知Q点在中点M的上方还是下方。
为此构造判别式d=F(M)=F(xp+1, yp+0.5)=a(xp+1)+b(yp+0.5)+c。
当d < 0,L(Q点)在M上方,取P2为下一个像素。
当d > 0,L(Q点)在M下方,取P1为下一个像素。
当d=0,选P1或P2均可,取P1为下一个像素。
其中d是xp, yp的线性函数。
三. Bresenham算法Bresenham算法是计算机图形学领域使用最广泛的直线扫描转换算法。
由误差项符号决定下一个像素取右边点还是右上方点。
设直线从起点(x1, y1)到终点(x2, y2)。
直线可表示为方程y = mx+b,其中b=y1–mx1,m = (y2–y1)/(x2–x1)=dy/dx;此处的讨论直线方向限于第一象限,如图1-3所示,当直线光栅化时,x每次都增加1个单元,设x像素为(xi,yi)。
下一个像素的列坐标为xi+1,行坐标为yi或者递增1为yi+1,由y与yi及yi+1的距离d1及d2的大小而定。
计算公式为y = m(xi + 1) + b (1.1)d1 = y – yi (1.2)d2=yi+1–y (1.3)如果d1–d2>0,则yi+1=yi+1,否则yi+1=yi。
式(1.1)、(1.2)、(1.3)代入d1–d2,再用dx乘等式两边,并以Pi=(d1–d2),dx代入上述等式,得Pi = 2xidy–2yidx+2dy+(2b–1)dx (1.4)d1–d2是用以判断符号的误差。
由于在第一象限,dx总大于0,所以Pi仍旧可以用做判断符号的误差。
Pi+1为Pi+1 = Pi+2dy–2(yi+1–yi)dx (1.5)求误差的初值P1,可将x1、y1和b代入式(1.4)中的xi、yi,而得到P1 = 2dy–dx综述上面的推导,第一象限内的直线Bresenham算法思想如下:(1)画点(x1, y1),dx=x2–x1,dy=y2–y1,计算误差初值P1=2dy–dx,i=1。
(2)求直线的下一点位置xi+1 = xi + 1,如果Pi>0,则yi+1=yi+1,否则yi+1=yi。
(3)画点(xi+1, yi+1)。
(4)求下一个误差Pi+1,如果Pi>0,则Pi+1=Pi+2dy–2dx,否则Pi+1=Pi+2dy。
(5)i=i+1;如果i<dx+1则转步骤(2);否则结束操作。
四. 程序设计1 程序设计功能说明为编程实现上述算法,本程序利用最基本的绘制元素(如点、直线等),绘制图形。
如图1-4所示,为程序运行主界面,通过选择菜单及下拉菜单的各功能项分别完成各种对应算法的图形绘制。
图1-4 基本图形生成的程序运行界面2 创建工程名称为“基本图形的生成”单文档应用程序框架(1)启动VC,选择“文件”|“新建”菜单命令,并在弹出的新建对话框中单击“工程”标签。
(2)选择MFC AppWizard(exe),在“工程名称”编辑框中输入“基本图形的生成”作为工程名称,单击“确定”按钮,出现Step 1对话框。
(3)选择“单个文档”选项,单击“下一个”按钮,出现Step 2对话框。
(4)接受默认选项,单击“下一个”按钮,在出现的Step 3~Step 5对话框中,接受默认选项,单击“下一个”按钮。
(5)在Step 6对话框中单击“完成”按钮,即完成“基本图形的生成”应用程序的所有选项,随后出现工程信息对话框(记录以上步骤各选项选择情况),如图1-5所示,单击“确定”按钮,完成应用程序框架的创建。
图1-5 信息程序基本3 编辑菜单资源设计如图1-4所示的菜单项。
在工作区的ResourceView标签中,单击Menu项左边“+”,然后双击其子项IDR_MAINFRAME,并根据表1-1中的定义编辑菜单资源。
此时VC已自动建好程序框架,如图1-5所示。
表1-1 菜单资源表菜单标题菜单项标题标示符ID直线DDA算法生成直线ID_DDALINEBresenham算法生成直线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章。
1的情形x每增加1,y最多增加1;当k (2)注意上述程序考虑到当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);int 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是xp, yp的线性函数。
为了提高运算效率,程序中采用增量计算。
具体算法如下:若当前像素处于d>0情况,则取正右方像素P1(xp+1, yp),判断下一个像素点的位置,应计算d1=F(xp+2, yp+0.5)=a(xp+2)+b(yp+0.5)=d+a;,其中增量为a。
若d<0时,则取右上方像素P2(xp+1, yp+1)。
再判断下一像素,则要计算d2 = F(xp+2,yp+1.5)=a(xp+2)+b(yp+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)以上程序已经考虑到所有象限直线的生成。