|
13 | 13 |
|
14 | 14 | """
|
15 | 15 |
|
| 16 | +from typing import Iterable, List, Set, Union |
16 | 17 |
|
17 | 18 | class Point:
|
18 | 19 | """
|
@@ -81,7 +82,7 @@ def __hash__(self):
|
81 | 82 | return hash(self.x)
|
82 | 83 |
|
83 | 84 |
|
84 |
| -def _construct_points(list_of_tuples): |
| 85 | +def _construct_points(list_of_tuples: Union[List[Point], List[List[float]], Iterable[List[float]]]) -> List[Point]: |
85 | 86 | """
|
86 | 87 | constructs a list of points from an array-like object of numbers
|
87 | 88 |
|
@@ -113,17 +114,20 @@ def _construct_points(list_of_tuples):
|
113 | 114 | points = []
|
114 | 115 | if list_of_tuples:
|
115 | 116 | for p in list_of_tuples:
|
116 |
| - try: |
117 |
| - points.append(Point(p[0], p[1])) |
118 |
| - except (IndexError, TypeError): |
119 |
| - print( |
120 |
| - f"Ignoring deformed point {p}. All points" |
121 |
| - " must have at least 2 coordinates." |
122 |
| - ) |
| 117 | + if isinstance(p, Point): |
| 118 | + points.append(p) |
| 119 | + else: |
| 120 | + try: |
| 121 | + points.append(Point(p[0], p[1])) |
| 122 | + except (IndexError, TypeError): |
| 123 | + print( |
| 124 | + f"Ignoring deformed point {p}. All points" |
| 125 | + " must have at least 2 coordinates." |
| 126 | + ) |
123 | 127 | return points
|
124 | 128 |
|
125 | 129 |
|
126 |
| -def _validate_input(points): |
| 130 | +def _validate_input(points: Union[List[Point], List[List[float]]]) -> List[Point]: |
127 | 131 | """
|
128 | 132 | validates an input instance before a convex-hull algorithms uses it
|
129 | 133 |
|
@@ -168,30 +172,10 @@ def _validate_input(points):
|
168 | 172 | if not points:
|
169 | 173 | raise ValueError(f"Expecting a list of points but got {points}")
|
170 | 174 |
|
171 |
| - if isinstance(points, set): |
172 |
| - points = list(points) |
173 |
| - |
174 |
| - try: |
175 |
| - if hasattr(points, "__iter__") and not isinstance(points[0], Point): |
176 |
| - if isinstance(points[0], (list, tuple)): |
177 |
| - points = _construct_points(points) |
178 |
| - else: |
179 |
| - raise ValueError( |
180 |
| - "Expecting an iterable of type Point, list or tuple. " |
181 |
| - f"Found objects of type {type(points[0])} instead" |
182 |
| - ) |
183 |
| - elif not hasattr(points, "__iter__"): |
184 |
| - raise ValueError( |
185 |
| - f"Expecting an iterable object but got an non-iterable type {points}" |
186 |
| - ) |
187 |
| - except TypeError: |
188 |
| - print("Expecting an iterable of type Point, list or tuple.") |
189 |
| - raise |
190 |
| - |
191 |
| - return points |
| 175 | + return _construct_points(points) |
192 | 176 |
|
193 | 177 |
|
194 |
| -def _det(a, b, c): |
| 178 | +def _det(a: Point, b: Point, c: Point) -> float: |
195 | 179 | """
|
196 | 180 | Computes the sign perpendicular distance of a 2d point c from a line segment
|
197 | 181 | ab. The sign indicates the direction of c relative to ab.
|
@@ -226,7 +210,7 @@ def _det(a, b, c):
|
226 | 210 | return det
|
227 | 211 |
|
228 | 212 |
|
229 |
| -def convex_hull_bf(points): |
| 213 | +def convex_hull_bf(points: List[Point]) -> List[Point]: |
230 | 214 | """
|
231 | 215 | Constructs the convex hull of a set of 2D points using a brute force algorithm.
|
232 | 216 | The algorithm basically considers all combinations of points (i, j) and uses the
|
@@ -299,7 +283,7 @@ def convex_hull_bf(points):
|
299 | 283 | return sorted(convex_set)
|
300 | 284 |
|
301 | 285 |
|
302 |
| -def convex_hull_recursive(points): |
| 286 | +def convex_hull_recursive(points: List[Point]) -> List[Point]: |
303 | 287 | """
|
304 | 288 | Constructs the convex hull of a set of 2D points using a divide-and-conquer strategy
|
305 | 289 | The algorithm exploits the geometric properties of the problem by repeatedly
|
@@ -369,7 +353,7 @@ def convex_hull_recursive(points):
|
369 | 353 | return sorted(convex_set)
|
370 | 354 |
|
371 | 355 |
|
372 |
| -def _construct_hull(points, left, right, convex_set): |
| 356 | +def _construct_hull(points: List[Point], left: Point, right: Point, convex_set: Set[Point]) -> None: |
373 | 357 | """
|
374 | 358 |
|
375 | 359 | Parameters
|
@@ -411,7 +395,7 @@ def _construct_hull(points, left, right, convex_set):
|
411 | 395 | _construct_hull(candidate_points, extreme_point, right, convex_set)
|
412 | 396 |
|
413 | 397 |
|
414 |
| -def convex_hull_melkman(points): |
| 398 | +def convex_hull_melkman(points: List[Point]) -> List[Point]: |
415 | 399 | """
|
416 | 400 | Constructs the convex hull of a set of 2D points using the melkman algorithm.
|
417 | 401 | The algorithm works by iteratively inserting points of a simple polygonal chain
|
|
0 commit comments