Created
April 21, 2024 12:04
-
-
Save stdlogicvector/9b91a6270e121b0dcdb089fac18fb797 to your computer and use it in GitHub Desktop.
Hackaday Vectorscope Badge Lorenz Attractor Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import math | |
from vectorscope import Vectorscope | |
from vos_state import vos_state | |
import vectoros | |
import keyboardcb | |
import keyleds | |
import asyncio | |
_abort = False | |
_xscale = 5 | |
_yscale = 5 | |
# Angles | |
_y = 0 | |
_p = 0 | |
_r = 0 | |
def rad2deg(r): | |
return r * 180.0 / math.pi | |
def deg2rad(d): | |
return d * math.pi / 180.0 | |
def calc(xyz, *, s=10, r=28, b=2.667): | |
x, y, z = xyz | |
x_dot = s*(y - x) | |
y_dot = r*x - y - x*z | |
z_dot = x*y - b*z | |
return [x_dot, y_dot, z_dot] | |
async def lorenz(scope): | |
global _abort, _xscale, _yscale, _y, _r, _p | |
dt = 0.005 | |
# Lorenz initial values | |
s = random.randint(5, 15) | |
a = random.randint(25, 35) | |
b = random.random() + 2.0 | |
xyz = [random.random(), random.random(), random.random()] | |
# Rotational Speeds | |
dy = 0.000 | |
dp = 0.000 | |
dr = 0.000 | |
# Offsets | |
ox = 0.0 | |
oy = 0.0 | |
oz = -s | |
print("s = " + repr(s)) | |
print("a = " + repr(a)) | |
print("b = " + repr(b)) | |
# Coordinate Buffers | |
px = [0] * 256 | |
py = [0] * 256 | |
while not _abort: | |
for i in range(0, 255): | |
xyz_dot = calc(xyz, s=s, r=a, b=b) | |
xyz[0] = xyz[0] + xyz_dot[0] * dt | |
xyz[1] = xyz[1] + xyz_dot[1] * dt | |
xyz[2] = xyz[2] + xyz_dot[2] * dt | |
#px_f = math.sin(u) * xyz[0] + math.cos(u) * xyz[1] | |
#py_f = math.cos(u) * xyz[0] - math.sin(u) * xyz[1] | |
cos_y = math.cos(_y) | |
cos_p = math.cos(_p) | |
cos_r = math.cos(_r) | |
sin_y = math.sin(_y) | |
sin_p = math.sin(_p) | |
sin_r = math.sin(_r) | |
px_f = (cos_y * cos_p) * (xyz[0] + ox) | |
px_f += (cos_y*sin_p*sin_r - sin_y*cos_r) * (xyz[1] + oy) | |
px_f += (cos_y*sin_p*cos_r + sin_y*sin_r) * (xyz[2] + oz) | |
py_f = (sin_y * cos_p) * (xyz[0] + ox) | |
py_f += (sin_y*sin_p*sin_r + cos_y*cos_r) * (xyz[1] + oy) | |
py_f += (sin_y*sin_p*cos_r - cos_y*sin_r) * (xyz[2] + oz) | |
px[i] = int(px_f * _xscale * 100) | |
py[i] = int(py_f * _yscale * 100) | |
#_y = (_y + dy) % (2*math.pi) | |
#_p = (_p + dp) % (2*math.pi) | |
#_r = (_r + dr) % (2*math.pi) | |
while not scope.wave.outBuffer_ready: | |
pass | |
scope.wave.packX(px) | |
scope.wave.packY(py) | |
scope.wave.outBuffer_ready = False | |
await asyncio.sleep_ms(5) | |
def do_abort(key): | |
global _abort | |
_abort = True | |
def do_zoom_in(key): | |
global _xscale, _yscale | |
_xscale += 1 | |
_yscale += 1 | |
if _xscale > 9: | |
_xscale = 9 | |
_yscale = 9 | |
def do_zoom_out(key): | |
global _xscale, _yscale | |
_xscale -= 1 | |
_yscale -= 1 | |
if _xscale < 1: | |
_xscale = 1 | |
_yscale = 1 | |
def do_rotate(key): | |
global _y, _r, _p | |
s = deg2rad(5.0) | |
if key == keyleds.JOY_DN: | |
_p = (_p - s) % (2 * math.pi) | |
elif key == keyleds.JOY_UP: | |
_p = (_p + s) % (2 * math.pi) | |
elif key == keyleds.JOY_RT: | |
_r = (_r - s) % (2 * math.pi) | |
elif key == keyleds.JOY_LT: | |
_r = (_r + s) % (2 * math.pi) | |
print("Pitch " + repr(rad2deg(_p))) | |
print("Roll " + repr(rad2deg(_r))) | |
async def slot_main(scope): | |
global _abort, _continue | |
vos_state.show_menu = False | |
keys = keyboardcb.KeyboardCB( | |
{keyleds.KEY_LEVEL: do_zoom_in, | |
keyleds.KEY_RANGE: do_zoom_out, | |
keyleds.JOY_UP: do_rotate, | |
keyleds.JOY_DN: do_rotate, | |
keyleds.JOY_RT: do_rotate, | |
keyleds.JOY_LT: do_rotate, | |
keyleds.KEY_MENU: do_abort} | |
) | |
await lorenz(scope) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment