Fr3deric
7 years ago
1 changed files with 124 additions and 0 deletions
@ -0,0 +1,124 @@
@@ -0,0 +1,124 @@
|
||||
#!/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 |
||||
|
||||
|
||||
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) |
||||
def __mul__(self, other): |
||||
if isinstance(other, Point): |
||||
raise Exception('not implemented') |
||||
else: |
||||
return Point(self.x * other, self.y * other) |
||||
def __truediv__(self, other): |
||||
if isinstance(other, Point): |
||||
raise ValueError() |
||||
else: |
||||
return self * (1/other) |
||||
@property |
||||
def len(self): |
||||
return math.sqrt(self.x**2 + self.y**2) |
||||
@property |
||||
def n(self): |
||||
n = Point(self.y, -self.x) |
||||
return n / n.len |
||||
@property |
||||
def intp(self): |
||||
return Point(int(round(self.x)), int(round(self.y))) |
||||
|
||||
|
||||
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 Twister: |
||||
def __init__(self, worldsize): |
||||
self.worldsize = worldsize |
||||
self.cycletime = 1.3 |
||||
self.sat = 0.5 + random.random() / 2 |
||||
self.hues = [random.random()] |
||||
self.hues += [ self.hues[0] + (i+1) * 0.25 for i in range(3) ] |
||||
random.shuffle(self.hues) |
||||
self.width = worldsize.x // 2.9 |
||||
|
||||
def update(self, t, dt): |
||||
# inspired by https://www.lexaloffle.com/bbs/?tid=3050 |
||||
|
||||
self.rows = [] |
||||
a0 = t * math.pi / self.cycletime |
||||
while len(self.rows) < self.worldsize.y: |
||||
y = len(self.rows) |
||||
a = a0 - y * math.pi / self.worldsize.y \ |
||||
* (math.sin(t * math.pi / 10) * 0.7) |
||||
ot1 = t * math.pi / 5 |
||||
ot2 = y * math.pi / (self.worldsize.y * 2) |
||||
offs = self.worldsize.x / 2 + math.sin(ot1 + ot2) * self.width / 2 |
||||
x1 = int(round(offs + self.width * math.sin(a))) |
||||
x2 = int(round(offs + self.width * math.sin(a+0.5*math.pi))) |
||||
x3 = int(round(offs + self.width * math.sin(a+math.pi))) |
||||
x4 = int(round(offs + self.width * math.sin(a+1.5*math.pi))) |
||||
row = [] |
||||
for i, (start, end) in enumerate([(x1, x2), (x2, x3), |
||||
(x3, x4), (x4, x1)]): |
||||
if start < end: |
||||
row += [(x, i, (x - start) / (end - start - 1)) |
||||
for x in range(start, end - 1)] |
||||
self.rows.append(row) |
||||
|
||||
def draw(self, frame): |
||||
for y, line in enumerate(self.rows): |
||||
for point in line: |
||||
x, i, j = point |
||||
val = 1 - math.sin(j * math.pi) / 2.3 |
||||
color = colorsys.hsv_to_rgb(self.hues[i], self.sat, val) |
||||
try: |
||||
frame.setPixel(x, y, convert_color(color)) |
||||
except ValueError: |
||||
pass |
||||
|
||||
|
||||
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) |
||||
|
||||
twister = Twister(Point(WIDTH, HEIGHT)) |
||||
t = 0 |
||||
dt = args.delay / 1000 |
||||
while t < args.time: |
||||
t += dt |
||||
frame = blup.animation.AnimationFrame(dim, args.delay) |
||||
|
||||
twister.update(t, dt) |
||||
twister.draw(frame) |
||||
|
||||
anim.addFrame(frame) |
||||
|
||||
blup.writebml.writeBml(anim, args.output_file) |
Loading…
Reference in new issue