bresenham算法例题分析
Bresenham画圆算法图形学讲义教学课件

共享顶点的两条边分别位于扫描线的两边,交点算一个。 共享顶点的两条边都位于扫描线的下边,交点算零个。 共享顶点的两条边都位于扫描线的上边,交点算二个。
右、上边界的象素不予填充。 左、下边界的象素予以填充。
算法的实现
求交
所有的边和扫描线求交,效率很低。因为一条扫描线往往只 和少数几条边相交。
如何判断多边形的一条边与扫描线是否相交?(ymin,ymax)
=(x+1)2 + (y-1)2 -R2 - 2(y-1) + 1 = D - 2(y-1) + 1
有了上述 D的递推计算公式,还需计算出D的初值。 ∵ 圆弧的起点为(0,R) ∴ D的初值为:
D = (0+1)2 +(R-1)2-R2 = 2 (1-R)
BresenhamCircle(r, color)
填充。
王选。
TrueType技术
Windows的字库
二次Bezier曲线描述轮廓, 控制点按顺时针方向编号。
使用时先生成轮廓,再在内部填充形成点阵 信息,显示或输出。
例子
H的TrueType字库控制信息 X方向 Y方向
标准字符集
• ASCII
• 共127个。 • 0-31 不可见,控制字符。 • 32-127可见(大小写字母,数字,运算
象素入栈多次,栈要很大的空间。
扫描线填充算法
沿扫描线,在扫描线与多边形的相交区间内填充。
只取一个种子象素。
种子象素入栈;当栈非空时执行以下四步操作:
1 栈顶元素出栈;
2 沿扫描线对出栈象素的左右象素进行填充,直至遇到边 界象素为止。即对每个出栈象素,对包含该象素的整个区 间进行填充。
}/*end of switch*/ }/*end of while*/ }/*end of BresenhamCircle*/
Bresenham快速画直线算法_20140523

Bresenham快速画直线算法一、算法原理简介:算法原理的详细描述及部分实现可参考:http://www.cs.helsinki.fi/group/goa/mallinnus/lines/bresenh.html假设以(x, y)为绘制起点,一般情况下的直观想法是先求m = dy /dx(即x每增加1,y的增量),然后逐步递增x, 设新的点为x1 = x + j, 则y1 = round(y + j * m)。
可以看到,这个过程涉及大量的浮点运算,效率上是比较低的(特别是在嵌入式应用中,DSP可以一周期内完成2次乘法,一次浮点却要上百个周期)。
下面,我们来看一下Bresenham算法,如Fig. 1,(x, y +ε)的下一个点为(x, y + ε + m),这里ε为累加误差。
可以看出,当ε+m < 0.5时,绘制(x + 1, y)点,否则绘制(x + 1, y + 1)点。
每次绘制后,ε将更新为新值:ε = ε + m ,如果(ε + m) <0.5 (或表示为2*(ε + m) < 1)ε = ε + m – 1, 其他情况将上述公式都乘以dx, 并将ε*dx用新符号ξ表示,可得ξ = ξ + dy, 如果2*(ξ + dy) < dxξ = ξ + dy – dx, 其他情况可以看到,此时运算已经全变为整数了。
以下为算法的伪代码及实例:起点:(x1,y1)=(0,0),终点:(x2,y2)=(5,3)ξ← 0, y ← y1For x ← x1 to x2 doPlot Point at (x, y)If (2(ξ + dy) < dx)ξ←ξ + dy; y←y;Elsey ← y + 1,ξ←ξ + dy – dxEnd Ifx ←x+1;End For二、画图步骤如下:起点:(x1,y1)=(0,0),终点:(x2,y2)=(5,3); dx=5; dy=3;ξ=0;第一步:(1)ξ=0;x=x1=0; y=y1=0; 画点(x1,y1)=(0,0);(2)2(ξ + dy)= 2(0 + 3)=6>dx=5; 因此:y2=y+1=1; ξ=ξ+dy–dx=0+3-5=-2;X2=x1+1=1;第二步:(1)ξ=-2;x=x2=1; y=y2=1; 画点(x2,y2)=(1,1);(2)2(ξ + dy)= 2(-2 + 3)=2<dx=5; 因此:y3=y=1; ξ=ξ+dy=-2+3=1; X3=x+1=2;第三步:(1)ξ=1;x=x3=2; y=y3=1; 画点(x3,y3)=(2,1);(2)2(ξ + dy)= 2(1 + 3)=8>dx=5; 因此:y4=y+1=2; ξ=ξ+dy-dx=1+3-5=-1; X4=x+1=3;第四步:(1)ξ=-1;x=x4=3 y=y4=2; 画点(x4,y4)=(3,2);(2)2(ξ + dy)= 2(-1+ 3)=4<dx=5; 因此:y5=y=2; ξ=ξ+dy=-1+3=2; X5=x+1=4;第五步:(1)ξ=2;x=x5=4; y=y5=2; 画点(x5,y5)=(4,2);(2)2(ξ + dy)= 2(2 + 3)=10>dx=5; 因此:y6=y+1=3; ξ=ξ+dy-dx=2+3-5=0; X6=x+1=5;第六步:(1)ξ=0;x=x6=5; y=y6=3; 画点(x6,y6)=(5,3);x1x2x3x4x5x6三、算法的注意点:在实际应用中,我们会发现,当dy > dx或出现Fig.2 右图情况时时,便得不到想要的结果,这是由于我们只考虑dx > dy,且x, y的增量均为正的情况所致。
[整理]案例2-直线中点bresenham算法
![[整理]案例2-直线中点bresenham算法](https://img.taocdn.com/s3/m/b927966a83d049649a665820.png)
[整理]案例2-直线中点bresenham算法课程实验报告课程名称计算机图形学班级实验日期姓名学号实验成绩实验名称直线中点Bresenham算法实斜率0?k?1直线的中点Bresenham算法。
验任意斜率直线段绘制算法。
目颜色类的定义不调用方法。
的直线类的定义不调用方法。
及鼠标按键消息映射方法。
要求1、案例描述实在屏幕客户区内按下鼠标左键赞扬直线的起点,移动鼠标指针到直线验终点上,弹起鼠标左键绘制任意斜率的直线段。
内 2、功能说明容,1,设计CRGB类其成员变量为double型的红绿蓝分量red,green和blue,将red,green和blue分量分别规范到[0,1]区间。
,2,设计Cline直线类,其成员变量为直线段的起点坐标P0和终点坐标P1,成员函数为MoveTo()和LineTo()函数。
,3,Cline类的LineTo()函数使用中点Bresenham算法绘制任意斜率的直线段,包括k=??,k>1,错误!未找到引用源。
0???1, -1??<0和k<-1这5种情况。
,4,自定义屏幕二维坐标系,原点位于客户区中心,x轴水平向右为正,y轴垂直向上为正。
直线段的起点坐标和终点坐标相对于屏幕客户区中心定义。
1、案例分析算 MFC提供的CDC类的成员函数MoveTo()和LineTo()函数用于绘制傻法任意斜率的直线段,直线段的颜色由所选用的画笔指定。
MoveTo()函数移描动当前点到参数(x,y)所指定的点,不画线;LineTo()函数从当前点画一述直线段到参数(x,y)所指定的点,但不包括(x,y)。
本案例通过定义Cline类来模拟CDC类绘制任意斜的直线段,采用直线中点Bresenham算法。
2、算法设计对于0???1的直线段,中点Bresenham算法如下:,1,使用鼠标选择起点坐标p0(x0,y0)和终点坐标p1(x1,y1)。
要求起点的的坐标小于等于终点的x坐标。
案例2直线中点Bresenham算法

总结
主教材《计算机图形学基础教程(Visual C++版)》中仅 介绍了斜率0≤k≤1直线段的中点Bresenham扫描转换算法。
本案例基于该算法实现的CLine类的成员函数类似于CDC
类的MoveTo()函数和LineTo()函数,可以使用鼠标绘制任意斜 率的直线段。
案例描述
在窗口客户区内按下鼠标左键选择直线
的起点,移动鼠标指针到直线终点,弹起鼠
标左键绘制任意斜率的直线段。
效果图
图2-1 效果图
原理算法
MFC提供的CDC类的成员函数MoveTo()和LineTo()函
数用于绘制任意斜率的直线段,直线段的颜色由所选用的 画笔指定。MoveTo()函数移动当前点到参数(x,y)所指定 的点,不画线;LineTo()函数从当前点画一直线段到参数( x,y)所指定的点,但不包括(x,y)点。
计算机图形学实践教程(VisualC++版)(第2版)
案例2 直线中点Bresenham算法
孔令德 太原工业学院计算机工程系 2017.1.10
知识点
斜率0≤k≤1直线的中点Bresenham算法。
任意斜率直线段绘制算法。 颜色类的定义与调用方法。 直线类的定义与调用方法。 鼠标按键消息映射方法。
原理算法
图2-2 直线段的斜率对称性
程序代码
d=0.5-k; for(p=P0;p.x<P1.x;p.x++) { pDC->SetPixelV(Round(p.x),Round(p.y), RGB(clr.red*255,clr.green*255,clr.blue*255)); if(d<0) { p.y++; d+=1-k; } else d-=k; } }
bresenham算法画直线例题

Bresenham算法是计算机图形学中常用的一种画直线的算法。
它的原理是利用像素点在屏幕上的排列规律,从而高效地计算出直线上的像素点。
本文将以一个具体的例题来说明Bresenham算法的原理及应用。
1. 问题描述假设我们需要在一个分辨率为800x600的屏幕上,画一条直线,起点坐标为(100, 200),终点坐标为(400, 300)。
请使用Bresenham算法计算直线上的像素点,并用符号“*”表示出来。
2. Bresenham算法原理Bresenham算法的核心思想是利用像素点的整数坐标值与直线的斜率之间的关系,从而逐个确定直线上的像素点。
具体步骤如下:- 计算直线的斜率k,即k = (y2 - y1) / (x2 - x1),其中(x1, y1)为起点坐标,(x2, y2)为终点坐标。
- 以起点坐标作为初始值,从左至右依次求解直线上各点像素的坐标。
- 对于每一个x坐标,根据斜率k的大小确定y坐标的增长方向。
3. Bresenham算法应用根据上述原理,我们来解决具体的例题。
计算直线的斜率k:k = (300 - 200) / (400 - 100) = 1/3以起点坐标(100, 200)作为初始值,从左至右依次求解直线上各点像素的坐标。
当x坐标从100递增至400时,y坐标的增长方向由斜率k来确定。
具体计算如下:- 当x=100时,y=200- 当x=101时,y=200+1/3≈200- 当x=102时,y=200+2/3≈201- ...- 当x=400时,y=300现在,我们可以得到直线上的像素点坐标,并用符号“*”表示出来。
4. 结果展示根据上述计算,我们可以得到该直线上的像素点坐标,展示如下:(100, 200) *(101, 200) *(102, 201) *...(400, 300) *通过Bresenham算法,我们成功地计算出了直线上的像素点,并用符号“*”进行了展示。
中点bresenham算法斜率大于1例题

随着计算机图形学的发展,Bresenham算法作为一种高效的直线扫描算法被广泛应用。
本文将结合中点Bresenham算法和斜率大于1的具体例题,深入探讨其原理及应用。
1. 中点Bresenham算法中点Bresenham算法是一种用于绘制直线的算法,其特点是高效、精确。
该算法通过在每个x处选择最接近直线的y坐标,从而实现了高效的直线绘制。
中点Bresenham算法的原理可用以下步骤描述:1)假设直线连接点A(x0, y0)和点B(x1, y1)。
2)计算直线斜率m = (y1-y0)/(x1-x0)。
3)设置初始值x=x0, y=y0。
4)计算决策参数P0 = 2*(y1-y0) - (x1-x0)。
5)循环执行以下步骤直至x达到x1:a) 如果P0<0,则选择点(x+1, y),即决策参数P0 = P0 + 2*(y1-y0)。
b) 如果P0>=0,则选择点(x+1, y+1),即决策参数P0 = P0 + 2*(y1-y0) - 2*(x1-x0)。
2. 斜率大于1的例题假设有一条直线连接点A(2, 5)和点B(7, 10),斜率m = (10-5)/(7-2) = 1。
我们可以通过中点Bresenham算法来绘制这条直线,具体步骤如下:1)设定初始值 x=2, y=5;2)计算初始的决策参数P0 = 2*(10-5) - (7-2) = 10;3)根据决策参数P0的值来确定下一个点的位置:a) 当P0<0时,选择点(3, 5),更新P0 = P0 + 10 = 20;b) 当P0>=0时,选择点(4, 6),更新P0 = P0 + 10 - 10 = 20;c) 重复上述步骤直至x=7。
3. 结论通过上述例题的分析,我们可以看出中点Bresenham算法在斜率大于1的情况下同样适用,并且能够高效地绘制直线。
其原理简单易懂,应用广泛,是计算机图形学领域的重要算法之一。
《图形学》实验七:中点Bresenham算法画椭圆

《图形学》实验七:中点Bresenham算法画椭圆VC++6.0,OpenGL使⽤中点Bresenham算法画椭圆。
1 #include <gl/glut.h>23#define WIDTH 5004#define HEIGHT 5005#define OFFSET 15 //偏移量,偏移到原点6#define A 67#define B 589void Init() //其它初始化10 {11 glClearColor(1.0f,1.0f,1.0f,1.0f); //设置背景颜⾊,完全不透明12 glColor3f(1.0f,0.0f,0.0f); //设置画笔颜⾊1314 glMatrixMode(GL_PROJECTION);15 glLoadIdentity();16 gluOrtho2D(0.0, 30.0, 0.0, 30.0);17 glMatrixMode(GL_MODELVIEW);18 }1920void MidBresenhamEllipse(int a,int b) //中点Bresenham算法画椭圆21 {22int x,y;23float d1,d2;24 x = 0;y = b;25 d1=b*b+a*a*(-b+0.25);26 glPointSize(5); //设置画笔尺⼨2728 glBegin(GL_POINTS);29 glVertex2i(OFFSET+x,OFFSET+y);30 glVertex2i(OFFSET-x,OFFSET-y);31 glVertex2i(OFFSET-x,OFFSET+y);32 glVertex2i(OFFSET+x,OFFSET-y);33 glEnd();3435while(b*b*(x+1) < a*a*(y-0.5)){36if(d1<=0){37 d1+=b*b*(2*x+3);38 x++;39 }40else{41 d1+=b*b*(2*x+3)+a*a*(-2*y+2);42 x++;43 y--;44 }45 glBegin(GL_POINTS);46 glVertex2i(OFFSET+x,OFFSET+y);47 glVertex2i(OFFSET-x,OFFSET-y);48 glVertex2i(OFFSET-x,OFFSET+y);49 glVertex2i(OFFSET+x,OFFSET-y);50 glEnd();51 }//while上半部分52 d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;53while(y>0){54if(d2<=0){55 d2+=b*b*(2*x+2)+a*a*(-2*y+3);56 x++,y--;57 }58else{59 d2+=a*a*(-2*y+3);60 y--;61 }62 glBegin(GL_POINTS);63 glVertex2i(OFFSET+x,OFFSET+y);64 glVertex2i(OFFSET-x,OFFSET-y);65 glVertex2i(OFFSET-x,OFFSET+y);66 glVertex2i(OFFSET+x,OFFSET-y);67 glEnd();68 }69 }7071void Display()72 {73 glClear(GL_COLOR_BUFFER_BIT); //清空颜⾊堆栈7475 MidBresenhamEllipse(A,B); //画⼀个半径为8的椭圆7677 glFlush(); //清空缓冲区指令78 }7980int main(int argc,char** argv)81 {82 glutInit(&argc,argv);83 glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); //初始化显⽰模式84 glutInitWindowSize(WIDTH,HEIGHT); //初始化窗⼝⼤⼩85 glutInitWindowPosition(200,100); //初始化窗⼝出现位置86 glutCreateWindow("中点Bresenham画椭圆"); //初始化窗⼝标题8788 glutDisplayFunc(Display); //注册显⽰函数89 Init(); //其它初始化90 glutMainLoop(); //进⼊程序循环9192return0;93 }Freecode :。
Bresenham算法-直线光栅化算法

Bresenham算法是计算机图形学典型的直线光栅化算法。
∙从另一个角度看直线光栅化显示算法的原理o由直线的斜率确定选择在x方向或y方向上每次递增(减)1个单位,另一变量的递增(减)量为0或1,它取决于实际直线与最近光栅网格点的距离,这个距离的最大误差为0.5。
∙1)Bresenham的基本原理o假定直线斜率k在0~1之间。
此时,只需考虑x方向每次递增1个单位,决定y方向每次递增0或1。
设直线当前点为(xi,y)直线当前光栅点为(xi,yi)则下一个直线的点应为(xi+1,y+k)下一个直线的光栅点或为右光栅点(xi+1,yi)(y方向递增量0)或为右上光栅点(xi+1,yi+1)(y方向递增量1)记直线与它垂直方向最近的下光栅点的误差为d,有:d=(y+k)–yi,且0≤d≤1当d<0.5:下一个象素应取右光栅点(xi+1,yi)当d≥0.5:下一个象素应取右上光栅点(xi+1,yi+1)如果直线的(起)端点在整数点上,误差项d的初值:d0=0,x坐标每增加1,d的值相应递增直线的斜率值k,即:d=d + k。
一旦d≥1,就把它减去1,保证d的相对性,且在0-1之间。
令e=d-0.5,关于d的判别式和初值可简化成:e的初值e0= -0.5,增量亦为k;e<0时,取当前象素(xi,yi)的右方象素(xi+1,yi);e>0时,取当前象素(xi,yi)的右上方象素(xi+1,yi+1);e=0时,可任取上、下光栅点显示。
Bresenham算法的构思巧妙:它引入动态误差e,当x方向每次递增1个单位,可根据e 的符号决定y方向每次递增 0 或 1。
e<0,y方向不递增e>0,y方向递增1x方向每次递增1个单位,e = e + k因为e是相对量,所以当e>0时,表明e的计值将进入下一个参考点(上升一个光栅点),此时须:e = e - 1∙2)Bresenham算法的实施——Rogers 版o通过(0,0)的所求直线的斜率大于0.5,它与x=1直线的交点离y=1直线较近,离y=0直线较远,因此取光栅点(1,1)比(1,0)更逼近直线;o如果斜率小于0.5,则反之;o当斜率等于0.5,没有确定的选择标准,但本算法选择(1,1)(程序)▪//Bresenham's line resterization algorithm for the first octal.▪//The line end points are (xs,ys) and (xe,ye) assumed not equal.▪// Round is the integer function.▪// x,y, ∆x, ∆y are the integer, Error is the real.▪//initialize variables▪x=xs▪y=ys▪∆x = xe -xs▪∆y = ye -ys▪//initialize e to compensate for a nonzero intercept▪Error =∆y/∆x-0.5▪//begin the main loop▪for i=1 to ∆x▪ WritePixel (x, y, value)▪if (Error ≥0) then▪ y=y+1▪ Error = Error -1▪ end if▪ x=x+1▪ Error = Error +∆y/∆x▪next i▪finish∙3)整数Bresenham算法o上述Bresenham算法在计算直线斜率和误差项时要用到浮点运算和除法,采用整数算术运算和避免除法可以加快算法的速度。