Filter out t < 0

This commit is contained in:
Michael Zhang 2023-02-02 19:06:04 -06:00
parent cfed4b9c68
commit 6267dce475
4 changed files with 30 additions and 10 deletions

View file

@ -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;

View file

@ -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())
} }
} }

View file

@ -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...

View file

@ -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