您的位置:首页 > 移动开发 > Unity3D

Unity学习(九)Bresenham快速画直线算法

2016-04-18 10:28 573 查看
在游戏中求直线,一般情况会想到通过斜率计算,但是这会涉及到大量的浮点运算,一旦玩家过多,还是会有比较大的消耗。

通常在电脑中画直线,圆形等各种形状并不是真正的直线,因为屏幕的像素非常小,所以肉眼看起来很像直线,其实都是由格子组成的。底层的算法比较多,这里就先学习Bresenham算法,它是光栅化的画直线算法。直线光栅化是指用像素点来模拟直线,如下图:



以上图为例,进行推导模拟:
1.起点为x1,y1时:y轴误差量为e1,e1+m=0.7>0.5,那么e2=e1+m-1=-0.3,y=y1+1=y2。
2.起点为x2,y2时:y轴误差量为e2,e2+m=-0.3+0.7=0.4,那么e3=e2+m=0.4,y=y2。
3.起点为x3,y2时:y轴误差量为e3,e3+m=0.4+0.7=1.1>0.5,那么e4=e3-1=0.1,y=y2+1=y3。
4.起点为x4,y3时:以此类推...知道x轴到达终点。
其中e+m>0.5,可以表示为2*(e+m) > 1
根据起点和终点可以得出x轴增量:dx。将上面的公式都乘以dx。
可以得到:
e= e*dx+m*dx = eps + dy
e= e+m-1 = eps+dy-dx

实现流程:
1.首先判断x,y的增量,谁大就累加谁。(上面是坐标系的左上方向)
2.循环累加x,累加误差量eps+dy
3.判断eps+dy是否大于dx,如果小于不做处理,如果大于等于dx,那么新的y=y+1,新的eps=eps-dx。
为了兼容xy坐标系的各个方向,我们可以先算出增量的方向,比如上面如果是坐标系的左下方向,y=y-1。

代码如下:

public bool LinePath(int x1, int y1, int x2, int y2, ref List mpaths)

{

int dx = x2 - x1;

int dy = y2 - y1;

int ux = (dx > 0) ? 1 : -1;

int uy = (dy > 0) ? 1 : -1;

int x = x1, y = y1, eps;

x2 += ux; y2 += uy;

eps = 0; dx = Mathf.Abs(dx); dy = Mathf.Abs(dy);

if (dx > dy)

{

for (x = x1; x != x2; x += ux)

{

mpaths.Add(new Vector2(x, y));

eps += dy;

if ((eps << 1) >= dx)

{

y += uy;

eps -= dx;

}

}

}

else

{

for (y = y1; y != y2; y += uy)

{

mpaths.Add(new Vector2(x, y));

eps += dx;

if ((eps << 1) >= dy)

{

x += ux; eps -= dy;

}

}

}

return true;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: