Fr3deric
7 years ago
1 changed files with 141 additions and 0 deletions
@ -0,0 +1,141 @@
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python3 |
||||
|
||||
import sys |
||||
import random |
||||
import math |
||||
import argparse |
||||
import collections |
||||
import blup.frame |
||||
import blup.output |
||||
import blup.animation |
||||
import blup.writebml |
||||
import colorsys |
||||
import functools |
||||
|
||||
|
||||
WIDTH = 22 |
||||
HEIGHT = 16 |
||||
DEPTH = 256 |
||||
|
||||
|
||||
class Point(collections.namedtuple('Point', ['x', 'y'])): |
||||
def __add__(self, other): |
||||
return Point(self.x + other.x, self.y + other.y) |
||||
def __sub__(self, other): |
||||
return Point(self.x - other.x, self.y - other.y) |
||||
@property |
||||
def len(self): |
||||
return math.sqrt(self.x**2 + self.y**2) |
||||
|
||||
|
||||
class PointLenOrder: |
||||
def __init__(self, value): |
||||
self.value = value |
||||
def __eq__(self, other): |
||||
return other.value.len == self.value.len |
||||
def __lt__(self, other): |
||||
return other.value.len < self.value.len |
||||
|
||||
|
||||
DIRECTIONS = [ Point(x, y) for x in [-1, 1] for y in [-1, 1] ] |
||||
|
||||
|
||||
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(), 0.5 + random.random() / 2, 1) |
||||
|
||||
|
||||
class Line: |
||||
def __init__(self, worldsize): |
||||
self.worldsize = worldsize |
||||
self.line = [Point(random.randint(0, worldsize.x), |
||||
random.randint(0, worldsize.y))] |
||||
self.slen = 1 |
||||
self.dir = random.choice(DIRECTIONS) |
||||
self.color = get_random_color() |
||||
diaglen = int(math.sqrt(worldsize.x**2 + worldsize.y**2)) |
||||
self.maxlen = random.randint(diaglen, diaglen * 3) |
||||
self.fadeout_time = 2 + random.random() * 2 |
||||
self.fadeout_remaining = None |
||||
self.finished = False |
||||
|
||||
def check_bounds(self, p): |
||||
return p.x < self.worldsize.x and p.x >= 0 \ |
||||
and p.y < self.worldsize.y and p.y >= 0 |
||||
|
||||
def update(self, t, dt): |
||||
if len(self.line) < self.maxlen: |
||||
if self.slen >= 3 and random.random() < 0.4: |
||||
dirs = list(DIRECTIONS) |
||||
dirs.remove(self.line[-1] - self.line[-2]) |
||||
if self.check_bounds(self.line[-1]): |
||||
newp = None |
||||
while newp is None or newp == self.line[-2]: |
||||
self.dir = random.choice(dirs) |
||||
newp = self.line[-1] + self.dir |
||||
else: |
||||
dirs.sort(key=lambda d: ((self.line[-1]+d) - Point(0, 0)).len) |
||||
self.dir = dirs[0] |
||||
self.slen = 1 |
||||
else: |
||||
self.slen += 1 |
||||
self.line.append(self.line[-1] + self.dir) |
||||
else: |
||||
if self.fadeout_remaining is None: |
||||
self.fadeout_remaining = self.fadeout_time |
||||
elif self.fadeout_remaining <= 0: |
||||
self.finished = True |
||||
else: |
||||
self.fadeout_remaining -= dt |
||||
|
||||
def draw(self, frame): |
||||
if self.fadeout_remaining is not None: |
||||
if self.fadeout_remaining > 0: |
||||
h, s, v = colorsys.rgb_to_hsv(*self.color) |
||||
v = v * (self.fadeout_remaining / self.fadeout_time) |
||||
color = colorsys.hsv_to_rgb(h, s, v) |
||||
else: |
||||
color = (0, 0, 0) |
||||
else: |
||||
color = self.color |
||||
for p in self.line: |
||||
if self.check_bounds(p): |
||||
frame.setPixel(p.x, p.y, convert_color(color)) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
parser = argparse.ArgumentParser(description='Generate 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) |
||||
|
||||
|
||||
lines = [Line(Point(WIDTH, HEIGHT))] |
||||
t = 0 |
||||
dt = args.delay / 1000 |
||||
while t < args.time: |
||||
t += dt |
||||
frame = blup.animation.AnimationFrame(dim, args.delay) |
||||
|
||||
for l in lines: |
||||
l.update(t, dt) |
||||
l.draw(frame) |
||||
|
||||
if lines[-1].fadeout_remaining is not None: |
||||
lines.append(Line(Point(WIDTH, HEIGHT))) |
||||
|
||||
for l in lines: |
||||
if l.finished: |
||||
lines.remove(l) |
||||
|
||||
anim.addFrame(frame) |
||||
|
||||
blup.writebml.writeBml(anim, args.output_file) |
Loading…
Reference in new issue