-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFractals.hs
67 lines (46 loc) · 1.63 KB
/
Fractals.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
module FractalMusic where
import HaskoreExamples
import Random
type Vector = [Float]
type Matrix = [Vector]
type AT = Vector -> Vector
type IFS = [AT]
-- First define some general matrix operations.
-- These will facilitate moving to higher dimensions later.
vadd :: Vector -> Vector -> Vector
vadd = zipWith (+)
vvmult :: Vector -> Vector -> Float
vvmult v1 v2 = foldl (+) 0 (zipWith (*) v1 v2)
mvmult :: Matrix -> Vector -> Vector
mvmult m v = map (vvmult v) m
cvmult :: Float -> Vector -> Vector
cvmult c v = map (c*) v
---------------------------------------------------------------------
-- The following simulates the Iterated Function System for the
-- SierPinski Triangle as described in Barnsley's "Desktop Fractal
-- Design Handbook".
-- First the affine transformations:
w1,w2,w3 :: AT
w1 v = (cvmult 0.01 ([[50,0],[0,50],[50,0]] `mvmult` v))
`vadd` [8,8,8]
w2 v = (cvmult 0.01 ([[50,0],[0,50],[50,0]] `mvmult` v))
`vadd` [30,16,2]
w3 v = (cvmult 0.01 ([[50,0],[0,50],[50,0]] `mvmult` v))
`vadd` [20,40,30]
init0 :: Vector
init0 = [0,0,0]
-- Now we have an Iterated Function System:
ws :: IFS
ws = [w1,w2,w3]
-- And here is the result:
result = scanl f init0 random
where f init r = (ws!!r) init
-- where "random" is a list of random indices in the range 0-2,
-- which simulates flipping the coin in Barnsley.
-- "randomInts" is imported from the Random.hs library.
random = map (`mod` 3) (randomInts 1 3)
--------
mkNote [a,b,c] = Rest (b/20) :+: Note (pitch (round a)) (c/20) []
sourceToHaskore :: [[Float]] -> Music
sourceToHaskore s = chord (map mkNote s)
sth n = sourceToHaskore (take n result)