You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.3 KiB

#!/usr/bin/env python3
import sys
import random
import argparse
import blup.frame
import blup.output
import blup.animation
import blup.writebml
import colorsys
WIDTH = 22
HEIGHT = 16
DEPTH = 256
def convert_color(c):
return list(map(lambda x: int(round(x*(DEPTH-1))), c))
def get_random_color():
return colorsys.hsv_to_rgb(random.random(), 1, 1)
def get_random_point():
return (random.randint(0, WIDTH-1), random.randint(0, HEIGHT-1))
def cap(x):
return min(1, max(0, x))
def cyc(x):
while x < 0:
x += 1
while x > 1:
x -= 1
return x
class Point:
def __init__(self, pos, color, evolve):
self.pos = pos
self.color = color
self.neighbours = []
h, s, v = colorsys.rgb_to_hsv(*color)
self.evolve = evolve
if 'h' in evolve:
h += (random.random()-.5) * 0.1
if 's' in evolve:
s += (random.random()-.5) * 0.5
if 'v' in evolve:
v += (random.random()-.5) * 0.5
self.ncolor = colorsys.hsv_to_rgb(cyc(h), cap(s), cap(v))
def __eq__(self, other):
return self.pos == other.pos
def __hash__(self):
return self.pos.__hash__()
def get_neighbours(self):
for x in [-1, 0, 1]:
for y in [-1, 0, 1]:
n = (self.pos[0]+x, self.pos[1]+y)
if n[0] >= 0 and n[1] >= 0 and n[0] < WIDTH and \
n[1] < HEIGHT and abs(x+y) < 2:
yield Point(n, self.ncolor, self.evolve)
class Blob:
def __init__(self, pos, color):
e = random.choice('hsv')
if random.random() > 0.8:
e += random.choice('hsv')
p = Point(pos, color, e)
self.points = set([p])
self.candids = set(p.get_neighbours())
self.completed = False
def grow(self):
if len(self.candids) == 0:
self.completed = True
return
newp = random.sample(self.candids, 1)[0]
self.candids.remove(newp)
self.points.add(newp)
self.candids = self.candids.union(set(newp.get_neighbours()) -
self.points - self.candids)
def draw(self, frame):
for p in self.points:
frame.setPixel(p.pos[0], p.pos[1], convert_color(p.color))
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Generate blob animations')
parser.add_argument('-d', '--delay', type=int, default=50)
parser.add_argument('-t', '--time', type=int, default=15)
parser.add_argument('output_file')
args = parser.parse_args()
dim = blup.frame.FrameDimension(WIDTH, HEIGHT, DEPTH, 3)
anim = blup.animation.Animation(dim)
anim.tags['description'] = ' '.join(sys.argv)
t = 0
blobs = [Blob(get_random_point(), get_random_color())]
while t < args.time:
t += args.delay / 1000
frame = blup.animation.AnimationFrame(dim, args.delay)
for b in blobs:
for i in range(4):
b.grow()
b.draw(frame)
if len(blobs[-1].points) > WIDTH*HEIGHT*0.6 and len(blobs) < 3:
blobs.append(Blob(get_random_point(), get_random_color()))
if len(blobs) >=2 and blobs[0].completed and blobs[1].completed:
blobs.remove(blobs[0])
anim.addFrame(frame)
blup.writebml.writeBml(anim, args.output_file)