Filter out t < 0
This commit is contained in:
parent
cfed4b9c68
commit
6267dce475
4 changed files with 30 additions and 10 deletions
|
@ -3,7 +3,7 @@ extern crate anyhow;
|
||||||
|
|
||||||
mod image;
|
mod image;
|
||||||
mod input_file;
|
mod input_file;
|
||||||
mod math;
|
mod utils;
|
||||||
mod ray;
|
mod ray;
|
||||||
mod scene;
|
mod scene;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use nalgebra::Vector3;
|
use nalgebra::Vector3;
|
||||||
use ordered_float::NotNan;
|
|
||||||
|
|
||||||
use crate::{math::compute_rotation_matrix, ray::Ray};
|
use crate::ray::Ray;
|
||||||
|
use crate::utils::{compute_rotation_matrix, min_f64};
|
||||||
|
|
||||||
use super::data::ObjectKind;
|
use super::data::ObjectKind;
|
||||||
|
|
||||||
|
@ -113,12 +113,14 @@ impl ObjectKind for Cylinder {
|
||||||
ray_point.x.powi(2) + ray_point.y.powi(2) <= self.radius.powi(2)
|
ray_point.x.powi(2) + ray_point.y.powi(2) <= self.radius.powi(2)
|
||||||
});
|
});
|
||||||
|
|
||||||
let solutions = side_solutions.into_iter().chain(end_solutions.into_iter());
|
let solutions = side_solutions
|
||||||
|
.into_iter()
|
||||||
|
.chain(end_solutions.into_iter())
|
||||||
|
// Remove any t < 0, since that means it's behind the viewer and we
|
||||||
|
// can't see it.
|
||||||
|
.filter(|t| *t >= 0.0);
|
||||||
|
|
||||||
// Return the minimum solution
|
// Return the minimum solution
|
||||||
solutions
|
min_f64(solutions)
|
||||||
.filter_map(|t| NotNan::new(t).ok())
|
|
||||||
.min()
|
|
||||||
.map(|t| t.into_inner())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use nalgebra::Vector3;
|
use nalgebra::Vector3;
|
||||||
|
|
||||||
use crate::ray::Ray;
|
use crate::{ray::Ray, utils::min_f64};
|
||||||
|
|
||||||
use super::data::ObjectKind;
|
use super::data::ObjectKind;
|
||||||
|
|
||||||
|
@ -40,7 +40,14 @@ impl ObjectKind for Sphere {
|
||||||
let solution_1 = (-b + discriminant.sqrt()) / (2.0 * a);
|
let solution_1 = (-b + discriminant.sqrt()) / (2.0 * a);
|
||||||
let solution_2 = (-b - discriminant.sqrt()) / (2.0 * a);
|
let solution_2 = (-b - discriminant.sqrt()) / (2.0 * a);
|
||||||
|
|
||||||
Some(solution_1.min(solution_2))
|
let solutions = [solution_1, solution_2]
|
||||||
|
.into_iter()
|
||||||
|
// Remove any t < 0, since that means it's behind the viewer and we
|
||||||
|
// can't see it.
|
||||||
|
.filter(|t| *t >= 0.0);
|
||||||
|
|
||||||
|
// Return the minimum solution
|
||||||
|
min_f64(solutions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Probably hit some NaN or Infinity value due to faulty inputs...
|
// Probably hit some NaN or Infinity value due to faulty inputs...
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
use nalgebra::{Matrix3, Vector3};
|
use nalgebra::{Matrix3, Vector3};
|
||||||
|
use ordered_float::NotNan;
|
||||||
|
|
||||||
|
/// Finds the minimum of an iterator of f64s, ignoring any NaN values
|
||||||
|
pub fn min_f64<I>(i: I) -> Option<f64>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = f64>,
|
||||||
|
{
|
||||||
|
i.filter_map(|i| NotNan::new(i).ok())
|
||||||
|
.min()
|
||||||
|
.map(|i| i.into_inner())
|
||||||
|
}
|
||||||
|
|
||||||
/// Calculate the rotation matrix between the 2 given vectors
|
/// Calculate the rotation matrix between the 2 given vectors
|
||||||
/// Based on the method here: https://math.stackexchange.com/a/897677
|
/// Based on the method here: https://math.stackexchange.com/a/897677
|
Loading…
Reference in a new issue