Skip to content

Instantly share code, notes, and snippets.

@mooman219
Last active January 25, 2020 23:45
Show Gist options
  • Save mooman219/9fd0373238604490fda8e28c6d714f85 to your computer and use it in GitHub Desktop.
Save mooman219/9fd0373238604490fda8e28c6d714f85 to your computer and use it in GitHub Desktop.
use crate::math::Polygons;
use alloc::vec;
use alloc::vec::*;
pub struct Raster {
w: usize,
h: usize,
a: Vec<f32>,
}
impl Raster {
pub fn new(w: usize, h: usize) -> Raster {
Raster {
w,
h,
a: vec![0.0; w * h + 1],
}
}
pub fn draw(&mut self, polygons: &Polygons, scale: f32) {
let scale = wide::f32x4::from(scale);
for line in &polygons.lines {
let abcd = line.abcd * scale;
// This looks bad.
self.line(abcd[0], abcd[1], abcd[2], abcd[3], line.x_mod, line.y_mod);
// self.line(abcd[0], abcd[1], abcd[2], abcd[3], efgh[0], efgh[1], efgh[2], efgh[3]);
}
}
#[inline(always)]
fn add(&mut self, index: usize, value: f32) {
unsafe {
*self.a.get_unchecked_mut(index) += value;
}
}
#[inline(always)]
fn add_smooth(&mut self, index: usize, height: f32, mid_x: f32) {
unsafe {
let mid_x = wide::f32x4::from(mid_x).fract()[0];
*self.a.get_unchecked_mut(index) += height * (1.0 - mid_x);
*self.a.get_unchecked_mut(index + 1) += height * mid_x;
}
}
#[inline(always)]
pub fn line(&mut self, x0: f32, y0: f32, x1: f32, y1: f32, x_mod: f32, y_mod: f32) {
let dx = x1 - x0;
let dy = y1 - y0;
let sx = (1f32).copysign(dx);
let sy = (1f32).copysign(dy);
let mut x = x0.floor() + x_mod;
let mut y = y0.floor() + y_mod;
let tdx = if dx == 0.0 {
1048576.0
} else {
1.0 / dx
};
let tdy = 1.0 / dy;
let mut tmx = tdx * (x - x0);
let mut tmy = tdy * (y - y0);
let tdx = tdx.abs();
let tdy = tdy.abs();
let mut x_prev = x0;
let mut y_prev = y0;
let mut x_next: f32;
let mut y_next: f32;
let mut index = (x0 as usize + y0 as usize * self.w) as isize;
let index_x_inc = sx as isize;
let index_y_inc = (sy * self.w as f32) as isize;
while tmx < 1.0 || tmy < 1.0 {
let prev_index = index;
if tmx < tmy {
y_next = tmx * dy + y0;
x_next = x;
tmx += tdx;
x += sx;
index += index_x_inc;
} else {
y_next = y;
x_next = tmy * dx + x0;
tmy += tdy;
y += sy;
index += index_y_inc;
}
self.add_smooth(prev_index as usize, y_prev - y_next, (x_prev + x_next) / 2.0);
x_prev = x_next;
y_prev = y_next;
}
self.add_smooth(index as usize, y_prev - y1, (x_prev + x1) / 2.0);
}
pub fn get_bitmap(&self) -> Vec<u8> {
let length = self.w * self.h;
let mut height = 0.0;
let mut output = Vec::with_capacity(length);
unsafe { output.set_len(length) };
let mut width = 0;
self.print();
for i in 0..length {
if width == self.w {
println!("");
width = 0;
}
width += 1;
unsafe {
height += self.a.get_unchecked(i);
// 500.99997f32
// print!(" {:>4}", ((self.a.get_unchecked(i).height) * 255.99998) as i16);
print!(" {:>4}", (height * 255.0) as i16);
*(output.get_unchecked_mut(i)) = ((height) * 255.0) as u8;
}
}
println!("");
output
}
pub fn print(&self) {
let mut width = 0;
for i in 0..(self.w * self.h) {
if width == self.w {
println!("");
width = 0;
}
width += 1;
unsafe {
print!(" {:>4}", (self.a.get_unchecked(i) * 255.0) as i16);
}
}
println!("");
println!("");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment