Skip to content

Instantly share code, notes, and snippets.

@samneggs
Last active December 12, 2021 00:28
Show Gist options
  • Save samneggs/2eb074730b51b7cc0ff23148514e497d to your computer and use it in GitHub Desktop.
Save samneggs/2eb074730b51b7cc0ff23148514e497d to your computer and use it in GitHub Desktop.
Pi Pico Flood Fill and Line Fill
from LCD_3inch5 import LCD_3inch5
from machine import Pin, UART
import framebuf
from time import sleep_ms, sleep_us, ticks_diff, ticks_us, sleep
from micropython import const
import array
from usys import exit
import gc
from random import randint
MAXSCREEN_X = const(240)
MAXSCREEN_Y = const(240)
NUM_POINTS = const(1200)#350
xc=array.array('h', 0 for _ in range(NUM_POINTS))
yc=array.array('h', 0 for _ in range(NUM_POINTS))
l=array.array('h', 0 for _ in range(NUM_POINTS))
dx2=array.array('i',(-1,0,1,-1,1,-1,0,1))
dy2=array.array('i',(-1,-1,-1,0,0,1,1,1))
dx=array.array('i',(0,1,0,-1))
dy=array.array('i',(-1,0,1,0))
rand=array.array('h', randint(0,99) for _ in range(NUM_POINTS))
# Flood fill, 0.37 seconds for non-displayed fill of 240x240
# display = 1 for display while filling (slower)
@micropython.viper
def ffill(x:int,y:int,display:int,color:int):
screen_addr=ptr16(display_buffer)
xc_addr=ptr16(xc)
yc_addr=ptr16(yc)
dx_addr=ptr32(dx)
dy_addr=ptr32(dy)
l_addr=ptr16(l)
rand_addr=ptr16(rand)
xc_addr[0]=x
yc_addr[0]=y
alive=1
l_addr[0]=1
done = False
addr=y*MAXSCREEN_Y+x
back_color=screen_addr[addr]
while not done:
done = True
for i in range(0,NUM_POINTS-100):
r=rand_addr[i]
if not r:
continue
if l_addr[i]:
for j in range(0,4):
y=yc_addr[i]+dy_addr[j]
x=xc_addr[i]+dx_addr[j]
if x and y and x<240 and y<240:
addr=y*MAXSCREEN_Y+x
read_color=screen_addr[addr]
if read_color==back_color:
xc_addr[alive]=x
yc_addr[alive]=y
alive+=1
l_addr[alive]=1
screen_addr[addr]=color
done = False
if alive>NUM_POINTS-100:
alive=0
if display:
lcd.show_xy(0,0,MAXSCREEN_X-1,MAXSCREEN_Y-1,display_buffer)
from LCD_3inch5 import LCD_3inch5
from machine import Pin, UART
import framebuf
from time import sleep_ms, sleep_us, ticks_diff, ticks_us, sleep
from micropython import const
import array
from usys import exit
import gc
from random import randint
MAXSCREEN_X = const(240)
MAXSCREEN_Y = const(240)
NUM_POINTS = const(1200)#350
xc=array.array('h', 0 for _ in range(NUM_POINTS))
yc=array.array('h', 0 for _ in range(NUM_POINTS))
l=array.array('h', 0 for _ in range(NUM_POINTS))
dx2=array.array('i',(-1,0,1,-1,1,-1,0,1))
dy2=array.array('i',(-1,-1,-1,0,0,1,1,1))
dx=array.array('i',(0,1,0,-1))
dy=array.array('i',(-1,0,1,0))
rand=array.array('h', randint(0,99) for _ in range(NUM_POINTS))
# Line fill
# display = 1 for display while filling (slower)
@micropython.viper
def lfill(x:int,y:int,display:int,color:int):
screen_addr=ptr16(display_buffer)
xc_addr=ptr16(xc)
yc_addr=ptr16(yc)
dx2_addr=ptr32(dx2)
dy2_addr=ptr32(dy2)
l_addr=ptr16(l)
rand_addr=ptr16(rand)
xc_addr[0]=x
yc_addr[0]=y
alive=1
update=0
l_addr[0]=1
done = False
addr=y*MAXSCREEN_Y+x
back_color=screen_addr[addr]
while not done:
done = True
for i in range(0,NUM_POINTS-100):
if l_addr[i]:
for j in range(0,8):
y=yc_addr[i]+dy2_addr[j]
x=xc_addr[i]+dx2_addr[j]
if x and y and x<240 and y<240:
addr=y*MAXSCREEN_Y+x
read_color=screen_addr[addr]
if read_color==back_color:
xc_addr[alive]=x
yc_addr[alive]=y
alive+=1
l_addr[alive]=1
screen_addr[addr]=color
done = False
if alive>NUM_POINTS-100:
alive=0
update+=1
if display and update>10:
lcd.show_xy(0,0,MAXSCREEN_X-1,MAXSCREEN_Y-1,display_buffer)
update = 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment