import Fractal.GRUFF import Fractal.RUFF.Mandelbrot.Address import Fractal.RUFF.Mandelbrot.Ray import Fractal.RUFF.Mandelbrot.Atom import Fractal.RUFF.Types.Complex import Control.Monad (ap, replicateM) import qualified Data.Map as M import Data.Maybe (mapMaybe) main :: IO () main = defaultMain [(labels, "gruff-labels.ppm")] labels :: Image labels = Image { imageWindow = Window{ width = 1280, height = 720, supersamples = 8 } , imageViewport = Viewport{ aspect =16/9, orient = 0 } , imageLocation = Location{ center = (-0.1178) :+ 1.0413, radius = 0.125 } , imageColours = Colours { colourInterior = red , colourBoundary = black , colourExterior = darkgrey } , imageLabels = rayLabels ++ atomLabels , imageLines = rayLines } addressSpec :: [String] addressSpec = [ "1 1/3 " ++ (unwords . map show . scanl (+) (3 :: Int)) steps | n <- [1 .. 3] , steps <- replicateM n [1,2,3] ] addresses :: [AngledInternalAddress] addresses = mapMaybe parseAngledInternalAddress addressSpec atoms :: [(AngledInternalAddress, MuAtom Double)] atoms = mapMaybe (\addr -> fmap ((,) addr) (findAtom_ addr)) addresses angles :: [(AngledInternalAddress, MuAtom Double, Angle, Angle)] angles = mapMaybe f atoms where f (addr, mu) = fmap g (externalAngles addr) where g (lo, hi) = (addr, mu, lo, hi) atomLabels :: [Label] atomLabels = [ Label { labelCoords = toRationalC (muNucleus mu) , labelColour = white , labelText = prettyAngledInternalAddress addr } | (addr, mu, _, _) <- angles ] rayLabels :: [Label] rayLabels = [ Label { labelCoords = fst . (!! (sharpness * k)) $ rays M.! a , labelColour = lightgrey, labelText = prettyAngle a } | (_, _, lo, hi) <- angles , (a, k) <- [(lo, 10), (hi, 11)] ] rayLines :: [Line] rayLines = [ Line{ lineSegments = rs, lineColour = midgrey } | rs <- M.elems rays ] rays :: M.Map Angle [(Complex Rational, Complex Rational)] rays = M.fromList [ (a, ray a) | (_, _, lo, hi) <- angles, a <- [lo, hi] ] ray :: Angle -> [(Complex Rational, Complex Rational)] ray = (zip`ap`tail) . map toRationalC . take (sharpness * 32) . externalRay 1e-8 sharpness (2**24) sharpness :: Int sharpness = 8 red, black, darkgrey, midgrey, lightgrey, white :: Colour red = Colour 1 0 0 black = Colour 0 0 0 darkgrey = Colour 0.25 0.25 0.25 midgrey = Colour 0.5 0.5 0.5 lightgrey = Colour 0.75 0.75 0.75 white = Colour 1 1 1 toRationalC :: Complex Double -> Complex Rational toRationalC (x :+ y) = toRational x :+ toRational y