move triangle methods onto Triangle struct
This commit is contained in:
parent
59d264a38f
commit
88a406f84d
1 changed files with 74 additions and 44 deletions
108
src/main.rs
108
src/main.rs
|
@ -44,26 +44,23 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_triangles(fb: &mut TGAImage) {
|
fn fill_triangles(fb: &mut TGAImage) {
|
||||||
/*
|
|
||||||
triangle( 7, 45, 35, 100, 45, 60, framebuffer, red);
|
|
||||||
triangle(120, 35, 90, 5, 45, 110, framebuffer, white);
|
|
||||||
triangle(115, 83, 80, 90, 85, 120, framebuffer, green);
|
|
||||||
*/
|
|
||||||
|
|
||||||
let t1a = Point2i::new(7, 45);
|
let t1a = Point2i::new(7, 45);
|
||||||
let t1b = Point2i::new(35, 100);
|
let t1b = Point2i::new(35, 100);
|
||||||
let t1c = Point2i::new(45, 60);
|
let t1c = Point2i::new(45, 60);
|
||||||
triangle_filled(t1a, t1b, t1c, RED, fb);
|
let t1 = Triangle::new(t1a, t1b, t1c);
|
||||||
|
t1.render_filled(RED, fb);
|
||||||
|
|
||||||
let t2a = Point2i::new(120, 35);
|
let t2a = Point2i::new(120, 35);
|
||||||
let t2b = Point2i::new(90, 5);
|
let t2b = Point2i::new(90, 5);
|
||||||
let t2c = Point2i::new(45, 110);
|
let t2c = Point2i::new(45, 110);
|
||||||
triangle_filled(t2a, t2b, t2c, WHITE, fb);
|
let t2 = Triangle::new(t2a, t2b, t2c);
|
||||||
|
t2.render_filled(WHITE, fb);
|
||||||
|
|
||||||
let a = Point2i::new(115, 83);
|
let a = Point2i::new(115, 83);
|
||||||
let b = Point2i::new(80, 90);
|
let b = Point2i::new(80, 90);
|
||||||
let c = Point2i::new(85, 120);
|
let c = Point2i::new(85, 120);
|
||||||
triangle_filled(a, b, c, GREEN, fb);
|
let t3 = Triangle::new(a, b, c);
|
||||||
|
t3.render_filled(GREEN, fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _render_diablo(model: Model, fb: &mut TGAImage) {
|
fn _render_diablo(model: Model, fb: &mut TGAImage) {
|
||||||
|
@ -150,48 +147,81 @@ fn line(mut a: Point2i, mut b: Point2i, color: TGAColor, mut fb: &mut TGAImage)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triangle_lines(a: Point2i, b: Point2i, c: Point2i, color: TGAColor, fb: &mut TGAImage) {
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
line(a, b, color, fb);
|
struct Triangle {
|
||||||
line(b, c, color, fb);
|
a: Point2i,
|
||||||
line(c, a, color, fb);
|
b: Point2i,
|
||||||
|
c: Point2i,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triangle_filled(a: Point2i, b: Point2i, c: Point2i, color: TGAColor, fb: &mut TGAImage) {
|
impl Triangle {
|
||||||
|
pub fn new(a: Point2i, b: Point2i, c: Point2i) -> Self {
|
||||||
let mut sorted = [a, b, c];
|
let mut sorted = [a, b, c];
|
||||||
sorted.sort_unstable_by(|a, b| a.y.cmp(&b.y));
|
sorted.sort_unstable_by(|a, b| a.y.cmp(&b.y));
|
||||||
let [a, b, c] = sorted;
|
let [a, b, c] = sorted;
|
||||||
|
Self { a, b, c }
|
||||||
|
}
|
||||||
|
|
||||||
let total_height = c.y - a.y;
|
pub fn signed_area(&self) -> f32 {
|
||||||
|
0.5 * ((self.b.y - self.a.y) * (self.a.x + self.b.x)
|
||||||
|
+ (self.c.y - self.b.y) * (self.c.x + self.b.x)
|
||||||
|
+ (self.a.y - self.c.y) * (self.a.x + self.c.x)) as f32
|
||||||
|
}
|
||||||
|
|
||||||
let (lower_left, upper_right) = triangle_bb(a, b, c);
|
pub fn bb(&self) -> AABB {
|
||||||
for y in lower_left.y..=upper_right.y {
|
let xmax = self.a.x.max(self.b.x.max(self.c.x));
|
||||||
let a = Point2i::new(lower_left.x, y);
|
let xmin = self.a.x.min(self.b.x.min(self.c.x));
|
||||||
let b = Point2i::new(upper_right.x, y);
|
|
||||||
|
let ymax = self.a.y.max(self.b.y.max(self.c.y));
|
||||||
|
let ymin = self.a.y.min(self.b.y.min(self.c.y));
|
||||||
|
AABB {
|
||||||
|
lower_left: Point2i::new(xmin, ymin),
|
||||||
|
upper_right: Point2i::new(xmax, ymax),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn render_filled(&self, color: TGAColor, fb: &mut TGAImage) {
|
||||||
|
let bb = self.bb();
|
||||||
|
for y in bb.ymin()..=bb.ymax() {
|
||||||
|
let a = Point2i::new(bb.xmin(), y);
|
||||||
|
let b = Point2i::new(bb.xmax(), y);
|
||||||
line(a, b, color, fb);
|
line(a, b, color, fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
let segment_height = b.y - a.y;
|
|
||||||
for y in a.y..=b.y {
|
|
||||||
let dy = y - a.y;
|
|
||||||
let x1 = a.x + ((c.x - a.x) * dy) / total_height;
|
|
||||||
let x2 = a.x + ((b.x - a.x) * dy) / segment_height;
|
|
||||||
line(Point2i::new(x1, y), Point2i::new(x2, y), color, fb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let segment_height = c.y - b.y;
|
pub fn render_lines(&self, color: TGAColor, fb: &mut TGAImage) {
|
||||||
for y in b.y..=c.y {
|
line(self.a, self.b, color, fb);
|
||||||
let x1 = a.x + ((c.x - a.x) * (y - a.y)) / total_height;
|
line(self.b, self.c, color, fb);
|
||||||
let x2 = b.x + ((c.x - b.x) * (y - b.y)) / segment_height;
|
line(self.c, self.a, color, fb);
|
||||||
line(Point2i::new(x1, y), Point2i::new(x2, y), color, fb);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn triangle_bb(a: Point2i, b: Point2i, c: Point2i) -> (Point2i, Point2i) {
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
let xmax = a.x.max(b.x.max(c.x));
|
struct AABB {
|
||||||
let xmin = a.x.min(b.x.min(c.x));
|
lower_left: Point2i,
|
||||||
|
upper_right: Point2i,
|
||||||
let ymax = a.y.max(b.y.max(c.y));
|
}
|
||||||
let ymin = a.y.min(b.y.min(c.y));
|
|
||||||
|
impl AABB {
|
||||||
(Point2i::new(xmin, ymin), Point2i::new(xmax, ymax))
|
pub fn new(lower_left: Point2i, upper_right: Point2i) -> Self {
|
||||||
|
Self {
|
||||||
|
lower_left,
|
||||||
|
upper_right,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xmin(&self) -> i32 {
|
||||||
|
self.lower_left.x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn xmax(&self) -> i32 {
|
||||||
|
self.upper_right.x
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ymin(&self) -> i32 {
|
||||||
|
self.lower_left.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ymax(&self) -> i32 {
|
||||||
|
self.upper_right.y
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue