Skip to content

Commit a376a44

Browse files
Update jarvis_march.py
1 parent c2c2e75 commit a376a44

File tree

1 file changed

+6
-80
lines changed

1 file changed

+6
-80
lines changed

geometry/jarvis_march.py

Lines changed: 6 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,11 @@
1818
-> GeeksforGeeks: https://www.geeksforgeeks.org/convex-hull-set-1-jarviss-algorithm-or-wrapping/
1919
"""
2020

21-
# pytest: disable=pytest-run-parallel
22-
2321
from __future__ import annotations
2422

2523

2624
class Point:
27-
"""
28-
Represents a 2D point with x and y coordinates.
29-
30-
>>> p = Point(1.0, 2.0)
31-
>>> p.x
32-
1.0
33-
>>> p.y
34-
2.0
35-
"""
25+
"""Represents a 2D point with x and y coordinates."""
3626

3727
def __init__(self, x_coordinate: float, y_coordinate: float) -> None:
3828
self.x = x_coordinate
@@ -58,33 +48,14 @@ def _cross_product(origin: Point, point_a: Point, point_b: Point) -> float:
5848
> 0: Counter-clockwise turn (left turn)
5949
= 0: Collinear
6050
< 0: Clockwise turn (right turn)
61-
62-
>>> origin = Point(0, 0)
63-
>>> point_a = Point(1, 1)
64-
>>> point_b = Point(2, 0)
65-
>>> _cross_product(origin, point_a, point_b) < 0
66-
True
67-
>>> _cross_product(origin, Point(1, 0), Point(2, 0)) == 0
68-
True
69-
>>> _cross_product(origin, Point(1, 0), Point(1, 1)) > 0
70-
True
7151
"""
7252
return (point_a.x - origin.x) * (point_b.y - origin.y) - (point_a.y - origin.y) * (
7353
point_b.x - origin.x
7454
)
7555

7656

7757
def _is_point_on_segment(p1: Point, p2: Point, point: Point) -> bool:
78-
"""
79-
Check if a point lies on the line segment between p1 and p2.
80-
81-
>>> _is_point_on_segment(Point(0, 0), Point(2, 2), Point(1, 1))
82-
True
83-
>>> _is_point_on_segment(Point(0, 0), Point(2, 2), Point(3, 3))
84-
False
85-
>>> _is_point_on_segment(Point(0, 0), Point(2, 0), Point(1, 0))
86-
True
87-
"""
58+
"""Check if a point lies on the line segment between p1 and p2."""
8859
# Check if point is collinear with segment endpoints
8960
cross = (point.y - p1.y) * (p2.x - p1.x) - (point.x - p1.x) * (p2.y - p1.y)
9061

@@ -110,52 +81,6 @@ def jarvis_march(points: list[Point]) -> list[Point]:
11081
Returns:
11182
List of Points that form the convex hull in counter-clockwise order.
11283
Returns empty list if there are fewer than 3 non-collinear points.
113-
114-
Examples:
115-
>>> # Triangle
116-
>>> p1, p2, p3 = Point(1, 1), Point(2, 1), Point(1.5, 2)
117-
>>> hull = jarvis_march([p1, p2, p3])
118-
>>> len(hull)
119-
3
120-
>>> all(p in hull for p in [p1, p2, p3])
121-
True
122-
123-
>>> # Collinear points return empty hull
124-
>>> points = [Point(i, 0) for i in range(5)]
125-
>>> jarvis_march(points)
126-
[]
127-
128-
>>> # Rectangle with interior point - interior point excluded
129-
>>> p1, p2 = Point(1, 1), Point(2, 1)
130-
>>> p3, p4 = Point(2, 2), Point(1, 2)
131-
>>> p5 = Point(1.5, 1.5)
132-
>>> hull = jarvis_march([p1, p2, p3, p4, p5])
133-
>>> len(hull)
134-
4
135-
>>> p5 in hull
136-
False
137-
138-
>>> # Star shape - only tips are in hull
139-
>>> tips = [
140-
... Point(-5, 6), Point(-11, 0), Point(-9, -8),
141-
... Point(4, 4), Point(6, -7)
142-
... ]
143-
>>> interior = [Point(-7, -2), Point(-2, -4), Point(0, 1)]
144-
>>> hull = jarvis_march(tips + interior)
145-
>>> len(hull)
146-
5
147-
>>> all(p in hull for p in tips)
148-
True
149-
>>> any(p in hull for p in interior)
150-
False
151-
152-
>>> # Too few points
153-
>>> jarvis_march([])
154-
[]
155-
>>> jarvis_march([Point(0, 0)])
156-
[]
157-
>>> jarvis_march([Point(0, 0), Point(1, 1)])
158-
[]
15984
"""
16085
if len(points) <= 2:
16186
return []
@@ -211,6 +136,7 @@ def jarvis_march(points: list[Point]) -> list[Point]:
211136

212137

213138
if __name__ == "__main__":
214-
import doctest
215-
216-
doctest.testmod()
139+
# Example usage
140+
points = [Point(0, 0), Point(1, 1), Point(0, 1), Point(1, 0), Point(0.5, 0.5)]
141+
hull = jarvis_march(points)
142+
print(f"Convex hull: {hull}")

0 commit comments

Comments
 (0)