kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Fixed colour order and added working MP examples
rodzic
7fd175abc5
commit
82b5110691
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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))
|
|
@ -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);
|
||||
|
|
Ładowanie…
Reference in New Issue