Skip to content

Instantly share code, notes, and snippets.

@todbot
Last active April 2, 2024 00:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save todbot/8ea13cebb1c3a510444428cc98d2f1af to your computer and use it in GitHub Desktop.
Save todbot/8ea13cebb1c3a510444428cc98d2f1af to your computer and use it in GitHub Desktop.
spirograph fun w/ bitmapfilter in CircuitPython
# bitmapfilter_play2_code.py -- spirograph fun w/ bitmapfilter
# 1 Apr 2024 - @todbot / Tod Kurt
import time, math, random
import board
import rainbowio
import vectorio
import displayio
import bitmaptools
import bitmapfilter
display = board.DISPLAY
display.auto_refresh = False
dw,dh = display.width, display.height
cx,cy = dw//2, dh//2
display.root_group = displayio.Group()
bitmap = displayio.Bitmap(dw, dh, 65535)
pixel_shader = displayio.ColorConverter(input_colorspace=displayio.Colorspace.RGB565_SWAPPED)
tile_grid = displayio.TileGrid(bitmap, pixel_shader=pixel_shader)
display.root_group.append(tile_grid)
color_converter = displayio.ColorConverter(input_colorspace=displayio.Colorspace.RGB888)
def swap(v):
"""swap high & low bytes of 16-bit number, since RGB565_SWAPPED"""
return ((v & 0xff) << 8) | ((v >> 8) & 0xff)
def to_bitmap_color(c):
"""convert RGB888 to RGB565_SWAPPED, surely there's a better way for this, gotta chat w/jepler"""
return swap(color_converter.convert(c))
def make_spirograph(a,b,h, dt=0.05, colr=0xffff):
""" from: https://samjbrenner.com/notes/processing-spirograph/"""
t = 0
ot = dt
od = a*ot
ab = a-b
oxpos = int( ab*math.cos(ot) + h*math.cos(od))
oypos = int( ab*math.sin(ot) + h*math.sin(od))
while t < 6.28:
d = a*t
xpos = int( ab*math.cos(t) + h*math.cos(d))
ypos = int( ab*math.sin(t) + h*math.sin(d))
bitmaptools.draw_line(bitmap, cx+oxpos, cy+oypos, cx+xpos, cy+ypos, colr)
ot, od = t, d # save last angle and positions
oxpos, oypos = xpos, ypos
t += dt
a = 30 # spirograph parameter
b = 50 # spirograph parameter
h = 70 # spirograph parameter
dim = bitmapfilter.ChannelScale(0.75, 0.75, 0.75)
last_time = 0
tic = 100 # position in phase space, arbitrary starting point
while True:
tic += 0.01
print("%.2f spiro! %3.2f %.2f, %.2f, %.2f" %(time.monotonic(), tic, a,b,h))
a = 100 + 50 * math.sin(tic/5) # evolve our spirograph settings
h = 50 + 50 * math.sin(tic*3) # evolve our spirograph settings
colr = to_bitmap_color(rainbowio.colorwheel(time.monotonic()*15))
make_spirograph( a, b, h, dt=0.03, colr=colr )
if time.monotonic() - last_time > 0.1:
last_time = time.monotonic()
tile_grid.bitmap = bitmapfilter.mix(bitmap, dim)
display.refresh()
@todbot
Copy link
Author

todbot commented Apr 2, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment