Last active
April 29, 2018 03:01
-
-
Save lispandfound/c0842b16668ece08190ebecd777705a5 to your computer and use it in GitHub Desktop.
Gift Wrap Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- For the minimumBy function | |
| import Data.List | |
| type Point = (Float, Float) | |
| -- Returns the relation between a line segment and a point. Takes three | |
| -- arguments, the first two defining the line segment, The last a test | |
| -- point. The value is 0 if the test point is on the line >0 if it is | |
| -- to the right and <0 if it is to the left. | |
| lineRelation :: Point -> Point -> Point -> Float | |
| lineRelation (x1, y1) (x2, y2) (x, y) = (y - y1) * (x2 - x1) - (y2 - y1) * (x - x1) | |
| -- Find a convex hull of a set of points using the gift wrap algorithm. | |
| giftWrap :: [Point] -> [Point] | |
| giftWrap points = giftWrap' anchor points | |
| where | |
| anchor = minimumBy minX points | |
| minX :: Point -> Point -> Ordering | |
| minX (x, y) (x1, y1) | |
| | x == x1 = compare y y1 | |
| | otherwise = compare x x1 | |
| giftWrap' :: Point -> [Point] -> [Point] | |
| giftWrap' p points | |
| | q == anchor = [p] | |
| | otherwise = p:(giftWrap' q points) | |
| -- Let q be the point such that for all r in S, r is right of the line pq. | |
| -- This satisfies the necessary property that all interior | |
| -- points are to the right of every edge of a clockwise | |
| -- traversal of a convex hull. | |
| where q = foldl1 (\cur r -> | |
| if lineRelation p r cur < 0 then | |
| r | |
| else | |
| cur) . filter (/= p) $ points |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment