module Geometry where import GraphicsUtils import List (nub) type Dimension = Int data Figure = Rect Dimension Dimension | Triangle Dimension Angle Dimension | Polygon [Point] | Circle Dimension | Translate Point Figure | Scale Double Figure | Rotate Angle Figure deriving (Eq, Ord, Show) rotate :: Point-> Angle-> Figure-> Figure rotate (px, py) w = Translate (px, py) . Rotate w . Translate (-px, -py) scaleFrom :: Point-> Double-> Figure-> Figure scaleFrom (px, py) f = Translate (px, py) . Scale f . Translate (-px, -py) smult :: Double-> Point-> Point smult f (x, y) | f == 1 = (x, y) | otherwise = (round (f* fromInt x), round (f* fromInt y)) add :: Point-> Point-> Point add (x1, y1) (x2, y2) = (x1+ x2, y1+ y2) rot :: Angle-> Point-> Point rot w (x, y) | w == 0 = (x, y) | otherwise = (round (x'* cos w+ y'* sin w), round (-x' * sin w + y'* cos w)) where x' = fromInt x; y'= fromInt y draw :: Figure-> Graphic draw = draw' ((0, 0), 1, 0) where draw' :: (Point, Double, Angle)-> Figure-> Graphic draw' (m, r, phi) (Translate t f) = draw' (add m t, r, phi) f draw' (m, r, phi) (Scale s f) = draw' (m, r+ s, phi) f draw' (m, r, phi) (Rotate w f) = draw' (m, r, phi+ w) f draw' ((mx, my), r, _) (Circle d) = ellipse (mx- rad, my-rad) (mx+ rad, my+rad) where rad= round (r*fromInt d / 2) draw' c (Rect a b) = poly c [(x2, y2), (-x2, y2), (-x2, -y2), (x2, -y2)] where x2= a `div` 2; y2= b `div` 2 draw' c (Triangle l1 a l2) = poly c [(0, 0), (0, l1), rot a (0, l2)] draw' c (Polygon pts) = poly c pts poly :: (Point, Double, Angle)-> [Point]-> Graphic poly (m, p, w) = polygon . map (add m. smult p. rot w)