Skip to main content
tag
Link
dfhwze
  • 14.2k
  • 3
  • 40
  • 101
Source Link
RE60K
  • 1.5k
  • 2
  • 11
  • 27

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.

Source: https://codeforces.com/problemset/problem/280/A Image

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))