Bresenham直线生成算法

Bresenham直线

算法思想:
设直线的起点为(x1, y1),终点为(x2, y2),则直线可表示为方程 y=mx+b,其中 b=y1-m∙x1, m = (y2-y1)/(x2-x1)=dy/dx。

首先讨论直线方向位于1a象限(),在这种情况下,当直线光栅化时,x每次都增加1个单元,即xi+1 = xi + 1,而y的相应增加值是多什么呢?

为了光栅化,yi+1只可能选择下图两种位置之一
Bresenham直线生成算法_第1张图片

yi+1的位置选择yi+1 =yi或者yi+1=yi+1,选择的原则是看精确值y与yi及yi+1的距离d1及d2的大小而定。

计算公式为
y = m(xi + 1) + b (2.1)
d1 = y - yi (2.2)
d2 = yi +1 - y (2.3)
如果d1-d2>0,则yi+1=yi+1,
否则yi+1=yi.

将式(2.1)、(2.2)、(2.3)代入d1-d2,再用dx乘等式两边,并以Pi=(d1-d2) dx代入上述等式,得

Pi = 2xidy-2yidx+2dy+(2b-1) dx

d1-d2是用以判断符号的误差。由于在1a象限,dx总大于0,所以Pi仍旧可以用作判断符号的误差。
Pi>0,则yi+1=yi+1,否则yi+1=yi.

求误差的初值P1,可将x1、y1和b代入式中的xi、yi而得到
P1 = 2dy-dx

综述上面的推导,第1a象限内的直线Bresenham算法思想如下:

  1. 计算两个方向的变化量:dx = x2- x1,dy= y2- y1.
  2. 计算误差初值P= 2dy-dx
  3. 求直线的下一点位置 xi+1 = xi + 1如果Pi>0,则yi+1=yi+1,否则yi+1=yi
  4. 画点(xi+1, yi+1);
  5. 然后进入循环 i=i+1求下一个误差如果Pi>0,则Pi+1=Pi+2dy-2dx,否则Pi+1=Pi+2dy;
    i

代码如下:

#include "graphics.h"
#include 
#include "windows.h"
#include 

void lineBres(int x0, int y0, int xEnd, int yEnd,int c)
{
        int dx = fabs (xEnd -x0), dy = fabs (yEnd-y0);
        int p =2* dy-dx;
        int twoDy = 2*dy, twoDyMinusDx = 2* (dy - dx);
        int x,y;

        if (x0>xEnd)
        {
                x=xEnd;
                y=yEnd;
                xEnd=x0;
        }
        else{
                x=x0;
                y=y0;
        }
        putpixel (x,y,c);

        while (x

最终效果:
Bresenham直线生成算法_第2张图片

你可能感兴趣的:(Bresenham直线生成算法)