module Reanimate.Builtin.CirclePlot
( circlePlot
) where
import Codec.Picture (PixelRGBA8 (..), generateImage)
import Graphics.SvgTree (Tree)
import Reanimate.Constants (screenHeight)
import Reanimate.Raster (embedImage)
import Reanimate.Svg (flipYAxis, scaleToHeight)
circlePlot :: Int
-> (Double -> Double -> PixelRGBA8)
-> Tree
circlePlot :: Int -> (Double -> Double -> PixelRGBA8) -> Tree
circlePlot Int
density Double -> Double -> PixelRGBA8
fn =
Double -> Tree -> Tree
scaleToHeight Double
forall a. Fractional a => a
screenHeight (Tree -> Tree) -> Tree -> Tree
forall a b. (a -> b) -> a -> b
$ Tree -> Tree
flipYAxis (Tree -> Tree) -> Tree -> Tree
forall a b. (a -> b) -> a -> b
$
Image PixelRGBA8 -> Tree
forall a. PngSavable a => Image a -> Tree
embedImage (Image PixelRGBA8 -> Tree) -> Image PixelRGBA8 -> Tree
forall a b. (a -> b) -> a -> b
$ (Int -> Int -> PixelRGBA8) -> Int -> Int -> Image PixelRGBA8
forall px. Pixel px => (Int -> Int -> px) -> Int -> Int -> Image px
generateImage Int -> Int -> PixelRGBA8
forall a a. (Integral a, Integral a) => a -> a -> PixelRGBA8
gen Int
density Int
density
where
cN :: Double
cN = Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ Int
density Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
gen :: a -> a -> PixelRGBA8
gen a
x a
y =
let radius :: Double
radius = Double -> Double
forall a. Floating a => a -> a
sqrt ((a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
-Double
cN)Double -> Double -> Double
forall a. Floating a => a -> a -> a
**Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ (a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
yDouble -> Double -> Double
forall a. Num a => a -> a -> a
-Double
cN)Double -> Double -> Double
forall a. Floating a => a -> a -> a
**Double
2)
ang :: Double
ang = Double -> Double -> Double
forall a. RealFloat a => a -> a -> a
atan2 (a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
yDouble -> Double -> Double
forall a. Num a => a -> a -> a
-Double
cN) (a -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
-Double
cN)
in if Double
radius Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
> Double
cN
then Pixel8 -> Pixel8 -> Pixel8 -> Pixel8 -> PixelRGBA8
PixelRGBA8 Pixel8
0 Pixel8
0 Pixel8
0 Pixel8
0
else Double -> Double -> PixelRGBA8
fn Double
ang (Double
radius Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Double
cN)