我正在寻找一种算法(用Java编码会很好,但是任何足够清晰的转换为Java都可以)来绘制一条4连接线。似乎Bresenham's algorithm是使用最广泛的,但我发现的所有可理解的实现都是8连接的。 OpenCV的cvline函数显然有一个4连接版本,但对我来说,源代码是一个平庸而且几乎是C文盲的程序员,难以理解。其他各种搜索都没有发现。
感谢任何人提供的任何帮助。
答案 0 :(得分:14)
以下是类似Bresenham的算法,它绘制了4条连线。代码是用Python编写的,但我想即使你不懂语言也可以轻松理解。
def line(x0, y0, x1, y1, color):
dx = abs(x1 - x0) # distance to travel in X
dy = abs(y1 - y0) # distance to travel in Y
if x0 < x1:
ix = 1 # x will increase at each step
else:
ix = -1 # x will decrease at each step
if y0 < y1:
iy = 1 # y will increase at each step
else:
iy = -1 # y will decrease at each step
e = 0 # Current error
for i in range(dx + dy):
draw_pixel(x0, y0, color)
e1 = e + dy
e2 = e - dx
if abs(e1) < abs(e2):
# Error will be smaller moving on X
x0 += ix
e = e1
else:
# Error will be smaller moving on Y
y0 += iy
e = e2
想法是绘制一条线,你应该用一个与理论线的DX / DY相匹配的比例增加X和Y.要做到这一点,我首先将错误变量e
初始化为0(我们在线),并在每一步检查错误是否更低如果我只增加X或如果我只增加Y(Bresenham检查是在仅改变X或X和Y两者之间进行选择)。
执行此检查的天真版本将添加1/dy
或1/dx
,但将所有增量乘以dx*dy
只允许使用整数值,这样可以提高速度和准确性,还可以避免需要dx==0
或dy==0
的特殊情况,从而简化逻辑。
当然,因为我们正在寻找比例误差,所以使用缩放的增量不会影响结果。
无论线象限是什么,增量的两种可能性总是会对误差产生不同的符号效应......所以我的任意选择是增加X步的误差并减小Y步的误差。 / p>
ix
和iy
变量是该行所需的实际方向(+1或-1),具体取决于初始坐标是低于还是高于最终坐标。
在4连线中绘制的像素数显然是dx+dy
,所以我只需要多次循环绘制线而不是检查我是否到达终点。请注意,此算法绘制除最后一个像素之外的所有像素;如果您还想要最终像素,则应在循环结束后添加额外的draw_pixel
调用。
以下图片中可以看到上述实现的示例结果
答案 1 :(得分:6)
对于Python-illiterate,这是6502代码的C版本:
void drawLine(int x0, int y0, int x1, int y1) {
int dx = abs(x1 - x0);
int dy = abs(y1 - y0);
int sgnX = x0 < x1 ? 1 : -1;
int sgnY = y0 < y1 ? 1 : -1;
int e = 0;
for (int i=0; i < dx+dy; i++) {
drawPixel(x0, y0);
int e1 = e + dy;
int e2 = e - dx;
if (abs(e1) < abs(e2)) {
x0 += sgnX;
e = e1;
} else {
y0 += sgnY;
e = e2;
}
}
}