diff --git a/skais/tests/utils/test_geometry.py b/skais/tests/utils/test_geometry.py index 91b0907040fce9c66b933f1d1023e136ae8e77a6..7a0b76ddb703f43a136c315e5abcf1833460a03d 100644 --- a/skais/tests/utils/test_geometry.py +++ b/skais/tests/utils/test_geometry.py @@ -18,6 +18,13 @@ class TestGeometry(unittest.TestCase): self.assertListEqual(result, expected) + + def test_bresenham_inverted_2(self): + result = bresenham(16, 4, 3, 9) + expected = [(3, 9), (4, 9), (5, 8), (6, 8), (7, 7), (8, 7), (9, 7), (10, 6), (11, 6), (12, 6), (13, 5), (14, 5), + (15, 4), (16, 4)] + self.assertListEqual(result, expected) + def test_bresenham_same_line(self): result = bresenham(3, 4, 10, 4) expected = [(3, 4), (4, 4), (5, 4), (6, 4), (7, 4), (8, 4), (9, 4), (10, 4)] diff --git a/skais/utils/geometry.py b/skais/utils/geometry.py index 78521b2dee50c79ee96b9eb4c08591c0a9891086..885aa429e8d6b5a5228888da3449d4a8b2ce9f0b 100644 --- a/skais/utils/geometry.py +++ b/skais/utils/geometry.py @@ -3,28 +3,44 @@ def bresenham(x1, y1, x2, y2): tmp = x2 x2 = x1 x1 = tmp - if y1 > y2: + + tmp = y2 y2 = y1 y1 = tmp + + dx = int(x2 - x1) + dy = int(y2 - y1) + + sx = sy = 1 + if dx < 0: + sx = -1 + if dy < 0: + sy = -1 + + x = x1 + y = y1 pixels = [(x1, y1)] - if x1 == x2: - x = x1 - for y in range(y1 + 1, y2 + 1): + if abs(dx) > abs(dy): # slope < 1 + p = (2 * abs(dy)) - abs(dx) + + for x in range(x1 + 1, x2 + 1): + if p < 0: + p += 2 * abs(dy) + else: + y += sy + p += (2 * abs(dy)) - (2 * abs(dx)) pixels.append((x, y)) - else: - a = 2*(y2 - y1) - b = a - 2*(x2 - x1) - p = a - (x2 - x1) - - y = y1 - for x in range(x1+1, x2+1): + else: # slope >= 1 + p = (2 * abs(dx)) - abs(dy) + for y in range(y1 + 1, y2 + 1): if p < 0: - p += a + p += 2 * abs(dx) else: - y += 1 - p += b + x += sx + p += (2 * abs(dx)) - (2 * abs(dy)) pixels.append((x, y)) + return pixels