Fixed colour order and added working MP examples

feature/galactic_unicorn
ZodiusInfuser 2022-07-28 18:20:11 +01:00 zatwierdzone przez Phil Howard
rodzic 7fd175abc5
commit 82b5110691
4 zmienionych plików z 252 dodań i 120 usunięć

Wyświetl plik

@ -320,6 +320,10 @@ namespace pimoroni {
x = (WIDTH - 1) - x;
y = (HEIGHT - 1) - y;
r = (r * this->brightness) >> 8;
g = (g * this->brightness) >> 8;
b = (b * this->brightness) >> 8;
uint16_t gamma_r = r_gamma_lut[r];
uint16_t gamma_g = g_gamma_lut[g];
uint16_t gamma_b = b_gamma_lut[b];
@ -342,7 +346,7 @@ namespace pimoroni {
uint8_t green_bit = gamma_g & 0b1;
uint8_t blue_bit = gamma_b & 0b1;
*p = (blue_bit << 2) | (green_bit << 1) | (red_bit << 0);
*p = (blue_bit << 0) | (green_bit << 1) | (red_bit << 2);
gamma_r >>= 1;
gamma_g >>= 1;
@ -395,11 +399,7 @@ namespace pimoroni {
uint8_t b = (col & 0b0000000000011111) << 3;
p++;
r = (r * this->brightness) >> 8;
g = (g * this->brightness) >> 8;
b = (b * this->brightness) >> 8;
set_pixel(x, y, b, g, r);
set_pixel(x, y, r, g, b);
}
}
@ -415,11 +415,7 @@ namespace pimoroni {
uint8_t b = (col & 0x0000ff) >> 0;
p++;
r = (r * this->brightness) >> 8;
g = (g * this->brightness) >> 8;
b = (b * this->brightness) >> 8;
set_pixel(x, y, b, g, r);
set_pixel(x, y, r, g, b);
}
}

Wyświetl plik

@ -1,134 +1,123 @@
import time
import random
from picographics import PicoGraphics, DISPLAY_GALACTIC_UNICORN
from galactic import GalacticUnicorn
from ulab import numpy as np
graphics = PicoGraphics(DISPLAY_GALACTIC_UNICORN)
gu = GalacticUnicorn()
width = 53
height = 15
heat = [0.0] * 1000
#heat = np.full((width + 5, height + 5), 0.0)
@micropython.native
def set(x, y, v):
global heat
heat[x + y * width] = v
#heat[x, y] = v
@micropython.native
def get(x, y):
global heat
x = x if x >= 0 else 0
x = x if x < width else width - 1
#try:
#return heat[x, y]
return heat[x + y * width]
#except IndexError:
# pass
@micropython.native
def select_colour(x, y):
#value = heat[x, y]
value = heat[x + y * width]
if value > 0.5:
return 255, 255, 180
elif value > 0.4:
return 220, 160, 0
elif value > 0.3:
return 180, 30, 0
elif value > 0.22:
return 20, 20, 20
else:
return 0, 0, 0
def setup_landscape():
global width, height, heat, fire_spawns, damping_factor
width = GalacticUnicorn.WIDTH + 2
height = GalacticUnicorn.HEIGHT + 4
heat = [[0.0 for y in range(height)] for x in range(width)]
fire_spawns = 5
damping_factor = 0.97
@micropython.native
def calc_average(x, y):
#if x > 0:
# return (heat[x, y] + heat[x, y + 2] + heat[x, y + 1] + heat[x - 1, y + 1] + heat[x + 1, y + 1]) / 5.0
return (heat[x + (y * width)] + heat[x + ((y + 2) * width)] + heat[x + ((y + 1) * width)] + heat[(x - 1 if x >= 0 else 0) + ((y + 1) * width)] + heat[(x + 1) + ((y + 1) * width)]) / 5.0
#else:
#return (heat[x, y] + heat[x, y + 2] + heat[x, y + 1] + heat[x - 0, y + 1] + heat[x + 1, y + 1]) / 5.0
#return (heat[x + (y * width)] + heat[x + ((y + 2) * width)] + heat[x + ((y + 1) * width)] + heat[(x) + ((y + 1) * width)] + heat[(x + 1) + ((y + 1) * width)]) / 5.0
def setup_portrait():
global width, height, heat, fire_spawns, damping_factor
width = GalacticUnicorn.HEIGHT + 2
height = GalacticUnicorn.WIDTH + 4
heat = [[0.0 for y in range(height)] for x in range(width)]
fire_spawns = 2
damping_factor = 0.99
gu.set_brightness(0.3)
@micropython.native
def update():
# clear the bottom row and then add a new fire seed to it
for x in range(width):
heat[x][height - 1] = 0.0
heat[x][height - 2] = 0.0
# heat[x-1:x+2, y:y+3]
#weights = np.array([[0.0, 0.0, 0.0],
#[0.0, 0.0, 0.0],
#[0.0, 0.0, 0.0]])
landscape = True
while True:
start = time.ticks_ms()
if gu.is_pressed(21):
gu.adjust_brightness(+0.01)
if gu.is_pressed(26):
gu.adjust_brightness(-0.01)
if gu.is_pressed(0):
landscape = True
width = 53
height = 15
for i in range(0, len(heat)):
heat[i] = 0.0
if gu.is_pressed(1):
landscape = False
width = 11
height = 55
for i in range(0, len(heat)):
heat[i] = 0.0
#for y, row in enumerate(heat):
#for x, val in enumerate(row):
# print(x, y, row, val)
for y in range(0, height):
for x in range(0, width):
r, g, b = select_colour(x, y)
if landscape:
gu.set_pixel(x, y, r, g, b)
#graphics.pixel(x, y)
else:
gu.set_pixel(y, x, r, g, b)
#graphics.pixel(y, x)
for c in range(fire_spawns):
x = random.randint(0, width - 4) + 2
heat[x + 0][height - 1] = 1.0
heat[x + 1][height - 1] = 1.0
heat[x - 1][height - 1] = 1.0
heat[x + 0][height - 2] = 1.0
heat[x + 1][height - 2] = 1.0
heat[x - 1][height - 2] = 1.0
for y in range(0, height - 2):
for x in range(1, width - 1):
# update this pixel by averaging the below pixels
#average = (get(x, y) + get(x, y + 2) + get(x, y + 1) + get(x - 1, y + 1) + get(x + 1, y + 1)) / 5.0
average = calc_average(x, y)
average = (
heat[x][y] + heat[x][y + 1] + heat[x][y + 2] + heat[x - 1][y + 1] + heat[x + 1][y + 1]
) / 5.0
# damping factor to ensure flame tapers out towards the top of the displays
average *= 0.95 if landscape else 0.99
average *= damping_factor
# update the heat map with our newly averaged value
set(x, y, average)
heat[x][y] = average
#gu.update(graphics)
# clear the bottom row and then add a new fire seed to it
for x in range(0, width):
set(x, height - 1, 0.0)
@micropython.native
def draw_landscape():
for y in range(GalacticUnicorn.HEIGHT):
for x in range(GalacticUnicorn.WIDTH):
value = heat[x + 1][y]
# add a new random heat source
source_count = 5 if landscape else 1
if value < 0.15:
gu.set_pixel(x, y, 0, 0, 0)
elif value < 0.25:
gu.set_pixel(x, y, 20, 20, 20)
elif value < 0.35:
gu.set_pixel(x, y, 180, 30, 0)
elif value < 0.45:
gu.set_pixel(x, y, 220, 160, 0)
else:
gu.set_pixel(x, y, 255, 255, 180)
for c in range(0, source_count):
px = random.randint(0, width - 4) + 2
set(px , height - 2, 1.0)
set(px + 1, height - 2, 1.0)
set(px - 1, height - 2, 1.0)
set(px , height - 1, 1.0)
set(px + 1, height - 1, 1.0)
set(px - 1, height - 1, 1.0)
end = time.ticks_ms()
print("Time:", end - start)
#time.sleep(0.02)
@micropython.native
def draw_portrait():
for y in range(GalacticUnicorn.WIDTH):
for x in range(GalacticUnicorn.HEIGHT):
value = heat[x + 1][y]
if value < 0.15:
gu.set_pixel(y, x, 0, 0, 0)
elif value < 0.25:
gu.set_pixel(y, x, 20, 20, 20)
elif value < 0.35:
gu.set_pixel(y, x, 180, 30, 0)
elif value < 0.45:
gu.set_pixel(y, x, 220, 160, 0)
else:
gu.set_pixel(y, x, 255, 255, 180)
landscape = True
setup_landscape()
gu.set_brightness(0.5)
while True:
if gu.is_pressed(GalacticUnicorn.SWITCH_BRIGHTNESS_UP):
gu.adjust_brightness(+0.01)
if gu.is_pressed(GalacticUnicorn.SWITCH_BRIGHTNESS_DOWN):
gu.adjust_brightness(-0.01)
if gu.is_pressed(GalacticUnicorn.SWITCH_A):
landscape = True
setup_landscape()
if gu.is_pressed(GalacticUnicorn.SWITCH_B):
landscape = False
setup_portrait()
start = time.ticks_ms()
update()
if landscape:
draw_landscape()
else:
draw_portrait()
print("total took: {} ms".format(time.ticks_ms() - start))

Wyświetl plik

@ -0,0 +1,137 @@
import time
import random
import math
from galactic import GalacticUnicorn
gu = GalacticUnicorn()
blob_count = 10
class Blob():
def __init__(self):
self.x = float(random.randint(0, width - 1))
self.y = float(random.randint(0, height - 1))
self.r = (float(random.randint(0, 40)) / 10.0) + 5.0
self.dx = (float(random.randint(0, 2)) / 10.0) - 0.1
self.dy = (float(random.randint(0, 2)) / 10.0) - 0.05 # positive bias
@micropython.native
def setup_portrait():
global width, height, liquid, blobs
width = GalacticUnicorn.HEIGHT
height = GalacticUnicorn.WIDTH
liquid = [[0.0 for y in range(height)] for x in range(width)]
blobs = [Blob() for i in range(blob_count)]
hue = 0.0
@micropython.native
def from_hsv(h, s, v):
i = math.floor(h * 6.0)
f = h * 6.0 - i
v *= 255.0
p = v * (1.0 - s)
q = v * (1.0 - f * s)
t = v * (1.0 - (1.0 - f) * s)
i = int(i) % 6
if i == 0:
return int(v), int(t), int(p)
if i == 1:
return int(q), int(v), int(p)
if i == 2:
return int(p), int(v), int(t)
if i == 3:
return int(p), int(q), int(v)
if i == 4:
return int(t), int(p), int(v)
if i == 5:
return int(v), int(p), int(q)
@micropython.native
def update_liquid():
for y in range(height):
for x in range(width):
liquid[x][y] = 0.0
for blob in blobs:
r_sq = blob.r * blob.r
blob_y_range = range(max(math.floor(blob.y - blob.r), 0),
min(math.ceil(blob.y + blob.r), height))
blob_x_range = range(max(math.floor(blob.x - blob.r), 0),
min(math.ceil(blob.x + blob.r), width))
for y in blob_y_range:
for x in blob_x_range:
x_diff = x - blob.x
y_diff = y - blob.y
d_sq = x_diff * x_diff + y_diff * y_diff
if d_sq <= r_sq:
liquid[x][y] += 1.0 - (d_sq / r_sq)
@micropython.native
def move_blobs():
for blob in blobs:
blob.x += blob.dx
blob.y += blob.dy
if blob.x < 0.0 or blob.x >= float(width):
blob.dx = 0.0 - blob.dx
if blob.y < 0.0 or blob.y >= float(height):
blob.dy = 0.0 - blob.dy
@micropython.native
def draw_portrait():
global hue
hue += 0.001
dark_r, dark_g, dark_b = from_hsv(hue, 1.0, 0.3)
mid_r, mid_g, mid_b = from_hsv(hue, 1.0, 0.6)
bright_r, bright_g, bright_b = from_hsv(hue, 1.0, 1.0)
for y in range(height):
for x in range(width):
v = liquid[x][y]
# select a colour for this pixel based on how much
# "blobfluence" there is at this position in the liquid
if v >= 1.5:
gu.set_pixel(y, x, bright_r, bright_g, bright_b)
elif v >= 1.25:
gu.set_pixel(y, x, mid_r, mid_g, mid_b)
elif v >= 1.0:
gu.set_pixel(y, x, dark_r, dark_g, dark_b)
else:
gu.set_pixel(y, x, 0, 0, 0)
setup_portrait()
gu.set_brightness(0.5)
while True:
if gu.is_pressed(GalacticUnicorn.SWITCH_BRIGHTNESS_UP):
gu.adjust_brightness(+0.01)
if gu.is_pressed(GalacticUnicorn.SWITCH_BRIGHTNESS_DOWN):
gu.adjust_brightness(-0.01)
if gu.is_pressed(GalacticUnicorn.SWITCH_A):
setup_portrait()
start = time.ticks_ms()
update_liquid()
move_blobs()
draw_portrait()
print("total took: {} ms".format(time.ticks_ms() - start))

Wyświetl plik

@ -34,6 +34,16 @@ STATIC const mp_rom_map_elem_t GalacticUnicorn_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_WIDTH), MP_ROM_INT(53) },
{ MP_ROM_QSTR(MP_QSTR_HEIGHT), MP_ROM_INT(11) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_A), MP_ROM_INT(0) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_B), MP_ROM_INT(1) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_C), MP_ROM_INT(3) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_D), MP_ROM_INT(6) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_SLEEP), MP_ROM_INT(27) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_VOLUME_UP), MP_ROM_INT(7) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_VOLUME_DOWN), MP_ROM_INT(8) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_BRIGHTNESS_UP), MP_ROM_INT(21) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_BRIGHTNESS_DOWN), MP_ROM_INT(26) },
};
STATIC MP_DEFINE_CONST_DICT(GalacticUnicorn_locals_dict, GalacticUnicorn_locals_dict_table);