From f467334b26f31b19ebbd222de2b4167b1538ccee Mon Sep 17 00:00:00 2001 From: Julian T Date: Thu, 28 Jan 2021 23:53:56 +0100 Subject: Unfinished film --- src/bound.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ src/bounding.rs | 62 ---------------------------------- src/camera/film.rs | 14 +++++--- src/camera/filter/mod.rs | 24 ++++++++++---- src/lib.rs | 2 +- src/vector.rs | 19 +++++++++++ 6 files changed, 132 insertions(+), 75 deletions(-) create mode 100644 src/bound.rs delete mode 100644 src/bounding.rs diff --git a/src/bound.rs b/src/bound.rs new file mode 100644 index 0000000..b7ce05d --- /dev/null +++ b/src/bound.rs @@ -0,0 +1,86 @@ +use crate::{Number, Float}; +use crate::vector::*; + +pub struct Bound2 { + pub min: Vector2, + pub max: Vector2 +} + +pub type Bound2i = Bound2; +pub type Bound2f = Bound2; + +fn min (a: T, b: T) -> T { + if b < a { + return b; + } + a +} + +fn max (a: T, b: T) -> T { + if b > a { + return b; + } + a +} + +impl Bound2 { + fn new(p0: &Vector2, p1: &Vector2) -> Bound2 { + let min = Vector2::from_xy(min(p0.x, p1.x), min(p0.y, p1.y)); + let max = Vector2::from_xy(max(p0.x, p1.x), max(p0.y, p1.y)); + + Bound2 { min, max } + } + + fn diagonal(&self) -> Vector2 { + self.max - self.min + } + + fn area(&self) -> T { + let diag = self.diagonal(); + return diag.x * diag.y; + } +} + +impl From<&Bound2i> for Bound2f { + fn from(b: &Bound2i) -> Self { + Self { + min: Vector2f::from(b.min), + max: Vector2f::from(b.max), + } + } +} + +impl From<&Bound2f> for Bound2i { + fn from(b: &Bound2f) -> Self { + Self { + min: Vector2i::from(b.min), + max: Vector2i::from(b.max), + } + } +} + +pub fn intersect(a: &Bound2, b: &Bound2) -> Bound2 { + Bound2::new( + &Vector2::from_xy(max(a.min.x, b.min.x), max(a.min.y, b.min.y)), + &Vector2::from_xy(min(a.max.x, b.max.x), min(a.max.y, b.max.y)), + ) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn create_test() -> Bound2 { + Bound2::new( + &Vector2::from_xy(1, 2), + &Vector2::from_xy(10, 3) + ) + } + + #[test] + fn area() { + let b = create_test(); + + assert!(b.area() == 9); + } +} diff --git a/src/bounding.rs b/src/bounding.rs deleted file mode 100644 index d5a3ed0..0000000 --- a/src/bounding.rs +++ /dev/null @@ -1,62 +0,0 @@ -use crate::{Number, Float}; -use crate::vector::Vector2; -use std::cmp; - -pub struct Bound2 { - pub min: Vector2, - pub max: Vector2 -} - -pub type Bound2i = Bound2; -pub type Bound2f = Bound2; - -fn min (a: T, b: T) -> T { - if b < a { - return b; - } - a -} - -fn max (a: T, b: T) -> T { - if b > a { - return b; - } - a -} - -impl Bound2 { - fn new(p0: &Vector2, p1: &Vector2) -> Bound2 { - let min = Vector2::from_xy(min(p0.x, p1.x), min(p0.y, p1.y)); - let max = Vector2::from_xy(max(p0.x, p1.x), max(p0.y, p1.y)); - - Bound2 { min, max } - } - - fn diagonal(&self) -> Vector2 { - self.max - self.min - } - - fn area(&self) -> T { - let diag = self.diagonal(); - return diag.x * diag.y; - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn create_test() -> Bound2 { - Bound2::new( - &Vector2::from_xy(1, 2), - &Vector2::from_xy(10, 3) - ) - } - - #[test] - fn area() { - let b = create_test(); - - assert!(b.area() == 9); - } -} diff --git a/src/camera/film.rs b/src/camera/film.rs index c4a65ce..e31b760 100644 --- a/src/camera/film.rs +++ b/src/camera/film.rs @@ -1,6 +1,7 @@ use crate::vector::{Vector2, Vector2f}; use crate::Float; -use crate::bounding::Bound2i; +use crate::bound; +use bound::{Bound2i, Bound2f}; use super::filter::Filter; #[derive(Clone)] @@ -12,8 +13,7 @@ pub struct Film<'a> { pub resolution: Vector2, pixels: Vec, - filter: &'a dyn Filter, - filter_radius: Vector2f, + filter: &'a Filter, } pub struct FilmTile { @@ -27,19 +27,23 @@ impl Pixel { } impl Film<'_> { - fn new(resolution: Vector2, filter: & dyn Filter) -> Film { + fn new(resolution: Vector2, filter: & Filter) -> Film { let area = resolution.x * resolution.y; Film { resolution, pixels: vec![Pixel::new(); area], filter, - filter_radius: filter.radius() } } fn get_tile(bound: &Bound2i) { // Used to calculate descrete coordinates into continues let halfpixel = Vector2f::from_xy(0.5, 0.5); + let fbound = Bound2f::from(bound); + + + + //let tilebound = bound::intersect(bound, } fn splat(&mut self, point: &Vector2, pixel: &Pixel) { diff --git a/src/camera/filter/mod.rs b/src/camera/filter/mod.rs index 93c6fc5..bfa17bb 100644 --- a/src/camera/filter/mod.rs +++ b/src/camera/filter/mod.rs @@ -1,22 +1,32 @@ use crate::vector::Vector2f; use crate::Float; -pub trait Filter { +trait Eval { fn eval(&self, point: &Vector2f) -> Float; - fn radius(&self) -> Vector2f; } -pub struct BoxFilter { - radius: Vector2f, +pub struct Filter { + eval: Box, + pub radius: Vector2f, } +struct BoxFilter {} + // The same a no filter, and can give aliasing in final image -impl Filter for BoxFilter { +impl Eval for BoxFilter { fn eval(&self, _: &Vector2f) -> Float { 1.0 } +} + +impl Eval for Filter { + fn eval(&self, point: &Vector2f) -> Float { + self.eval.eval(point) + } +} - fn radius(&self) -> Vector2f { - self.radius +impl Filter { + fn new_box(radius: &Vector2f) -> Filter { + Filter { radius: radius.clone(), eval: Box::new(BoxFilter {}) } } } diff --git a/src/lib.rs b/src/lib.rs index 1d43855..7066a80 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ mod vector; -mod bounding; +mod bound; mod camera; mod spectrum; diff --git a/src/vector.rs b/src/vector.rs index 9b89168..ff443f5 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -30,6 +30,25 @@ impl Sub for Vector2 { } } +impl From for Vector2f { + fn from(v: Vector2i) -> Self { + Self { + x: v.x as Float, + y: v.y as Float, + } + } +} + +impl From for Vector2i { + fn from(v: Vector2f) -> Self { + Self { + x: v.x as i32, + y: v.y as i32, + } + } +} + + #[cfg(test)] mod tests { use super::*; -- cgit v1.2.3