Bresenham 画线算法是由Bresenham提出的一种精确而有效的光栅线生成算法,该算法仅仅使用了
整数的增量来实现的。
Bresenham算法将对整形参数的符号检测,整形参数的值比于实际险段之间的偏量。
Bresenham算法内容
对于直线方程 Y = kX + b;
A,0< 斜率 < 1 时候的算法
1,输入线段的两个端点Point1和Point2,并且存储到Point1(x1,y1)和Point2(x2,y2)中;
2,将Point1载入桢缓存,绘画第一个起始点;
3,计算常量△x、△y、2△y和2(△y-△x),并且获得一个决策参数的第一个值:P = 2△y - △x;
4,从n = 0开始,在沿线经过每个Xn处,进行下面的监测:
如果Pn< 0, 下一个点绘制的是(Xn+1,yn),并且Pn+1= Pn + 2△y
如果P0>= 0 ,下一个点绘制的是(Xn+1,Yn+1),并且Pn+1 = Pn + 2(△y-△x)
5,重复执行△x-1次步骤4;
关于在C++中的算法如下实例:
#include
<
iostream
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
using
namespace
std;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
Bresenham(
int
x1,
int
y1,
int
x2,
int
y2)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int dx = x2 - x1;//△x
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int dy = y2 - y1;//△y
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int p = (2*dy) - dx ; //P = 2△y - △x
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int dobDy = 2* dy ; // 2 △y
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int dobD = 2*(dy - dx) ; // 2(△y - △x)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int PointX,PointY;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
//设置两个临时用来显示位置的变量
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if( x1 > x2)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//判断线段的方向
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
PointX = x2;//起始坐标X
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
PointY = y2;/**/////起始坐标Y
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
x2 = x1;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
PointX = x1;//起始坐标X
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
PointY = y1;//起始坐标Y
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
// 达到第一个起始点
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<"Point: X:"<<PointX<<" Y:"<<PointY<<endl;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
while (PointX<x2)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
PointX++;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
if (p < 0)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
p += dobDy;
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
PointY++;
p += dobD;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
cout<<"Point: X:"<<PointX<<" Y:"<<PointY<<endl;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
main()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
//绘画线段(2,2)点到(60,50)需要的点
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
Bresenham(2,2,60,50);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return 0;
}
B,斜率 k = 1 或这斜率 k = 0 时候的算法
对于斜率=0或者斜率=1时候,不需要通过算法直接的对于其中单一坐标变量进行处理就可以。
C, 斜率 k < 0 的情况算法
将起始点和中止点坐标Point1和Point2交换,可以转化到斜率为0和1之内的算法去实现。