diff --git a/demos/clouds.py b/demos/clouds.py new file mode 100644 --- /dev/null +++ b/demos/clouds.py @@ -0,0 +1,141 @@ +### clouds.py +### Author: Matthew Reed +### Random noise generated colors +### Adapted from https://github.com/scanlime/fadecandy/blob/master/examples/processing/grid24x8z_clouds/grid24x8z_clouds.pde + +import sys +import time +import signal +import logging +import configparser +from enum import Enum + +import math +import matrix +import noise +import color_utils +import random + +class Clouds: + + def __init__(self, config, parent, matrix, controller): + self.logger = logging.getLogger('paint') + self.config = config + self.parent = parent + self.matrix = matrix + self.controller = controller + + def reset(self): + pass + + def splash(self): + + r = matrix.Colors.RED.value + o = matrix.Colors.ORANGE.value + y = matrix.Colors.YELLOW.value + g = matrix.Colors.GREEN.value + b = matrix.Colors.BLUE.value + p = matrix.Colors.PURPLE.value + w = matrix.Colors.WHITE.value + v = matrix.Colors.VIOLET.value + l = matrix.Colors.LIGHT_BLUE.value + m = matrix.Colors.MAGENTA.value + q = matrix.Colors.OFF.value + + splash = [ + [q, q, q, q, q, q, q, q], + [q, q, q, q, q, q, q, q], + [q, q, r, w, p, v, q, q], + [q, q, b, g, o, m, q, q], + [q, q, r, p, y, l, q, q], + [q, q, q, q, q, q, q, q], + [q, q, q, q, q, q, q, q], + [q, q, q, q, q, q, q, q], + ] + + for x in range(0, self.matrix.WIDTH): + for y in range(0, self.matrix.HEIGHT): + self.matrix.set_pixel(x, y, splash[y][x]) + + self.matrix.update() + + def hsv_to_rgb(self, h, s, v): + if s == 0.0: return (v, v, v) + i = int(h*6.) # XXX assume int() truncates! + f = (h*6.)-i; p,q,t = v*(1.-s), v*(1.-s*f), v*(1.-s*(1.-f)); i%=6 + if i == 0: return (v, t, p) + if i == 1: return (q, v, p) + if i == 2: return (p, v, t) + if i == 3: return (p, q, v) + if i == 4: return (t, p, v) + if i == 5: return (v, p, q) + + + def fractalNoise(self, x, y, z): + r = 0 + amp = 1.0 + for octave in range(4): + r += noise.pnoise3(x, y, z) * amp; + amp /= 2; + x *= 2; + y *= 2; + z *= 2; + return r; + + def constrain(self, val, min_val, max_val): + return min(max_val, max(min_val, val)) + + def run(self): + + dx = 0.0 + dy = 0.0 + + #start timers and counters + self.start_time = time.time() + last_time = time.time() + + led_iteration_count = 0 + frame_count = 0 + + keep_going = True + + while keep_going: + + for event in self.controller.read_input(): + if event.code == 313 and event.value == 1: + keep_going = False + + if time.time() > last_time + 1: + last_time = time.time() + + + now = time.time() + speed = 0.002 + angle = math.sin(now) + z = now * 0.08 + hue = now * 10 + scale = 0.005; + + dx += math.cos(angle) * speed + dy += math.sin(angle) * speed + + for x in range(self.matrix.WIDTH): + for y in range(self.matrix.HEIGHT): + + n = self.fractalNoise(dx + x*scale, dy + y*scale, z) - 0.75 + m = self.fractalNoise(dx + x*scale, dy + y*scale, z + 10.0) - 0.75 + + color = self.hsv_to_rgb( + (hue + 80.0 * m) % 256.0, + 256 - 256 * self.constrain(pow(3.0 * abs(n), 3.5), 0, 0.9), + 256 * self.constrain(pow(3.0 * abs(n), 1.5), 0, 0.9) + ) + + self.matrix.set_pixel(x, y, color) + + self.matrix.update() + + led_iteration_count = (led_iteration_count + 1) % self.matrix.NUM_LEDS + frame_count = frame_count + 1 + + time.sleep(0.01) \ No newline at end of file