Vertex drawing

This commit is contained in:
2025-11-27 23:26:23 +01:00
parent 39d1306d93
commit 78a6cbf031
2 changed files with 123 additions and 28 deletions
+21 -28
View File
@@ -3,37 +3,30 @@ pub mod components;
use osmium::{renderer::Point, terminal}; use osmium::{renderer::Point, terminal};
fn main() { fn main() {
let (term_width, term_height) = crossterm::terminal::size().unwrap();
let a = term_height - 3;
let engine = osmium::init(); let engine = osmium::init();
let my_rect = engine.entity(|r| { engine.entity(|r| {
r.draw_rect(0, 0, 1, 2, 0xff0000); r.draw_vertex(
r.draw_rect(1, 0, 1, 2, 0x00ff00); 0,
r.draw_rect(2, 0, 1, 2, 0x0000ff); 0,
}); &[
Point { x: 0, y: 0 },
Point { x: 30, y: 0 },
Point { x: 15, y: 8 },
],
0x0000ff,
);
my_rect.component(components::Velocity(Point { x: 0, y: 0 })); r.draw_vertex_outline(
my_rect.component(components::ZigZag(term_width - 3)); 0,
0,
my_rect.set_position(0, term_height - 3); &[
Point { x: 0, y: 0 },
components::threads::tick(&engine); Point { x: 30, y: 0 },
components::threads::key(&engine); Point { x: 15, y: 8 },
],
engine.on_event({ 0xff0000,
let my_rect = my_rect.clone(); );
move |e: &crossterm::event::Event| {
if let Some(key_event) = e.as_key_event() {
match key_event.code {
crossterm::event::KeyCode::Char(' ') => {
my_rect.component(components::Jumping(0, a));
}
_ => {}
}
}
}
}); });
terminal::hide_cursor().unwrap(); terminal::hide_cursor().unwrap();
+102
View File
@@ -23,6 +23,108 @@ impl Renderer {
print_liner(self.pos.x + x, self.pos.y + y, &hex_bg(color), &rect); print_liner(self.pos.x + x, self.pos.y + y, &hex_bg(color), &rect);
} }
pub fn draw_pixel(&self, x: u16, y: u16, color: u32) {
print_liner(self.pos.x + x, self.pos.y + y, &hex_bg(color), &" \x1b[0m");
}
pub fn draw_line(&self, x0: i16, y0: i16, x1: i16, y1: i16, color: u32) {
let dx = (x1 - x0).abs();
let sx = if x0 < x1 { 1 } else { -1 };
let dy = -(y1 - y0).abs();
let sy = if y0 < y1 { 1 } else { -1 };
let mut err = dx + dy;
let (mut x, mut y) = (x0, y0);
loop {
self.draw_pixel(x as u16, y as u16, color);
if x == x1 && y == y1 {
break;
}
let e2 = 2 * err;
if e2 >= dy {
err += dy;
x += sx;
}
if e2 <= dx {
err += dx;
y += sy;
}
}
}
pub fn draw_vertex_outline(&self, x: u16, y: u16, vertices: &[Point], color: u32) {
if vertices.len() < 2 {
return;
}
for i in 0..vertices.len() {
let p0 = &vertices[i];
let p1 = &vertices[(i + 1) % vertices.len()];
self.draw_line(
x as i16 + p0.x as i16,
y as i16 + p0.y as i16,
x as i16 + p1.x as i16,
y as i16 + p1.y as i16,
color,
);
}
}
pub fn draw_vertex(&self, x: u16, y: u16, vertices: &[Point], color: u32) {
if vertices.len() < 3 {
return;
}
self.draw_vertex_outline(x, y, vertices, color);
let pts: Vec<(i32, i32)> = vertices
.iter()
.map(|p| ((p.x + x) as i32, (p.y + y) as i32))
.collect();
let min_y = pts.iter().map(|(_, y)| *y).min().unwrap();
let max_y = pts.iter().map(|(_, y)| *y).max().unwrap();
for y in min_y..=max_y {
let mut intersections = Vec::<i32>::new();
for i in 0..pts.len() {
let (x1, y1) = pts[i];
let (x2, y2) = pts[(i + 1) % pts.len()];
// same edge test as your original
if (y1 <= y && y2 > y) || (y2 <= y && y1 > y) {
let dy = y2 - y1;
let dx = x2 - x1;
let t = (y - y1) as f32 / dy as f32;
let x = (x1 as f32 + t * dx as f32).round() as i32;
intersections.push(x);
}
}
if intersections.len() < 2 {
continue;
}
intersections.sort_unstable();
// fill between pairs
for pair in intersections.chunks(2) {
if pair.len() < 2 {
continue;
}
for x in pair[0]..=pair[1] {
self.draw_pixel(x as u16, y as u16, color);
}
}
}
}
pub fn set_position(&mut self, x: u16, y: u16) { pub fn set_position(&mut self, x: u16, y: u16) {
self.pos.x = x; self.pos.x = x;
self.pos.y = y; self.pos.y = y;