refactored line drawing, broke out code.
broke the line drawing driver into seperate module.
This commit is contained in:
parent
0b363ed8e7
commit
1afb386f04
31
src/heading_drawing.rs
Normal file
31
src/heading_drawing.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use crate::line_drawing::{draw_line, FourQuadrantMatrix, Line, UPoint};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
struct Sector {
|
||||||
|
total_sectors: u8,
|
||||||
|
sectors: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
//heading starts at north, with the positive direction being clockwise.
|
||||||
|
//Heading ranges from -pi to pi.
|
||||||
|
//
|
||||||
|
//sectors have 0 at north an proceed clockwise, always being positive.
|
||||||
|
fn heading_to_sector(sectors: u8, heading: f32) -> Sector {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sector_to_line(sector: Sector, radius: usize) -> Line {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_heading<const X: usize, const Y: usize>(
|
||||||
|
heading: f32,
|
||||||
|
sectors: u8,
|
||||||
|
) -> FourQuadrantMatrix<{ X }, { Y }, u8> {
|
||||||
|
let mut ret = FourQuadrantMatrix::new(UPoint { x: X / 2, y: Y / 2 });
|
||||||
|
draw_line::<X, Y>(
|
||||||
|
§or_to_line(heading_to_sector(sectors, heading), X.max(Y)),
|
||||||
|
&mut ret,
|
||||||
|
);
|
||||||
|
ret
|
||||||
|
}
|
|
@ -1,15 +1,16 @@
|
||||||
use core::mem::swap;
|
use core::{mem::swap, ops::Index, ops::IndexMut};
|
||||||
|
|
||||||
struct Point {
|
#[derive(Debug, Clone, Copy)]
|
||||||
x: isize,
|
pub struct Point {
|
||||||
y: isize,
|
pub x: isize,
|
||||||
|
pub y: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point {
|
impl Point {
|
||||||
/// converts a point (representing a point on a 4 quadrant grid) into a upoint (representing a
|
/// converts a point (representing a point on a 4 quadrant grid) into a upoint (representing a
|
||||||
/// point on a 1 quadrant grid with the origin in the bottom-left corner). Returns none if
|
/// point on a 1 quadrant grid with the origin in the bottom-left corner). Returns none if
|
||||||
/// the resulting point would have either number negative.
|
/// the resulting point would have either number negative.
|
||||||
fn to_upoint(&self, zero_coord: &UPoint) -> Option<UPoint> {
|
pub fn to_upoint(self, zero_coord: &UPoint) -> Option<UPoint> {
|
||||||
Some(UPoint {
|
Some(UPoint {
|
||||||
x: zero_coord.x.checked_add_signed(self.x)?,
|
x: zero_coord.x.checked_add_signed(self.x)?,
|
||||||
y: zero_coord.y.checked_add_signed(self.y)?,
|
y: zero_coord.y.checked_add_signed(self.y)?,
|
||||||
|
@ -17,15 +18,16 @@ impl Point {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UPoint {
|
#[derive(Debug, Clone, Copy)]
|
||||||
x: usize,
|
pub struct UPoint {
|
||||||
y: usize,
|
pub x: usize,
|
||||||
|
pub y: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UPoint {
|
impl UPoint {
|
||||||
/// converts a upoint (representing a point on a 1 quadrant grid with the origin in the
|
/// converts a upoint (representing a point on a 1 quadrant grid with the origin in the
|
||||||
/// bottom-left corner) into a point( representing a point on a 4 quadrant grid
|
/// bottom-left corner) into a point( representing a point on a 4 quadrant grid)
|
||||||
pub fn to_point(&self, zero_coord: &UPoint) -> Point {
|
pub fn to_point(self, zero_coord: &UPoint) -> Point {
|
||||||
Point {
|
Point {
|
||||||
x: zero_coord.x as isize - self.x as isize,
|
x: zero_coord.x as isize - self.x as isize,
|
||||||
y: zero_coord.y as isize - self.y as isize,
|
y: zero_coord.y as isize - self.y as isize,
|
||||||
|
@ -33,44 +35,95 @@ impl UPoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_line<const X: usize, const Y: usize>(
|
/// A matrix that allows negative co-oordinates. Will panic if referencing out of bounds, just like
|
||||||
mut p0: Point,
|
/// a nomral matrix.
|
||||||
mut p1: Point,
|
pub struct FourQuadrantMatrix<const X: usize, const Y: usize, T> {
|
||||||
matrix: &mut [[u8; X]; Y],
|
matrix: [[T; X]; Y],
|
||||||
|
pub zero_coord: UPoint,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const X: usize, const Y: usize, T> FourQuadrantMatrix<{ X }, { Y }, T>
|
||||||
|
where
|
||||||
|
T: Copy,
|
||||||
|
T: Default,
|
||||||
|
{
|
||||||
|
pub fn new(zero_coord: UPoint) -> FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||||
|
FourQuadrantMatrix {
|
||||||
|
matrix: [[T::default(); X]; Y],
|
||||||
|
zero_coord,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, const X: usize, const Y: usize> IndexMut<Point> for FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||||
|
fn index_mut(&mut self, index: Point) -> &mut Self::Output {
|
||||||
|
let upoint = index
|
||||||
|
.to_upoint(&self.zero_coord)
|
||||||
|
.expect("would result in negative unsigned coordinate!");
|
||||||
|
&mut self.matrix[upoint.x][upoint.y]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, const X: usize, const Y: usize> Index<Point> for FourQuadrantMatrix<{ X }, { Y }, T> {
|
||||||
|
type Output = T;
|
||||||
|
|
||||||
|
fn index(&self, index: Point) -> &Self::Output {
|
||||||
|
let upoint = index
|
||||||
|
.to_upoint(&self.zero_coord)
|
||||||
|
.expect("would result in negative unsigned coordinate!");
|
||||||
|
&self.matrix[upoint.x][upoint.y]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, const X: usize, const Y: usize> From<FourQuadrantMatrix<{ X }, { Y }, T>> for [[T; X]; Y] {
|
||||||
|
fn from(value: FourQuadrantMatrix<{ X }, { Y }, T>) -> Self {
|
||||||
|
value.matrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct Line(pub Point, pub Point);
|
||||||
|
|
||||||
|
//no boxes here!
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct ULine(pub UPoint, pub UPoint);
|
||||||
|
|
||||||
|
/// Renders a line into a matrix of pixels.
|
||||||
|
pub fn draw_line<const X: usize, const Y: usize>(
|
||||||
|
line: &Line,
|
||||||
|
matrix: &mut FourQuadrantMatrix<{ X }, { Y }, u8>,
|
||||||
) {
|
) {
|
||||||
let steep = (p0.x - p1.x).abs() < (p0.y - p1.x).abs();
|
let mut line = *line;
|
||||||
|
let steep = (line.0.x - line.1.x).abs() < (line.0.y - line.1.x).abs();
|
||||||
|
|
||||||
if steep {
|
if steep {
|
||||||
swap(&mut p0.x, &mut p0.y);
|
swap(&mut line.0.x, &mut line.0.y);
|
||||||
swap(&mut p1.x, &mut p1.y);
|
swap(&mut line.1.x, &mut line.1.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if p0.x > p1.x {
|
if line.0.x > line.1.x {
|
||||||
swap(&mut p0, &mut p1)
|
swap(&mut line.0.x, &mut line.1.x);
|
||||||
|
swap(&mut line.0.y, &mut line.1.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
let dx = p1.x - p0.x;
|
let dx = line.1.x - line.0.x;
|
||||||
let dy = p1.y - p0.y;
|
let dy = line.1.y - line.0.y;
|
||||||
let derror2 = dy.abs() * 2;
|
let derror2 = dy.abs() * 2;
|
||||||
let mut error2 = 0;
|
let mut error2 = 0;
|
||||||
let mut y = p0.y;
|
let mut y = line.0.y;
|
||||||
|
|
||||||
for x in p0.x..=p1.x {
|
for x in line.0.x..=line.1.x {
|
||||||
if steep {
|
if steep {
|
||||||
matrix[y as usize][x as usize] = 1;
|
matrix[Point { x: y, y: x }] = 1;
|
||||||
} else {
|
} else {
|
||||||
matrix[x as usize][y as usize] = 1;
|
matrix[Point { x, y }] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
error2 += derror2;
|
error2 += derror2;
|
||||||
|
|
||||||
if error2 > dx {
|
if error2 > dx {
|
||||||
y += if p1.y > p0.y { 1 } else { -1 };
|
y += if line.1.y > line.0.y { 1 } else { -1 };
|
||||||
error2 -= dx * 2
|
error2 -= dx * 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn heading_to_sector(sectors: u8, heading: f32) -> u8 {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ mod calibration;
|
||||||
mod led;
|
mod led;
|
||||||
mod tilt_compensation;
|
mod tilt_compensation;
|
||||||
mod line_drawing;
|
mod line_drawing;
|
||||||
|
mod heading_drawing;
|
||||||
|
|
||||||
use microbit::{display::blocking::Display, hal::Timer};
|
use microbit::{display::blocking::Display, hal::Timer};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue