Skip to content

Commit cdbfddc

Browse files
authored
Merge pull request #1840 from Shaikh-Ubaid/pkg_convexhull
PKG: Add convexhull computation package
2 parents 2aacbb6 + fe0e7bf commit cdbfddc

File tree

5 files changed

+119
-0
lines changed

5 files changed

+119
-0
lines changed

integration_tests/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ RUN(NAME test_package_01 LABELS cpython llvm)
529529
RUN(NAME test_pkg_lpdraw LABELS cpython llvm wasm)
530530
RUN(NAME test_pkg_lnn_01 LABELS cpython llvm)
531531
RUN(NAME test_pkg_lnn_02 LABELS cpython llvm)
532+
RUN(NAME test_pkg_lpconvexhull LABELS cpython c)
532533

533534
RUN(NAME generics_01 LABELS cpython llvm c)
534535
RUN(NAME generics_02 LABELS cpython llvm c)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .lpconvexhull_main import convex_hull
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from lpython import i32
2+
from .utils import min, distance
3+
4+
def orientation(p: tuple[i32, i32], q: tuple[i32, i32], r: tuple[i32, i32]) -> i32:
5+
# Function to find the orientation of triplet (p, q, r)
6+
# Returns the following values:
7+
# 0: Colinear
8+
# 1: Clockwise
9+
# 2: Counterclockwise
10+
value: i32 = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1])
11+
if value == 0:
12+
return 0 # Colinear
13+
elif value > 0:
14+
return 1 # Clockwise
15+
else:
16+
return 2 # Counterclockwise
17+
18+
19+
def convex_hull(points: list[tuple[i32, i32]]) -> list[tuple[i32, i32]]:
20+
"""Finds the convex hull of a set of points.
21+
22+
Args:
23+
points: A list of points.
24+
25+
Returns:
26+
A list of points that form the convex hull.
27+
"""
28+
29+
n: i32 = len(points)
30+
if n < 3:
31+
return [(-1, -1)] # Convex hull not possible
32+
33+
# Find the leftmost point
34+
leftmost: tuple[i32, i32] = min(points)
35+
hull: list[tuple[i32, i32]] = []
36+
37+
p: tuple[i32, i32] = leftmost
38+
39+
while True:
40+
hull.append(p)
41+
q: tuple[i32, i32] = points[0]
42+
43+
r: tuple[i32, i32]
44+
for r in points:
45+
if r == p or r == q:
46+
continue
47+
direction: i32 = orientation(p, q, r)
48+
if direction == 1 or (direction == 0 and distance(p, r) > distance(p, q)):
49+
q = r
50+
51+
p = q
52+
53+
if p == leftmost:
54+
break
55+
56+
return hull
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from lpython import i32, f64
2+
3+
def min(points: list[tuple[i32, i32]]) -> tuple[i32, i32]:
4+
"""Finds the left-most point in a list of points.
5+
6+
Args:
7+
points: A list of points.
8+
9+
Returns:
10+
The left-most point in the list.
11+
"""
12+
13+
left_most_point: tuple[i32, i32] = points[0]
14+
point: tuple[i32, i32]
15+
for point in points:
16+
if point[0] < left_most_point[0]:
17+
left_most_point = point
18+
19+
return left_most_point
20+
21+
22+
def distance(p: tuple[i32, i32], q: tuple[i32, i32]) -> f64:
23+
# Function to calculate the Euclidean distance between two points
24+
x1: i32; y1: i32
25+
x2: i32; y2: i32
26+
27+
x1, y1 = p
28+
x2, y2 = q
29+
return f64((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from lpython import Const, i32, f64
2+
3+
from lpdraw import Line, Circle, Clear, Display
4+
from lpconvexhull import convex_hull
5+
from numpy import empty, int32
6+
7+
def plot_graph(polygon: list[tuple[i32, i32]], points: list[tuple[i32, i32]]):
8+
Width: Const[i32] = 500 # x-axis limits [0, 499]
9+
Height: Const[i32] = 500 # y-axis limits [0, 499]
10+
Screen: i32[Height, Width] = empty((Height, Width), dtype=int32)
11+
Clear(Height, Width, Screen)
12+
13+
i: i32
14+
n: i32 = len(polygon)
15+
for i in range(n):
16+
Line(Height, Width, Screen, polygon[i][0], polygon[i][1], polygon[(i + 1) % n][0], polygon[(i + 1) % n][1])
17+
18+
point_size: i32 = 5
19+
for i in range(len(points)):
20+
Circle(Height, Width, Screen, points[i][0], points[i][1], f64(point_size))
21+
22+
Display(Height, Width, Screen)
23+
24+
def main0():
25+
points: list[tuple[i32, i32]] = [(445, 193), (138, 28), (418, 279), (62, 438), (168, 345), (435, 325), (293, 440), (158, 94), (403, 288), (136, 278), (141, 243), (287, 313), (338, 492), (172, 78), (29, 404), (79, 377), (184, 91), (69, 324), (408, 72), (494, 1)]
26+
convex_hull_points: list[tuple[i32, i32]] = convex_hull(points)
27+
# print(convex_hull_points)
28+
plot_graph(convex_hull_points, points)
29+
30+
assert convex_hull_points == [(29, 404), (138, 28), (494, 1), (435, 325), (338, 492), (62, 438)]
31+
32+
main0()

0 commit comments

Comments
 (0)