module Graphics.Chalkboard.Utils
(
innerSteps, outerSteps, fracPart
, fromPolar
, toPolar
, angleOfLine
, interpBool
, sampleUI
, withMask
, withDefault
, choose
, insideRegion
, insideCircle
, distance
, intervalOnLine
, circleOfDots
) where
import Graphics.Chalkboard.Types
innerSteps :: Int -> [R]
innerSteps n = map (/ fromIntegral (n * 2)) (map fromIntegral (take n [1::Int,3..]))
outerSteps :: Int -> [R]
outerSteps n = map (/ fromIntegral n) (map fromIntegral (take (n + 1) [(0::Int)..]))
fracPart :: R -> R
fracPart x = x fromIntegral ((floor x) :: Integer)
interpBool :: Bool -> UI
interpBool True = 1.0
interpBool False = 0.0
sampleUI :: UI -> Bool
sampleUI n = n >= 0.5
withMask :: a -> (Bool -> Maybe a)
withMask a True = Just a
withMask _ False = Nothing
withDefault :: a -> (Maybe a -> a)
withDefault a Nothing = a
withDefault _ (Just b) = b
choose :: a -> a -> (Bool -> a)
choose t _f True = t
choose _t f False = f
insideRegion :: (Point,Point) -> Point -> Bool
insideRegion ((x1,y1),(x2,y2)) (x,y) = x1 <= x && x <= x2
&& y1 <= y && y <= y2
insideCircle :: Point -> R -> Point -> Bool
insideCircle (x1,y1) r (x,y) = distance (x1,y1) (x,y) <= r
distance :: Point -> Point -> R
distance (x,y) (x',y') = sqrt (xd * xd + yd * yd)
where
xd = x x'
yd = y y'
distanceLe :: Point -> Point -> R -> Bool
distanceLe (x,y) (x',y') w = (xd * xd + yd * yd) <= w * w
where
xd = x x'
yd = y y'
intervalOnLine :: (Point,Point) -> Point -> R
intervalOnLine ((x1,y1),(x2,y2)) (x0,y0) =
((x0x1)*(x2x1)+(y0y1)*(y2y1))/(xd * xd + yd * yd)
where
xd = x2x1
yd = y2y1
fromPolar :: (R,Radian) -> Point
fromPolar (p, phi) = (p * cos phi, p * sin phi)
toPolar :: Point -> (R,Radian)
toPolar (x, y) = (x * x + y * y, atan2 x y)
angleOfLine :: (Point,Point) -> Radian
angleOfLine ((x1,y1),(x2,y2)) = atan2 (x2 x1) (y2 y1)
circleOfDots :: Int -> [Point]
circleOfDots 0 = error "circleOfDots 0"
circleOfDots n = [ (x,y)
| x <- map (\ t -> t * 2 1) $ outerSteps n
, y <- map (\ t -> t * 2 1) $ outerSteps n
, (x * x + y * y) <= 1.0
]