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.
- First I find all 4 corners of original and rotated rectangle, along with lines joining them.
- Then I find intersection with axis-parallel lines using
getints
- Then I take all intersections in a clockwise/anti-clockwise order and find area using the co-ordinates of the polygon thus formed.
Source: https://codeforces.com/problemset/problem/280/A
import Data.Ord
import Data.List
import Control.Monad
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))