Skip to content

Commit

Permalink
Add convex hull util.
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas M. DuBuisson committed Apr 28, 2013
1 parent b875f54 commit 100c0b5
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
1 change: 1 addition & 0 deletions CV.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ Library
,Utils.Pointer
,Utils.Rectangle
,Utils.Stream
,Utils.ConvexHull
Other-modules: CV.Bindings.Matrix,
CV.Bindings.Calibrate,
CV.Bindings.Fittings,
Expand Down
42 changes: 42 additions & 0 deletions Utils/ConvexHull.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module Utils.ConvexHull
( convexHull
) where

import Data.List
import Data.Ord

convexHull :: [(Double,Double)] -> [(Double,Double)]
convexHull lst =
let frst = minPoint lst
in case frst of
Nothing -> []
Just f ->
let sorted = sortBy (comparing (heading f)) lst
in case sorted of
(a:b:cs) -> grahamScan (b:a:f:[]) cs
cs -> f : cs
where
grahamScan [] _ = []
grahamScan ps [] = ps
grahamScan (x:[]) _ = [x]
grahamScan (p2:p1:ps) (x:xs) =
case turn p1 p2 x of
LeftTurn -> grahamScan (x:p2:p1:ps) xs
Straight -> grahamScan (x:p2:p1:ps) xs
_ -> grahamScan (p1:ps) (x:xs)

heading :: (Double,Double) -> (Double,Double) -> Double
heading (x1,y1) (x2,y2) = atan2 (y2-y1) (x2-x1)

minPoint :: [(Double,Double)] -> Maybe (Double,Double)
minPoint [] = Nothing
minPoint xs = Just $ minimumBy (comparing snd) xs

data Turn = LeftTurn | RightTurn | Straight deriving (Eq, Ord, Show, Read)

turn :: (Double,Double) -> (Double,Double) -> (Double,Double) -> Turn
turn a b c =
let h1 = heading a b
h2 = heading b c
d = h2 - h1
in if d >= 0 && d < pi then LeftTurn else RightTurn

0 comments on commit 100c0b5

Please sign in to comment.