44 lines
1.3 KiB
Haskell
44 lines
1.3 KiB
Haskell
-- Не стоит в первой же лабе использовать монады, можно и без них
|
||
|
||
import System.Random (randomRIO)
|
||
|
||
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 :: Point -> IO Point
|
||
genNextPoint point = do
|
||
random <- randomRIO (0.0, 1.0 :: Float)
|
||
return $ applyTransformation point random
|
||
|
||
barnsleyFern :: Point -> Int -> IO [Point]
|
||
barnsleyFern _ 0 = return []
|
||
barnsleyFern startPoint n = do
|
||
x' <- genNextPoint startPoint
|
||
xs <- barnsleyFern x' (n - 1)
|
||
return (startPoint : xs)
|
||
|
||
main :: IO ()
|
||
main = do
|
||
putStrLn "Укажите количество шагов рекурсии:"
|
||
input <- getLine
|
||
let n = read input :: Int
|
||
fractal <- barnsleyFern (0, 0) n
|
||
print fractal |