|
1 | | -import matplotlib.pyplot as plt |
| 1 | +from typing import List, Tuple |
2 | 2 |
|
3 | 3 |
|
4 | 4 | def digital_differential_analyzer_line( |
5 | | - p1: tuple[int, int], p2: tuple[int, int] |
6 | | -) -> list[tuple[int, int]]: |
| 5 | + p1: Tuple[int, int], p2: Tuple[int, int] |
| 6 | +) -> List[Tuple[int, int]]: |
7 | 7 | """ |
8 | | - Draws a line between two points using the Digital Differential Analyzer (DDA) algorithm. |
| 8 | + Draw a line between two points using the Digital Differential Analyzer (DDA) |
| 9 | + algorithm. |
9 | 10 |
|
10 | | - The DDA algorithm works by computing the differences in x and y (dx, dy), |
11 | | - determining the dominant axis (the one with the larger absolute difference), |
12 | | - and incrementing along it in small uniform steps. The other coordinate is |
13 | | - updated by a proportional fractional amount at each iteration, producing a |
14 | | - sequence of intermediate points that approximate a straight line. |
15 | | -
|
16 | | - While simple and widely used for teaching computer graphics, the algorithm |
17 | | - relies on floating-point arithmetic and rounding at each step. This makes it |
18 | | - less efficient and less precise than the integer-only Bresenham line algorithm, |
19 | | - which is commonly preferred in performance-critical rasterization tasks. |
| 11 | + The DDA algorithm increments the dominant axis in unit steps and updates the |
| 12 | + other axis proportionally. After each step coordinates are rounded to the |
| 13 | + nearest integer to obtain pixel coordinates. |
20 | 14 |
|
21 | 15 | Args: |
22 | | - p1: Coordinates of the starting point. |
23 | | - p2: Coordinates of the ending point. |
| 16 | + p1: Starting coordinate (x1, y1). |
| 17 | + p2: Ending coordinate (x2, y2). |
24 | 18 |
|
25 | 19 | Returns: |
26 | | - List of coordinate points that form the line. |
| 20 | + A list of integer coordinate tuples representing the rasterized line. |
| 21 | + The list includes the end point and excludes the start point. |
27 | 22 |
|
| 23 | + Examples: |
28 | 24 | >>> digital_differential_analyzer_line((1, 1), (4, 4)) |
29 | 25 | [(2, 2), (3, 3), (4, 4)] |
30 | 26 |
|
31 | | - For more information, see: |
32 | | - https://en.wikipedia.org/wiki/Digital_differential_analyzer_(graphics_algorithm) |
| 27 | + >>> digital_differential_analyzer_line((0, 0), (0, 5)) |
| 28 | + [(0, 1), (0, 2), (0, 3), (0, 4), (0, 5)] |
| 29 | +
|
| 30 | + >>> digital_differential_analyzer_line((5, 5), (2, 5)) |
| 31 | + [(4, 5), (3, 5), (2, 5)] |
| 32 | +
|
| 33 | + >>> digital_differential_analyzer_line((3, 3), (3, 3)) |
| 34 | + [(3, 3)] |
33 | 35 | """ |
34 | 36 | x1, y1 = p1 |
35 | 37 | x2, y2 = p2 |
36 | 38 | dx = x2 - x1 |
37 | 39 | dy = y2 - y1 |
| 40 | + |
38 | 41 | steps = max(abs(dx), abs(dy)) |
39 | | - x_increment = dx / float(steps) |
40 | | - y_increment = dy / float(steps) |
41 | | - coordinates = [] |
42 | | - x: float = x1 |
43 | | - y: float = y1 |
44 | | - for _ in range(steps): |
45 | | - x += x_increment |
46 | | - y += y_increment |
47 | | - coordinates.append((round(x), round(y))) |
48 | | - return coordinates |
| 42 | + if steps == 0: |
| 43 | + return [p1] |
49 | 44 |
|
| 45 | + x_inc = dx / float(steps) |
| 46 | + y_inc = dy / float(steps) |
50 | 47 |
|
51 | | -if __name__ == "__main__": |
52 | | - import doctest |
| 48 | + x, y = float(x1), float(y1) |
| 49 | + points: List[Tuple[int, int]] = [] |
53 | 50 |
|
54 | | - doctest.testmod() |
| 51 | + for _ in range(steps): |
| 52 | + x += x_inc |
| 53 | + y += y_inc |
| 54 | + points.append((round(x), round(y))) |
55 | 55 |
|
56 | | - x1 = int(input("Enter the x-coordinate of the starting point: ")) |
57 | | - y1 = int(input("Enter the y-coordinate of the starting point: ")) |
58 | | - x2 = int(input("Enter the x-coordinate of the ending point: ")) |
59 | | - y2 = int(input("Enter the y-coordinate of the ending point: ")) |
60 | | - coordinates = digital_differential_analyzer_line((x1, y1), (x2, y2)) |
61 | | - x_points, y_points = zip(*coordinates) |
62 | | - plt.plot(x_points, y_points, marker="o") |
63 | | - plt.title("Digital Differential Analyzer Line Drawing Algorithm") |
64 | | - plt.xlabel("X-axis") |
65 | | - plt.ylabel("Y-axis") |
66 | | - plt.grid() |
67 | | - plt.show() |
| 56 | + return points |
0 commit comments