diff --git a/generators/staticSinePlasma.py b/generators/staticSinePlasma.py old mode 100644 new mode 100755 index aea5625..e6a6007 --- a/generators/staticSinePlasma.py +++ b/generators/staticSinePlasma.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # inspired by: # http://lodev.org/cgtutor/plasma.html @@ -6,18 +6,24 @@ import sys import time import math -#import pygame import colorsys import blup.frame import blup.output import blup.animation import blup.writebml +import argparse + +WIDTH = 22 +HEIGHT = 16 +DEPTH = 256 class Plasma(object): - def __init__(self, width, height): + def __init__(self, width, height, test_palette=False, zoom=1): self.width = width self.height = height + self.test_palette = test_palette + self.zoom = zoom self.pixelvalues = [[0] * height for i in range(width)] self.pixelsReady = False @@ -42,7 +48,10 @@ class Plasma(object): for x in range(self.width): rowvalues = self.pixelvalues[x] for y in range(self.height): - pixeldata[x][y] = palette.getColorValue(norm(rowvalues[y])) + if y == 0 and self.test_palette: + pixeldata[x][y] = palette.getColorValue(x/(self.width-1)) + else: + pixeldata[x][y] = palette.getColorValue(norm(rowvalues[y])) return pixeldata @@ -55,25 +64,26 @@ class Plasma(object): for y in range(self.height): xx = x+self.offset yy = y+self.offset - p = 128 + 128 * math.sin(xx / 9.0) - p += 128 + 128 * math.sin(yy / 16.0) - p += 128 + 128 * math.sin((yy + xx) / 16.0) - p += 128 + 128 * math.sin(math.sqrt(yy*yy + xx*xx) / 16.0) - p += 128 + 8 * math.sin(math.sqrt(yy* xx) / 16.0) + p = 128 + 128 * math.sin(xx / 9.0 * self.zoom) + p += 128 + 128 * math.sin(yy / 16.0 * self.zoom) + p += 128 + 128 * math.sin((yy + xx) / 16.0 * self.zoom) + p += 128 + 128 * math.sin(math.sqrt(yy*yy + xx*xx * self.zoom) / 16.0) + p += 128 + 8 * math.sin(math.sqrt(yy* xx * self.zoom) / 16.0) self.pixelvalues[x][y] = p self.pixelsReady = True -class Palette(object): - def __init__(self): +class HSVPalette(object): + def __init__(self, depth): self.offset = 0 self.cache = {} + self.depth = depth def getColorValue(self, x): x = round(x, 3) if x in self.cache: return self.cache[x] c = colorsys.hsv_to_rgb((x + self.offset) % 1, 1, 1) - c = list(map(lambda x: int(x * 255), c)) + c = list(map(lambda x: int(x * (self.depth - 1)), c)) self.cache[x] = c return c @@ -83,76 +93,88 @@ class Palette(object): if self.offset > 1: self.offset -= 1 -############################################## +class ExponentialHSVPalette(object): + def __init__(self, depth): + self.offset = 0 + self.cache = {} + self.depth = depth -w = 22 -h = 16 + def getColorValue(self, x): + x = round(x, 3) + if x in self.cache: + return self.cache[x] + xx = (x + self.offset) % 1 + a = 4 + b = 3 + c = colorsys.hsv_to_rgb((a**(xx*b)-1)/(a**b), 1, 1) + c = list(map(lambda x: int(x * (self.depth - 1)), c)) + self.cache[x] = c + return c -#w = 80 -#h = 18 + def update(self): + self.cache = {} + self.offset += 0.01 + if self.offset > 1: + self.offset -= 1 -scalex = 30 -scaley = 60 +class SingleColorPalette(object): + def __init__(self, depth): + self.cache = {} + self.depth = depth + self.h = 0 + + def getColorValue(self, x): + x = round(x, 3) + if x in self.cache: + return self.cache[x] + a = 4 + b = 3 + c = colorsys.hsv_to_rgb(self.h, 1, (a**(x*b)-1)/(a**b)) + c = list(map(lambda x: int(x * (self.depth - 1)), c)) + self.cache[x] = c + return c -plasma = Plasma(w,h) -palette= Palette() + def update(self): + self.cache = {} + self.h += 0.005 + if self.h > 1: + self.h -= 1 -#screen = pygame.display.set_mode((w*scalex, h*scaley)) -#pygame.display.update() +############################################## -#dim = blup.frame.FrameDimension(w, h, 8, 3) -dim = blup.frame.FrameDimension(w, h, 256, 3) -#out = blup.output.getOutput('serialblup:/dev/ttyUSB0:115200') -#out = blup.output.getOutput('colorfulshell') -#out = blup.output.getOutput('e3blp:bastel0:4242') +PALETTES = { + 'hsv': HSVPalette, + 'exponentialhsv': ExponentialHSVPalette, + 'singlecolor': SingleColorPalette, +} + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Generate plasma animations') + parser.add_argument('-d', '--delay', type=int, default=50) + parser.add_argument('-n', '--num-frames', type=int, default=200) + parser.add_argument('-p', '--palette', choices=PALETTES.keys(), default='hsv') + parser.add_argument('-z', '--zoom', type=float, default=1) + parser.add_argument('--test-palette', action='store_true') + parser.add_argument('output_file') + args = parser.parse_args() + + plasma = Plasma(WIDTH, HEIGHT, args.test_palette, zoom=args.zoom) + dim = blup.frame.FrameDimension(WIDTH, HEIGHT, DEPTH, 3) + palette = PALETTES[args.palette](DEPTH) -if len(sys.argv) > 1: - outfile = sys.argv[1] anim = blup.animation.Animation(dim) -else: - out = blup.output.getOutput('e3blp') - anim = None - -num_frames = 200 -delay = 50 - -i = 0 -while i < num_frames: - #screen.fill((0,0,0)) - - #print 'updating palette...' - palette.update() - #print 'updating plasma...' - plasma.update() - #print 'applying palette...' - pixeldata = plasma.applyPalette(palette) - - #print 'drawing...' - if anim is not None: - frame = blup.animation.AnimationFrame(dim, delay) - else: - frame = blup.frame.Frame(dim) - - for x in range(w): - #rowdata = pixeldata[x] - for y in range(h): - #pygame.draw.rect(screen, pixeldata[x][y], (x*scalex, y*scaley, scalex, scaley), 0) - #pygame.draw.circle(screen, rowdata[y], (x, y), 1, 1) - frame.setPixel(x, y, pixeldata[x][y]) - #print frame.channels, frame.depth - #print 'done drawing' - - if anim is not None: - anim.addFrame(frame) - i += 1 - else: - out.sendFrame(frame) - time.sleep(delay / 1000) + anim.tags['description'] = ' '.join(sys.argv) + - #pygame.display.update() - #print 'done updating' - #time.sleep(0.05) + for i in range(args.num_frames): + palette.update() + plasma.update() + pixeldata = plasma.applyPalette(palette) + frame = blup.animation.AnimationFrame(dim, args.delay) -if anim is not None: - writebml.writeBml(anim, outfile) + for x in range(WIDTH): + for y in range(HEIGHT): + frame.setPixel(x, y, pixeldata[x][y]) + anim.addFrame(frame) + blup.writebml.writeBml(anim, args.output_file)