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只可能选择下图两种位置之一

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<x2则跳出循环结束绘制。

代码如下:

#include "graphics.h"
#include <conio.h>
#include "windows.h"
#include <math.h>

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<xEnd)
        {
                x++;
                if(p<0)
                        p+=twoDy;
                else{
                        y++;
                        p+=twoDyMinusDx;
                }
               putpixel (x,y,c);
       }

}

void main()
{
	 int gd=DETECT,gm; /*图形屏幕初始化*/
	initgraph(&gd,&gm,"");
	lineBres(0,0,500,300,YELLOW);
	lineBres(0,0,500,400,BLUE);
	getch();
 	closegraph();
}


最终效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值