Files @ 835bac5d3b3c
Branch filter:

Location: led-matrix-software/demos/clouds.py

matthewreed
Added new demos and handle splash screens and controller input
### 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)