Skip to content

Commit

Permalink
Merge pull request #1840 from Shaikh-Ubaid/pkg_convexhull
Browse files Browse the repository at this point in the history
PKG: Add convexhull computation package
  • Loading branch information
Shaikh-Ubaid authored May 23, 2023
2 parents 2aacbb6 + fe0e7bf commit cdbfddc
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ RUN(NAME test_package_01 LABELS cpython llvm)
RUN(NAME test_pkg_lpdraw LABELS cpython llvm wasm)
RUN(NAME test_pkg_lnn_01 LABELS cpython llvm)
RUN(NAME test_pkg_lnn_02 LABELS cpython llvm)
RUN(NAME test_pkg_lpconvexhull LABELS cpython c)

RUN(NAME generics_01 LABELS cpython llvm c)
RUN(NAME generics_02 LABELS cpython llvm c)
Expand Down
1 change: 1 addition & 0 deletions integration_tests/lpconvexhull/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .lpconvexhull_main import convex_hull
56 changes: 56 additions & 0 deletions integration_tests/lpconvexhull/lpconvexhull_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from lpython import i32
from .utils import min, distance

def orientation(p: tuple[i32, i32], q: tuple[i32, i32], r: tuple[i32, i32]) -> i32:
# Function to find the orientation of triplet (p, q, r)
# Returns the following values:
# 0: Colinear
# 1: Clockwise
# 2: Counterclockwise
value: i32 = (q[1] - p[1]) * (r[0] - q[0]) - (q[0] - p[0]) * (r[1] - q[1])
if value == 0:
return 0 # Colinear
elif value > 0:
return 1 # Clockwise
else:
return 2 # Counterclockwise


def convex_hull(points: list[tuple[i32, i32]]) -> list[tuple[i32, i32]]:
"""Finds the convex hull of a set of points.
Args:
points: A list of points.
Returns:
A list of points that form the convex hull.
"""

n: i32 = len(points)
if n < 3:
return [(-1, -1)] # Convex hull not possible

# Find the leftmost point
leftmost: tuple[i32, i32] = min(points)
hull: list[tuple[i32, i32]] = []

p: tuple[i32, i32] = leftmost

while True:
hull.append(p)
q: tuple[i32, i32] = points[0]

r: tuple[i32, i32]
for r in points:
if r == p or r == q:
continue
direction: i32 = orientation(p, q, r)
if direction == 1 or (direction == 0 and distance(p, r) > distance(p, q)):
q = r

p = q

if p == leftmost:
break

return hull
29 changes: 29 additions & 0 deletions integration_tests/lpconvexhull/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from lpython import i32, f64

def min(points: list[tuple[i32, i32]]) -> tuple[i32, i32]:
"""Finds the left-most point in a list of points.
Args:
points: A list of points.
Returns:
The left-most point in the list.
"""

left_most_point: tuple[i32, i32] = points[0]
point: tuple[i32, i32]
for point in points:
if point[0] < left_most_point[0]:
left_most_point = point

return left_most_point


def distance(p: tuple[i32, i32], q: tuple[i32, i32]) -> f64:
# Function to calculate the Euclidean distance between two points
x1: i32; y1: i32
x2: i32; y2: i32

x1, y1 = p
x2, y2 = q
return f64((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
32 changes: 32 additions & 0 deletions integration_tests/test_pkg_lpconvexhull.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from lpython import Const, i32, f64

from lpdraw import Line, Circle, Clear, Display
from lpconvexhull import convex_hull
from numpy import empty, int32

def plot_graph(polygon: list[tuple[i32, i32]], points: list[tuple[i32, i32]]):
Width: Const[i32] = 500 # x-axis limits [0, 499]
Height: Const[i32] = 500 # y-axis limits [0, 499]
Screen: i32[Height, Width] = empty((Height, Width), dtype=int32)
Clear(Height, Width, Screen)

i: i32
n: i32 = len(polygon)
for i in range(n):
Line(Height, Width, Screen, polygon[i][0], polygon[i][1], polygon[(i + 1) % n][0], polygon[(i + 1) % n][1])

point_size: i32 = 5
for i in range(len(points)):
Circle(Height, Width, Screen, points[i][0], points[i][1], f64(point_size))

Display(Height, Width, Screen)

def main0():
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)]
convex_hull_points: list[tuple[i32, i32]] = convex_hull(points)
# print(convex_hull_points)
plot_graph(convex_hull_points, points)

assert convex_hull_points == [(29, 404), (138, 28), (494, 1), (435, 325), (338, 492), (62, 438)]

main0()

0 comments on commit cdbfddc

Please sign in to comment.