Check out the Pastebin Gadgets Shop. We have thousands of fun, geeky & affordable gadgets on sale :-)Want more features on Pastebin? Sign Up, it's FREE!
tweet

# Golly Python script to output meta-life animation

By: a guest on May 13th, 2012  |  syntax: Python  |  size: 3.88 KB  |  views: 792  |  expires: Never
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
1. from __future__ import division
2.
3. import golly as g
4. from math import floor, ceil, log
5. from os import system, unlink
6.
7. resx, resy = 1920, 1080 # woo 1080p
8. osa = 3 # 3x3 oversampling
9. framerate = 30
10. #resx, resy = 160, 90
11. #osa = 2
12. #framerate = 5
13. framecount = framerate*90 # 90 seconds long seems reasonable
15. cellsize = osa # make cells larger by a full pixel in each direction, to cut down on moire effects
16.
17. centrex, centrey = 114500, 4365
18. initw, inith = 96, 54
19. finalscale = 11.0 # so that we scale out by a factor of 2**11 over the animation
20. finalratefact = 17.0  # so that we speed up by a factor of 2**17 over the animation (the metapixels animate at about 2**-15 of the speed)
21. initrate = 1 # initially approx one step per second
22. initrateadj = initrate * framecount/framerate/(finalratefact*log(2)) # magic calculation to make it so that d/dt of setframe(t) at 0 is initrate
23.
24. curstep = 0
25. def setstep(n):
26.         global curstep
27.         n = int(round(n))
28.         if n < curstep:
29.                 return
30.         g.run(n - curstep)
31.         curstep = n
32.
33. def setframe(t):
34.         setstep(initrateadj * 2**(finalratefact * t))
35.
36. class Rect:
37.         def __init__(self, l, t, w, h):
38.                 self.left = l
39.                 self.top = t
40.                 self.width = w
41.                 self.height = h
42.
43. def calcscale(t):
44.         if t < 3*framerate/framecount:
45.                 t = 3*framerate/framecount # don't zoom out for the first 3 seconds
46.         w = initw * 2**(finalscale * t)
47.         h = inith * 2**(finalscale * t)
48.         l = centrex - w / 2.0
49.         t = centrey - h / 2.0
50.         return Rect(l,t,w,h)
51.
52. def clamp(x,minim,maxim):
53.         if x < minim:
54.                 return minim
55.         if x > maxim:
56.                 return maxim
57.         return x
58.
59. def doframe(n):
60.         t = n/framecount
61.         setframe(t)
62.         sc = calcscale(t)
63.         # get all the cells in the view area
64.         cells = g.getcells([sc.left, sc.top, sc.width, sc.height])
65.         # generate a large image (for oversampling)
66.         output = [[0 for x in xrange(resx * osa)] for y in xrange(resy * osa)]
67.         # draw all the live cells on the image
68.         for i in xrange(0, len(cells), 2):
69.                 cellx, celly = cells[i:i+2]
70.                 # find the bounds of this cell on the screen
71.                 xmin = int(floor(((cellx - sc.left) / sc.width) * resx * osa))
72.                 xmax = int(floor(((cellx - sc.left + 1) / sc.width) * resx * osa)) + 1
73.                 ymin = int(floor(((celly - sc.top) / sc.height) * resy * osa))
74.                 ymax = int(floor(((celly - sc.top + 1) / sc.height) * resy * osa)) + 1
75.                 # make the cells slightly larger and overlapping, to reduce the moire effects
76.                 xmin -= cellsize
77.                 ymin -= cellsize
78.                 xmax += cellsize
79.                 ymax += cellsize
80.                 # draw the cell on the image
81.                 xmin = clamp(xmin, 0, resx * osa)
82.                 xmax = clamp(xmax, 0, resx * osa)
83.                 ymin = clamp(ymin, 0, resy * osa)
84.                 ymax = clamp(ymax, 0, resy * osa)
85.                 for y in xrange(ymin, ymax):
86.                         output[y][xmin:xmax] = [1] * (xmax - xmin)
87.         # Scale down the oversampled image to the target size, by averaging
88.         if osa > 1:
89.                 output = [[sum(output[i][j] for i in xrange(y*osa,(y+1)*osa) for j in xrange(x*osa,(x+1)*osa)) for x in xrange(resx)] for y in xrange(resy)]
90.         # Save the image as a PGM, and then use ImageMagick to convert it to PNG
91.         with open(outputmask % (n, "pgm"), 'w') as fp:
92.                 fp.write("P2\n%d %d\n%d\n" % (resx, resy, osa*osa))
93.                 sc = calcscale(t)
94.                 for row in output:
95.                         fp.write(' '.join(map(str,row)))
96.                         fp.write('\n')
97.         system("convert %s -depth 8 %s" % (outputmask % (n, "pgm"), outputmask % (n, "png")))
99.
100. # Parameters so that I can run several instances of Golly and have them render separate slices of the frames
101. # and thus make use of my multicore CPU...
102. def main(step=1,start=0):
103.         global curstep
104.         g.reset()
105.         curstep = 0
106.         for i in xrange(start,framecount,step):
107.                 g.show("Frame %d of %d..." % (i+1, framecount));
108.                 doframe(i)
109.
110. main()
111. # or, make copies of the script and have each copy have one of, eg:
112. #main(3,0)
113. #main(3,1)
114. #main(3,2)
115. # and then run three instances of Golly and have each run a different copy of the script
clone this paste RAW Paste Data
Top