from math import floor
def sign(n):
return (n > 0) - (n < 0)
def raytrace(A, B):
""" Return all cells of the unit grid crossed by the line segment between
A and B.
"""
(xA, yA) = A
(xB, yB) = B
(dx, dy) = (xB - xA, yB - yA)
(sx, sy) = (sign(dx), sign(dy))
grid_A = (floor(A[0]), floor(A[1]))
grid_B = (floor(B[0]), floor(B[1]))
(x, y) = grid_A
traversed=[grid_A]
tIx = dy * (x + sx - xA) if dx != 0 else float("+inf")
tIy = dx * (y + sy - yA) if dy != 0 else float("+inf")
while (x,y) != grid_B:
# NB if tIx == tIy we increment both x and y
(movx, movy) = (tIx <= tIy, tIy <= tIx)
if movx:
# intersection is at (x + sx, yA + tIx / dx^2)
x += sx
tIx = dy * (x + sx - xA)
if movy:
# intersection is at (xA + tIy / dy^2, y + sy)
y += sy
tIy = dx * (y + sy - yA)
traversed.append( (x,y) )
return traversed
if __name__ == '__main__':
print(raytrace( (1,1.5) , (4,1.5) ))
print(raytrace( (1,1.5) , (5,2.5) ))
ZnJvbSBtYXRoIGltcG9ydCBmbG9vcgpkZWYgc2lnbihuKToKICAgIHJldHVybiAobiA+IDApIC0gKG4gPCAwKQoKZGVmIHJheXRyYWNlKEEsIEIpOgogICAgIiIiIFJldHVybiBhbGwgY2VsbHMgb2YgdGhlIHVuaXQgZ3JpZCBjcm9zc2VkIGJ5IHRoZSBsaW5lIHNlZ21lbnQgYmV0d2VlbgogICAgICAgIEEgYW5kIEIuCiAgICAiIiIKCiAgICAoeEEsIHlBKSA9IEEKICAgICh4QiwgeUIpID0gQgogICAgKGR4LCBkeSkgPSAoeEIgLSB4QSwgeUIgLSB5QSkKICAgIChzeCwgc3kpID0gKHNpZ24oZHgpLCBzaWduKGR5KSkKCiAgICBncmlkX0EgPSAoZmxvb3IoQVswXSksIGZsb29yKEFbMV0pKQogICAgZ3JpZF9CID0gKGZsb29yKEJbMF0pLCBmbG9vcihCWzFdKSkKICAgICh4LCB5KSA9IGdyaWRfQQogICAgdHJhdmVyc2VkPVtncmlkX0FdCgogICAgdEl4ID0gZHkgKiAoeCArIHN4IC0geEEpIGlmIGR4ICE9IDAgZWxzZSBmbG9hdCgiK2luZiIpCiAgICB0SXkgPSBkeCAqICh5ICsgc3kgLSB5QSkgaWYgZHkgIT0gMCBlbHNlIGZsb2F0KCIraW5mIikKCiAgICB3aGlsZSAoeCx5KSAhPSBncmlkX0I6CiAgICAgICAgIyBOQiBpZiB0SXggPT0gdEl5IHdlIGluY3JlbWVudCBib3RoIHggYW5kIHkKICAgICAgICAobW92eCwgbW92eSkgPSAodEl4IDw9IHRJeSwgdEl5IDw9IHRJeCkKICAgICAgICAKICAgICAgICBpZiBtb3Z4OgogICAgICAgICAgICAjIGludGVyc2VjdGlvbiBpcyBhdCAoeCArIHN4LCB5QSArIHRJeCAvIGR4XjIpCiAgICAgICAgICAgIHggKz0gc3gKICAgICAgICAgICAgdEl4ID0gZHkgKiAoeCArIHN4IC0geEEpCgogICAgICAgIGlmIG1vdnk6CiAgICAgICAgICAgICMgaW50ZXJzZWN0aW9uIGlzIGF0ICh4QSArIHRJeSAvIGR5XjIsIHkgKyBzeSkKICAgICAgICAgICAgeSArPSBzeQogICAgICAgICAgICB0SXkgPSBkeCAqICh5ICsgc3kgLSB5QSkKCiAgICAgICAgdHJhdmVyc2VkLmFwcGVuZCggKHgseSkgKQogICAgICAgIAogICAgcmV0dXJuIHRyYXZlcnNlZAoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIHByaW50KHJheXRyYWNlKCAoMSwxLjUpICwgKDQsMS41KSApKQogICAgcHJpbnQocmF5dHJhY2UoICgxLDEuNSkgLCAoNSwyLjUpICkpCiAgICA=
[(1, 1), (2, 1), (3, 1), (4, 1)]
[(1, 1), (2, 1), (3, 2), (4, 2), (5, 2)]