Source code for bravo.utilities.geometry

"""
Simple pixel graphics helpers.
"""

[docs]def gen_line_simple(point1, point2): """ An adaptation of Bresenham's line algorithm in three dimensions. This function returns an iterable of integer coordinates along the line from the first point to the second point. No points are omitted. """ # XXX should be done with ints instead of floats tx, ty, tz = point1.x, point1.y, point1.z # t is for temporary rx, ry, rz = int(tx), int(ty), int(tz) # r is for rounded ox, oy, oz = point2.x, point2.y, point2.z # o is for objective dx = ox - tx dy = oy - ty dz = oz - tz largest = float(max(abs(dx), abs(dy), abs(dz))) dx, dy, dz = dx / largest, dy / largest, dz / largest # We make a vector which maximum value is 1.0 yield rx, ry, rz while abs(ox - tx) > 1 or abs(oy - ty) > 1 or abs(oz - tz) > 1: tx += dx ty += dy tz += dz yield int(tx), int(ty), int(tz) yield ox, oy, oz
class HurpPoint(object): def __init__(self, t): self.x, self.y, self.z = t
[docs]def gen_close_point(point1, point2): """ Retrieve the first integer set of coordinates on the line from the first point to the second point. The set of coordinates corresponding to the first point will not be retrieved. """ point1 = HurpPoint(point1) point2 = HurpPoint(point2) g = gen_line_simple(point1, point2) next(g) return next(g)
[docs]def gen_line_covered(point1, point2): """ This is Bresenham's algorithm with a little twist: *all* the blocks that intersect with the line are yielded. """ tx, ty, tz = point1.x, point1.y, point1.z # t is for temporary rx, ry, rz = int(tx), int(ty), int(tz) # r is for rounded ox, oy, oz = point2.x, point2.y, point2.z # o is for objective dx = ox - tx dy = oy - ty dz = oz - tz largest = float(max(abs(dx), abs(dy), abs(dz))) dx, dy, dz = dx / largest, dy / largest, dz / largest # We make a vector which maximum value is 1.0 adx, ady, adz = abs(dx), abs(dy), abs(dz) px, py, pz = rx, ry, rz while abs(ox - tx) > 1 or abs(oy - ty) > 1 or abs(oz - tz) > 1: tx += dx ty += dy tz += dz if (ty < 0 and dy < 0) or (ty >= 127 and dy > 0): break rx, ry, rz = int(tx), int(ty), int(tz) yield rx, ry, rz # Send blocks that are in fact intersected by the line # but that bresenham skipped. if rx != px and adx != 1: yield px, ry, rz if ry != py and ady != 1: yield px, py, rz if rz != pz and adz != 1: yield px, ry, pz if ry != py and ady != 1: yield rx, py, rz if rz != pz and adz != 1: yield rx, py, pz if rz != pz and adz != 1: yield rx, ry, pz px, py, pz = rx, ry, rz