use crate::{ block::Block, format::ser::map_scalar8, frame::Frame, helpers::vector::Vec2, helpers::{matrix::Mat2, pixel::Pixel}, view::View, }; impl View<&mut Frame> { pub fn draw_box(&mut self, color: Pixel) { let w = self.size.x; let h = self.size.y; for x in 0..w { self[(x, 0)] = color; self[(x, h - 1)] = color; } for y in 0..h { self[(0, y)] = color; self[(w - 1, y)] = color; } } } impl Frame { pub fn draw_line(&mut self, start: Vec2, end: Vec2, color: Pixel) { let diff = end - start; let len = (diff.x * diff.x + diff.y * diff.y).sqrt(); let normal = Vec2 { x: diff.x / len, y: diff.y / len, }; let mut cursor = start.clone(); let mut lc = 0.0; while lc < len { self.set(cursor.into(), color); lc += 0.5; cursor = cursor + normal.scale(0.5); } } } impl Pixel { pub const RED: Pixel = Pixel { r: 255, g: 0, b: 0 }; pub const GREEN: Pixel = Pixel { r: 0, g: 255, b: 0 }; pub const BLUE: Pixel = Pixel { r: 0, g: 0, b: 255 }; pub const MAGENTA: Pixel = Pixel { r: 255, g: 0, b: 255, }; pub const CYAN: Pixel = Pixel { r: 0, g: 255, b: 255, }; } pub fn draw_debug(block: &Block, mut target: View<&mut Frame>) { match &block { Block::Literal(_) | Block::CompressedLiteral(_) => { target.draw_box(Pixel::GREEN); } Block::Split(box [a, b]) => { let [at, bt] = target.split_mut_unsafe(); draw_debug(a, at); draw_debug(b, bt); } Block::Reference { translation } => { target.draw_box(Pixel::BLUE); target.frame.draw_line( target.center().into(), (target.center() + *translation).into(), Pixel::RED, ) } Block::AdvancedReference(r) => { let mat = Mat2 { a: map_scalar8(r.transform.a), b: map_scalar8(r.transform.b), c: map_scalar8(r.transform.c), d: map_scalar8(r.transform.d), }; let translation = Vec2 { x: map_scalar8(r.translation.x), y: map_scalar8(r.translation.y), }; let halfsize = Into::>::into(target.size).scale(0.5); let transform = |p| translation + mat.transform(p - halfsize) + halfsize; let (tl, tr, bl, br) = ( transform(Vec2::::ZERO) + target.offset.into(), transform(target.size.x_only().into()) + target.offset.into(), transform(target.size.y_only().into()) + target.offset.into(), transform(target.size.into()) + target.offset.into(), ); target.draw_box(Pixel::CYAN); target.frame.draw_line(tl, tr, Pixel::MAGENTA); target.frame.draw_line(tr, br, Pixel::MAGENTA); target.frame.draw_line(bl, br, Pixel::MAGENTA); target.frame.draw_line(tl, bl, Pixel::MAGENTA); } }; }