import System.Random (StdGen, mkStdGen, randomR) type Point = (Float, Float) transformation1 :: Point -> Point transformation1 (_, y) = (0, 0.16 * y) transformation2 :: Point -> Point transformation2 (x, y) = (0.85 * x + 0.04 * y, -0.04 * x + 0.85 * y + 1.6) transformation3 :: Point -> Point transformation3 (x, y) = (0.2 * x - 0.26 * y, 0.23 * x + 0.22 * y + 1.6) transformation4 :: Point -> Point transformation4 (x, y) = (-0.15 * x + 0.28 * y, 0.26 * x + 0.24 * y + 0.44) applyTransformation :: Point -> Float -> Point applyTransformation point random | random < 0.01 = transformation1 point | random < 0.86 = transformation2 point | random < 0.93 = transformation3 point | otherwise = transformation4 point genNextPoint :: StdGen -> Point -> (Point, StdGen) genNextPoint gen point = let (random, newGen) = randomR (0.0, 1.0 :: Float) gen in (applyTransformation point random, newGen) barnsleyFern :: StdGen -> Point -> Int -> [Point] barnsleyFern _ _ 0 = [] barnsleyFern gen startPoint n = let (nextPoint, newGen) = genNextPoint gen startPoint in startPoint : barnsleyFern newGen nextPoint (n - 1) n = 1000 randomSeed = 17 main :: IO () main = print $ barnsleyFern (mkStdGen randomSeed) (0, 0) n