use embassy_ssd1306_graphics::Graphics;
use embedded_hal_async::i2c::I2c;
use crate::draw_utils::{polar_end, thick_segment, filled_disk};
#[derive(Clone, Copy, Debug)]
pub struct RoboticArm {
pub base_x: i32,
pub base_y: i32,
pub seg1_len: i32,
pub seg2_len: i32,
}
impl RoboticArm {
#[inline]
pub fn new(base_x: i32, base_y: i32, seg1_len: i32, seg2_len: i32) -> Self {
Self { base_x, base_y, seg1_len, seg2_len }
}
pub fn draw<I: I2c>(
&self,
gfx: &mut Graphics<'_, I>,
angle_shoulder: f32,
angle_elbow: f32,
on: bool,
cos_fn: fn(f32) -> f32,
sin_fn: fn(f32) -> f32,
) {
let cs = cos_fn(angle_shoulder);
let ss = sin_fn(angle_shoulder);
let (ex, ey) = polar_end(self.base_x, self.base_y, self.seg1_len, cs, ss);
let abs_elbow = angle_shoulder + angle_elbow;
let ce = cos_fn(abs_elbow);
let se = sin_fn(abs_elbow);
let (fx, fy) = polar_end(ex, ey, self.seg2_len, ce, se);
thick_segment(gfx, self.base_x, self.base_y, ex, ey, on);
thick_segment(gfx, ex, ey, fx, fy, on);
filled_disk(gfx, self.base_x, self.base_y, 3, on);
filled_disk(gfx, ex, ey, 2, on);
filled_disk(gfx, fx, fy, 2, on);
}
#[inline]
pub fn erase<I: I2c>(
&self,
gfx: &mut Graphics<'_, I>,
angle_shoulder: f32,
angle_elbow: f32,
cos_fn: fn(f32) -> f32,
sin_fn: fn(f32) -> f32,
) {
self.draw(gfx, angle_shoulder, angle_elbow, false, cos_fn, sin_fn);
}
}