From 93acb5bf0e8272e74679a717c367bba2b70f5ba6 Mon Sep 17 00:00:00 2001 From: Frederic Date: Fri, 8 Dec 2017 23:47:25 +0100 Subject: [PATCH] added blobs.py --- generators/blobs.py | 126 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100755 generators/blobs.py diff --git a/generators/blobs.py b/generators/blobs.py new file mode 100755 index 0000000..9bdc9a7 --- /dev/null +++ b/generators/blobs.py @@ -0,0 +1,126 @@ +#!/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)