module Circle where
import Text.Blaze.Svg11 ((!))
import qualified Text.Blaze.Svg11 as S
import qualified Text.Blaze.Svg11.Attributes as A
import ApproxEq
import Helpers (fta)
import qualified Point as P
import Shape
data Circle = Circle { center :: P.Point
, radius :: !Float
} deriving (Eq, Show)
instance SvgShape Circle where
toSvg (Circle (P.Point cx cy) rad) =
S.circle ! A.cx (fta cx) ! A.cy (fta cy) ! A.r (fta rad)
instance ApproxEq Circle where
approxEqual a b epsilon = raddiiEqual && centersEqual
where
raddiiEqual = abs (radius a - radius b) < epsilon
centersEqual = approxEqual (center a) (center b) epsilon
instance Transformable Circle where
translate p c = Circle{center=center c + p, radius=radius c}
rotate p t c = Circle{center=P.rotateP (center c) p t, radius=radius c}
mirror p v c = Circle{center=P.mirrorP (center c) p v, radius=radius c}
offset d leftSide c = Circle{center=center c, radius=radius c + e}
where e = if leftSide then P.xVal d * (-1) else P.xVal d
instance Mergable Circle where
merge a b epsilon = if approxEqual a b epsilon then Just a else Nothing
instance Ord Circle where
compare a b = circleAsTuple a `compare` circleAsTuple b
(<=) a b = circleAsTuple a <= circleAsTuple b
mkCircle :: Float -> Float -> Float -> Circle
mkCircle a b = Circle (P.Point a b)
circleAsTuple :: Circle -> ((Float, Float), Float)
circleAsTuple (Circle c r) = (P.pointAsTuple c, r)
circumference :: Circle -> Float
circumference c = 2 * pi * radius c
circleCoords :: Circle -> Float -> P.Point
circleCoords (Circle (P.Point cx cy) r) angle = P.Point x y
where
x = cx + r * cos angle
y = cy + r * sin angle