# Find intersection of rectangle with itself rotated

Given $$\w, h, \alpha\$$ for a rectangle centered at origin with width $$\w\$$, height $$\h\$$ and itself rotated by $$\\alpha\$$ around origin clockwise, I wrote a code to find the intersection area.

1. First I find all 4 corners of original and rotated rectangle, along with lines joining them.
2. Then I find intersection with axis-parallel lines using getints
3. Then I take all intersections in a clockwise/anti-clockwise order and find area using the co-ordinates of the polygon thus formed.
import Data.Ord
import Data.List

main :: IO ()
main = do
[w, h, a] <- map read . words <$> getLine let a' = (min a (180 - a)) * pi / 180 let pts = [(w/2, h/2), (w/2, -h/2), (-w/2,-h/2), (-w/2,h/2)] :: [(Double, Double)] let pts' = map (rotate a') pts let lines = zip pts (tail$ cycle pts)
let lines' = zip pts' (tail $cycle pts') let ints = concatMap (getints lines') lines print . area . uniq$ sortBy (comparing theta) ints

uniq [] = []
uniq [x] = [x]
uniq (x:y:xs)
| x == y = uniq (x:xs)
| otherwise = x : uniq (y:xs)

rotate a (x, y) = (x * cos a - y * sin a, x * sin a + y * cos a)

theta (x, y) = atan2 y x

getints xs y = concatMap (\x -> getints' x y) xs

getints' l'@((x1', y1'), (x2', y2')) l@((x, y), (x', y'))
| x == x' =
let y'' = y1' + (x - x1') / (x2' - x1') * (y2' - y1')
in if min y y' <= y'' && y'' <= max y y' then [(x, y'')] else []
| y == y' = map swap $getints' (swap' l') (swap' l) where swap (a, b) = (b, a) swap' (p1, p2) = (swap p1, swap p2) area ps = let xs = map fst ps ys = map snd ps in 0.5 * abs (sum$ zipWith4 (\x y y' x' -> x * y - y' * x') xs (tail $cycle ys) ys (tail$ cycle xs))