Bresenham直线生成算法详解

基本思想

        比较从理想直线到位于直线上方的像素的距离t和相邻的位于直线下方的像素的距离s,根据距 离误差项的符号确定与理想直线最近的像素,如下图所示:

简言之就是判断t和s哪个点距离直线更近

判断 s-t 的大小

        已知当前的像素的中心点坐标为(xi,yi),根据 s-t 的值来判断下一步的点所在位置。详细计算推导过程如下:

\because 设位于s、t之间直线的坐标(x,y),得到  s=y-y_{i} , t=y_{i}+1-y

\therefore s-t=y-y_{i}-(y_{i}+1-y)=2y-2y_{i}-1

\because  x_{i}=x_{i+1} 时,真实的直线y值为:y=m\left ( x_{i}+1 \right )+b ,

\therefore 2y-2y_{i}-1=2(mx_{i}+m+b)-2y_{i}-1

\because m代表直线的斜率(slope),故m=\frac{\Delta y}{\Delta x},

\therefore  在原式两边同时乘上\Delta x,原式 = \Delta x(s-t)=2\Delta yx_{i}+2\Delta y+2\Delta xb-2\Delta xy_{i}-\Delta x

\because 我们的目的是判断 s-t 是大于0的还是小于0的,且由于\Delta x恒大于0,所以我们可以令

d_{i}=\Delta x(s-t) ,此时 d_{i} s-t 正负方向一致,可以用来代替 s-t 来判断其大小。由于判断的是正负性,所以一些已知项可以当成常数C来看。

\therefore d_{i}=2\Delta yx_{i}-2\Delta xy_{i}+C

此时d_{i+1}=2\Delta yx_{i+1}-2\Delta xy_{i+1}+C

联立两个式子,注意代入 x_{i+1}=x_{i}+1,然后求 d_{i+1}-d_{i} ,结果得到:

d_{i+1}-d_{i}=2\Delta y-2\Delta x\left ( y_{i+1}-y_{i} \right )

\because 当我们选择直线上方的点的话,那么 d_{i}>0 ,y_{i+1}-y_{i}=1,此时

d_{i+1}=d_{i}+2(\Delta y-\Delta x) ;

反之 d_{i+1}=d_{i}+2\Delta y

\therefore 最终推出以下式子:

d_{i+1}=\left\{\begin{matrix} d_{i}+2(\Delta y-\Delta x) , d_{i}\geq 0 \\\\ d_{i}+2\Delta y , d_{i}< 0 \end{matrix}\right.

此时 d_{i+1} 就代表了 s-t 的正负性,当 d_{i}\geq 0 ,代表了 比 大,所以要取上面的一格,即y_{i+1}=y_{i}+1 ; 反之取的格子位置不变,即 y_{i+1}=y_{i} 。

接下来看一道例题,来体会一下breseham算法的应用。

例题

首先先画好直线段:

接着通过求x,y,d_{i} 三个变量的值来确定像素的坐标位置:

第一个像素点位置就是起点,即(0,0),x_{1}=0,y_{1}=0

初始的误差值d_{1} ,由前面的式子 d_{i}=2\Delta yx_{i}+2\Delta y+2\Delta xb-2\Delta xy_{i}-\Delta x,令 i = 1

得:

 d_{1}=2\Delta yx_{1}+2\Delta y+2\Delta xb-2\Delta xy_{1}-\Delta x=2\Delta yx_{1}+2\Delta y+2\Delta xb-2\Delta x(\frac{\Delta y}{\Delta x})-\Delta x=2\Delta y-\Delta x

所以得值 d_{1} = 2\Delta y-\Delta x = -1。

综上第一个点,三个参数是x_{1}=0,y_{1}=0,d_{1}=-1

第二个点,x一定往右一格,所以此时x_{1}=1

因为上一格求得的误差d_{1}=-1< 0,所以此时 y_{i+1}=y_{i},即y_{2}=0

由于d_{1}< 0,故 d_{2}=d_{i}+2\Delta y=3

综上第二个点,三个参数是x_{2}=1,y_{2}=0,d_{2}=3

第三个点,x一定往右一格,所以此时x_{2}=2

因为上一格求得的误差d_{2}=3> 0,所以此时 y_{i+1}=y_{i}+1,即y_{3}=1

由于d_{2}> 0,故 d_{3}=d_{i}+2(\Delta y-\Delta x)=-3

综上第三个点,三个参数是x_{2}=2,y_{2}=1,d_{3}=-3

依次类推······

结果如图:

 得到的坐标依次为(0,0) (1,0) (2,1) (3,1) (4,2) (5,2)

根据坐标填充像素:

 此时,breseham算法生成直线像素已完成。

代码描述(C语言伪代码)

//Bresenham
void Bes_line(int x0,int y0,int x1,int y1){
	int dx,dy,h,x,y;
	dx=abs(x0-x1);
	dy=abs(y0-y1);
	h=2*dy-dx;
	x=x0;
	y=y0;

	glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_POINTS);  
    glVertex2f(x,y);	
	while (x<x1)
	{
		if(h<0)  h+=2*dy;
		else{
			h=+2*(dy-dx);
			y++;
		}
		glVertex2f(x,y);		
		x++;
	}
	glEnd();
}

Bresenham算法的优点

  • 不用计算斜率,不涉及到浮点数的运算。 

  • 计算中涉及到的全部是整数

  • 乘法运算只有乘以2,可以用移位运算来实现。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值