之前需要一个算法实现获取两个端点的线段上的点的位置,所以找了一些画线算法。
参考了这位博主的内容,顺便补充和完善了一下。
给定两个点起点P1(x1, y1), P2(x2, y2),如何画它们直连的直线呢,即是如何得到上图所示的蓝色的点。假设直线的斜率0<k>0,直线在第一象限,Bresenham算法的过程如下:
1.画起点(x1, y1).
2.准备画下一个点,X坐标加1,判断如果达到终点,则完成。否则找下一个点,由图可知要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点。
2.1.如果线段ax+by+c=0与x=x1+1的交点y坐标大于(y+*y+1))/2则选右上那个点
2.2.否则选右下那个点。
3.画点
4.跳回第2步
5.结束
具体的算法包含所有象限的代码如下:
void DrawBresenhamline(int x0, int y0, int x1, int y1)
{
int dx = x1 - x0;//x偏移量
int dy = y1 - y0;//y偏移量
int ux = dx >0 ? 1 : -1;//x伸展方向
int uy = dy >0 ? 1 : -1;//y伸展方向
int dx2 = abs(dx << 1);//x偏移量乘2
int dy2 = abs(dy << 1);//y偏移量乘2
if (abs(dx)>abs(dy))//以x为增量方向计算
{
int e = -dx; //e = -0.5 * 2 * dx,把e 用2 * dx* e替换
int x = x0;//起点x坐标
int y = y0;//起点y坐标
while (x!=x1+ux)
{
printf("%d,%d\n", x, y);
e = e + dy2;//来自 2*e*dx= 2*e*dx + 2dy (原来是 e = e + k)
if (e > 0)//e是整数且大于0时表示要取右上的点(否则是右下的点)
{
if (y!=y1)
{
y += uy;
}
e = e - dx2;//2*e*dx = 2*e*dx - 2*dx (原来是 e = e -1)
}
x += ux;
}
}
else
{//以y为增量方向计算
int e = -dy; //e = -0.5 * 2 * dy,把e 用2 * dy* e替换
int x = x0;//起点x坐标
int y = y0;//起点y坐标
while (y!=y1+uy)
{
printf("%d,%d\n", x, y);
e = e + dx2;//来自 2*e*dy= 2*e*dy + 2dy (原来是 e = e + k)
if (e > 0)//e是整数且大于0时表示要取右上的点(否则是右下的点)
{
if (x!=x1)
{
x += ux;
}
e = e - dy2;//2*e*dy = 2*e*dy - 2*dy (原来是 e = e -1)
}
y += uy;
}
}
}