module ConvexHull
( convexHull
) where
import Data.List
import Geometry ( V2, turn )
convexHull :: [V2] -> [V2]
convexHull :: [V2] -> [V2]
convexHull [] = []
convexHull [V2
p] = [V2
p]
convexHull [V2]
ps = [V2] -> [V2]
forall a. [a] -> [a]
tail (([V2] -> V2 -> [V2]) -> [V2] -> [V2] -> [V2]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' [V2] -> V2 -> [V2]
f [] ([V2] -> [V2]
forall a. [a] -> [a]
reverse [V2]
ps')) [V2] -> [V2] -> [V2]
forall a. [a] -> [a] -> [a]
++ [V2] -> [V2]
forall a. [a] -> [a]
tail (([V2] -> V2 -> [V2]) -> [V2] -> [V2] -> [V2]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' [V2] -> V2 -> [V2]
f [] [V2]
ps') where
ps' :: [V2]
ps' = [V2] -> [V2]
forall a. Ord a => [a] -> [a]
sort [V2]
ps
f :: [V2] -> V2 -> [V2]
f [V2]
hull V2
p = [V2] -> [V2]
go [V2]
hull where
go :: [V2] -> [V2]
go (V2
p1:h :: [V2]
h@(V2
p2:[V2]
_)) | V2 -> V2 -> V2 -> Ordering
turn V2
p2 V2
p1 V2
p Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
/= Ordering
LT = [V2] -> [V2]
go [V2]
h
go [V2]
h = V2
pV2 -> [V2] -> [V2]
forall a. a -> [a] -> [a]
:[V2]
h