SOE ex.8.6


polygon :: [Coordinate] -> Region
polygon cs =
  foldl1 Intersect $ zipWith HalfPlane cs' (tail (cycle cs'))
  where
  cs' = if isClockwiseOrder cs then reverse cs else cs
  isClockwiseOrder (p1:p2:p3:_) = p2 `isLeftOf` (p1, p3)
  isClockwiseOrder _ = False


----- a test -----
main = putStrLn $ show $ polygon [(0,0), (0,5), (5,0)]

----- data/type used in this exercise -----
data Region = HalfPlane Coordinate Coordinate
            | Region `Intersect` Region
  deriving Show
type Coordinate = (Float, Float)
type Ray = (Coordinate, Coordinate)

----- reuse the isLeftOf function -----
isLeftOf :: Coordinate -> Ray -> Bool
(px, py) `isLeftOf` ((ax, ay), (bx, by))
  = let (s, t) = (px - ax, py - ay)
        (u, v) = (px - bx, py - by)
    in s * v >= t * u

Leave a Reply