This repository has been archived by the owner on Dec 15, 2018. It is now read-only.
/
Flame.py
121 lines (110 loc) · 3.9 KB
/
Flame.py
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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/python
"""
One fractal flame, which contains several Variations, here called Petals
"""
import io, json, pprint, random, math
from Petal import Petal
class Flame():
"""
calculates a fractal flame similar but not exactly like in flam3
"""
MaxFill=100 # the exit criteria for stopping the chaos game
def __init__(self):
"""puts 3 standard petals into the flame"""
self.petals=[Petal(), Petal(1), Petal(2), Petal(3)]
def getConfig(self):
"""the vector of all petals, themselves as data vectors"""
data=[ pet.get() for pet in self.petals]
return data
def fillConfig(self, data):
"""replaces the petals with ones obtained from data"""
self.petals=[ Petal(en) for en in data ]
def read(self, fn):
"""reads a json file and creates the petals"""
print('reading <- %s' %(fn))
data=[]
with io.open(fn, 'r') as datafile:
data=json.load(datafile)
self.fillConfig(data)
def write(self, fn):
"""creates a json file with all parameters"""
print('writing -> %s' % (fn))
data=self.getConfig()
with io.open(self.fn, 'w') as datfile:
json.dump(data, datfile)
def mutate(self):
"""carries out one mutation"""
probN=random.random()
if probN < 0.001:
pet=Petal(random.randomint(0, 1e9))
pet.mutate()
self.petals.append(pet)
else:
pet=random.choice(self.petals)
pet.mutate()
if pet.prob < 0.01:
self.petals.remove(pet)
probSum=0
for pet in self.petals:
probSum+= pet.prob
probSum=1/probSum
for pet in self.petals:
pet.prob*=probSum
def calculate(self, parent, width, height, callback):
"""
carries out the Chaos Game with all petals - time consuming
It randomly selects a petal and let the petal calculate the new point, the points are recorded into histograms, one for each color.
At the end the logarithm is taken of all buckets and the maximal value is recorded in maxd.
The callback is called with the parent and self.
Divergent flames are re-initialized with a random point in the center square.
"""
buckets=[[ [0]*3 for i in range(height)] for j in range(width)]
x, y= random.random()-0.5, random.random()-0.5
outside=0
dim=width
if height<dim:
dim=height
dim = dim/2
mw=width
hw=mw/2
mh=height
hh=mh/2
iteration=0
while True:
iteration+=1
petal=random.choice(self.petals)
x, y = petal.calculate(x, y)
fx=math.floor( x*dim+hw)
fy=math.floor(y*dim+hh)
if fx<0 or fx>=mw or fy<0 or fy>=mh:
outside+=1
if outside >10:
x, y = random.random()-0.5, random.random()-0.5
#self.dead=True
#callback(self, buckets, 0)
#return
continue
else:
outside=0
d=0
for c in range(3):
buckets[fx][fy][c]+=petal.colors[c]
d+=buckets[fx][fy][c]
if d > self.MaxFill:
break
pprint(iteration)
maxd=0
for i in range(width):
for j in range(height):
for c in range(3):
d=buckets[i][j][c]
if d>1:
d=math.log(d)
if d>maxd:
maxd=d
else:
d=0
buckets[i][j][c]=d
self.buckets=buckets
self.maxd=maxd
callback(parent, self)