图形学-中点Bresenham算法

图形学-中点Bresenham算法

  • 原理
  • 代码
  • 例子

原理

由Bresenham提出的直线生成算法的基本原理是,每次在最大位移方向上走一步,而另一个方向是走步还是不走步取决于误差项的判别。

图形学-中点Bresenham算法_第1张图片

这时直线将平面分成三个区域:对于直线上的点,F(x,y)=0;对于直线上方的点,F(x,y)>0;对于直线下方的点,F(x,y)<0,如下图所示。

图形学-中点Bresenham算法_第2张图片

首先假设0≤k≤1,由于x是最大位移方向,因此每次在x方向上加1,y方向上或加1 或加0。假定当前点是P(xi,yi),则下一个点在pu(xi+1,yi+1)与pd(xi+1,yi)中选一。以M表示pu和pd的终点即M(xi+1,yi+0.5)。又设Q是理想直线与垂直线x=xi+1的交点。显然,若M在Q的下方,则pu(xi+1,yi+1)离直线近,应取为下一个像素,否则应取Pd(xi+1,yi)。
图形学-中点Bresenham算法_第3张图片
所以如前所述,欲判断Q在M的上方还是下方,只要把M代入F(x,y),并判断它的符号即可。
在这里插入图片描述
如上构造判别式,当di<0时,M在直线下方,故应取Pu。当di>0时,应取正右方的Pd。当di=0时,
两者一样合适,可以随便取一个。
所以现在根据上面的判别式对误差项进行递推
当di<0时,取右上方像素Pu,欲判断再下一个像素应该取那个应计算
图形学-中点Bresenham算法_第4张图片
此时di的增量为1-k
当di≥0时,取右上方像素Pd,欲判断再下一个像素应该取那个应计算
图形学-中点Bresenham算法_第5张图片

下面进行di的初值计算。显然直线的第一个像素P(x0,y0)在直线上,因此响应的di的初始值计算如下
图形学-中点Bresenham算法_第6张图片
但是这其中仍然有小数,由于我们使用的只是di的符号,因此可以用2di△x摆脱小数
图形学-中点Bresenham算法_第7张图片
这样Bresenham算法的绘图过程如下
图形学-中点Bresenham算法_第8张图片
Bresenham算法对任意斜率的直线段具有通用性,对于斜率为整且大于1的直线段,只需要交换x和y之间的规则。对于负斜率,除了一个坐标递减而另一个坐标地政外,其余程序是类似的。

代码

void MidBresenhamLine(int x0, int y0, int x1, int y1, int color)
{
 int dx, dy, d, UpIncre, DownIncre, x, y;
 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;
 d = dx - 2 * dy;
 UpIncre = 2 * dx - 2 * dy; DownIncre = -2 * dy;
 COLORREF c = RGB(250, 250, 250);
 while (x <= x1)
 {
  putpixel(x, y, c);
  x++;
  if (d < 0)
  {
   y++;
   d += UpIncre;
  }
  else
   d += DownIncre;
 }
}

例子

图形学-中点Bresenham算法_第9张图片
图形学-中点Bresenham算法_第10张图片

你可能感兴趣的:(计算机图形学,计算机视觉)