from typing import List
from math import sqrt
class Point:
def __init__(self, x: int, y: int):
self.x = x
self.y = y
def cross_product(o: Point, a: Point, b: Point) -> int:
return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x)
def convex_hull(points: List[Point]) -> List[Point]:
n = len(points)
if n <= 3:
return points
points.sort(key=lambda p: (p.x, p.y))
ans = [None] * (2 * n)
# Build lower hull
k = 0
for i in range(n):
while k >= 2 and cross_product(ans[k-2], ans[k-1], points[i]) <= 0:
k -= 1
ans[k] = points[i]
k += 1
# Build upper hull
t = k + 1
for i in range(n-2, -1, -1):
while k >= t and cross_product(ans[k-2], ans[k-1], points[i]) <= 0:
k -= 1
ans[k] = points[i]
k += 1
ans = ans[:k-1]
return ans
def dist(a: Point, b: Point) -> float:
return sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2)
def perimeter(points: List[Point]) -> float:
n = len(points)
perimeter = 0.0
for i in range(n-1):
perimeter += dist(points[i], points[i+1])
perimeter += dist(points[0], points[n-1])
return perimeter
# Driver code
points = [Point(0, 3), Point(2, 2), Point(1, 1), Point(2, 1), Point(3, 0), Point(0, 0), Point(3, 3)]
convex_points = convex_hull(points)
print(perimeter(convex_points))