Toggle Navigation
Hatchery
Eggs
maycontainh2o
__init__.py
Users
Badges
Login
Register
__init__.py
raw
Content
# By Dan Hagon (@axiomsofchoice) # 05/06/2022 at a rainy EMFCamp # See: https://2022.badge.emfcamp.org/projects/its_raining_at_emfcamp2022 # 24/07/2022 at a fast drying MCH2022 ¯\_(ツ)_/¯ # See: https://mch2022.badge.team/projects/maycontainh2o # MIT License import mch22 import buttons import display import virtualtimers as vt from math import sin, cos, pi, sqrt, atan2 from random import uniform, randrange from .bno055 import init as acc_init from .bno055 import get_accel class Particle(): def __init__(self, disp_w, disp_h, cur_acc, max_speed=5., lifetime=10): self.position = (int(uniform(0., disp_w)), int(uniform(0., disp_h))) # Speed in pixels per tick (where tick is typically 100ms) speed = uniform(.75 * max_speed, max_speed) # Make sure the generated direction is within a sector of the circle norm = sqrt(cur_acc[0] * cur_acc[0] + cur_acc[1] * cur_acc[1]) cur_dir = (cur_acc[0] / norm, cur_acc[1] / norm) rad_dir = uniform(atan2(cur_dir[0], cur_dir[1]) - (0.1 * pi), atan2(cur_dir[0], cur_dir[1]) + 0.1 * pi) self.velocity = (speed * sin(rad_dir), speed * cos(rad_dir)) self.lifetime = randrange(lifetime // 2, lifetime) self.life_line = [] def update_pos(self, accel): self.position = (self.position[0] + self.velocity[0], self.position[1] + self.velocity[1]) self.velocity = (self.velocity[0] + accel[0], self.velocity[1] + accel[1]) self.lifetime -= 1 self.life_line.append(self.position) def draw(self, ): if len(self.life_line) > 1: for i in range(len(self.life_line) - 1): display.drawLine(int(self.life_line[i][0]), int(self.life_line[i][1]), int(self.life_line[i + 1][0]), int((self.life_line[i + 1][1])), # MCH2022 Yellow 0xF9C74F) display.drawLine(int(self.pos[0]), int(self.pos[1]), int(self.pos[0] + self.vel[0]), int((self.pos[1] + self.vel[1])), # MCH2022 Light blue 0x56B5A0) @property def pos(self): return self.position @property def vel(self): return self.velocity @property def is_live(self): return self.lifetime > 0 class ParticlesApp(): def seed_particles(self, w, h, curr_acc, max_particles=18): if self.particle_state is None: self.particle_state = [] num_parts = len(self.particle_state) self.particle_state.extend([Particle(w, h, curr_acc) for _ in range(max_particles - num_parts)]) def reboot(self, pressed): if pressed: vt.delete(self.animation_tick) vt.stop() display.windowRemove(self.window_name) mch22.exit_python() def animation_tick(self): # MCH2022 Purple display.drawFill(0x532C85) # Get acceleromter value raw_acc = get_accel() f_acc = (float(raw_acc[0]), float(raw_acc[1]), float(raw_acc[2])) denom = sqrt(f_acc[0] * f_acc[0] + f_acc[1] * f_acc[1] + f_acc[2] * f_acc[2]) normalised = (f_acc[0] / denom, f_acc[1] / denom, f_acc[2] / denom) gravity = 9.8 accel_vals = (normalised[0] * gravity, normalised[1] * gravity, normalised[2] * gravity) # accel_vals = (0.0, -9.8) # Update particle state for p in self.particle_state: p.update_pos(accel_vals) # Remove the dead particles self.particle_state = [p for p in self.particle_state if p.is_live] # If necessary add new particles self.seed_particles(self.w, self.h, accel_vals) # Draw particles for p in self.particle_state: p.draw() display.flush() return self.tick_period def on_activate(self, tick_period=10): self.window_name = "maycontainh2o" self.w = display.width() self.h = display.height() display.windowCreate(self.window_name, self.w, self.h) self.particle_state = [] acc_init() buttons.attach(buttons.BTN_A, self.reboot) self.tick_period = tick_period vt.new(self.tick_period, self.animation_tick) vt.begin() app = ParticlesApp() app.on_activate()