diff options
| author | Raymond Hogenson <rayhogenson@openmailbox.org> | 2016-09-27 22:58:31 -0400 |
|---|---|---|
| committer | Raymond Hogenson <rayhogenson@openmailbox.org> | 2016-09-27 22:58:31 -0400 |
| commit | fea99295c9ca99d3f3abd41b9bfaac91f4bda6dd (patch) | |
| tree | bf8c763b9cda0cf985614048758c35398b184126 /fish_render.py | |
| parent | 78fde3bb014ecd8e2368f2cc088839aecd0ca1ed (diff) | |
| download | bridge-fea99295c9ca99d3f3abd41b9bfaac91f4bda6dd.tar.zst | |
Split files and finish render code
Although it is unlikely that this code will actually run, it is split up
rather nicely such that it should be maintainable into the future.
Right now only one fish is supported, and it moves at some fixed rate
across the bridge. This is fine for a demo, but the rendering process
will need to be changed significantly before the end.
Diffstat (limited to 'fish_render.py')
| -rw-r--r-- | fish_render.py | 91 |
1 files changed, 76 insertions, 15 deletions
diff --git a/fish_render.py b/fish_render.py index be94a23..becd8c1 100644 --- a/fish_render.py +++ b/fish_render.py @@ -1,29 +1,90 @@ +"""Rendering classes and helper functions.""" +from __future__ import division, unicode_literals +import color +import random class Fish(object): - def __init__(self, x, y, width, height, color): + """Object displayed on the bridge, probably a fish.""" + def __init__(self, x, y, width, height, color, step): + """Create fish with default parameters.""" self.x = x self.y = y self.width = width self.height = height self.color = color + self.speed = step + def update(self): + """Swim gently to the other side of the bridge.""" + self.x += self.step -class BridgeRender(object): - WIDTH_SEGMENTS = 200 - HEIGHT_SEGMENTS = 2 - SAMPLES_PER_SEGMENT = 4 # Actual samples is this squared - def __init__(self, fish): +class Light(object): + """Represent a bridge light and its state.""" + def __init__(self, x, y, light, start_color, step): + """Store all facts about a light.""" + self.light = light + self.color = start_color + self.transitioning_to = start_color + self.step = step + self.x = x + self.y = y + + def update(self, fish): + """Change color depending on where the fish is.""" + if abs(self.transitioning_to - self.color) < self.step: + self.step = random_change() + self.transitioning_to = pick_HSV().to_RGB() + new_background = transition( + self.color, self.transitioning_to, self.step + ) + coverage = compute_coverage(fish, self.x, self.y) + new_color = coverage * fish.color + (1 - coverage) * new_background + self.light.setRGBRaw(*new_color.components) + + +class Bridge(object): + """Store objects on the bridge.""" + def __init__(self, lights, fish, rig): + """Initialize with lights and fish.""" + self.lights = lights self.fish = fish + self.rig = rig + + def update(self): + """Compute fish coverages and push lights to bridge.""" + for x, light_col in enumerate(self.lights): + for y, light in enumerate(light_col): + fish.update() + light.update(fish) + self.rig.updateOnce() + + +def compute_coverage(fish, x, y): + """Calculate the coverage of a fish over a box.""" + min_x = max(x, fish.x) + max_x = min(x+1, fish.x + fish.width) + min_y = max(y, fish.y) + max_y = min(y+1, fish.y + fish.height) + coverage = (max_x - min_x) * (max_y - min_y) + return coverage + + +def pick_HSV(): + """Return a random color in an appropriate interval.""" + hue = random.random() * (MAX_HUE - MIN_HUE) + MIN_HUE + saturation = random.random() + value = random.random() + return color.HSV(hue, saturation, value) + - def compute_coverage(self, x, y): - min_x = max(x, self.fish.x - self.fish.width) - max_x = min(x+1, self.fish.x + self.fish.width) - min_y = max(y, self.fish.y - self.fish.height) - max_y = min(y+1, self.fish.y + self.fish.height) +def transition(start, end, step): + """Return a vector equal to (end - start) * step + start.""" + return (end - start) / abs(end - start) * step + start - return (max_x - min_x) * (max_y - min_y) - def compute_color(self, x, y, base_color): - cov = compute_coverage(x, y) - return (cov * self.fish.color) + ((1 - cov) * base_color) +def random_change(): + """Return a random amount that a light should change each frame.""" + min_time = int(MIN_TIME * FRAME_RATE) + max_time = int(MAX_TIME * FRAME_RATE) + return 1 / random.randint(min_time, max_time) |
