Cross product
This commit is contained in:
parent
0000005024
commit
0000006041
7 changed files with 204 additions and 45 deletions
92
assignment-1/Cargo.lock
generated
92
assignment-1/Cargo.lock
generated
|
@ -14,8 +14,15 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -135,6 +142,85 @@ version = "0.1.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||
|
||||
[[package]]
|
||||
name = "num"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-complex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-bigint",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.17.0"
|
||||
|
@ -203,6 +289,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
|
|
|
@ -8,3 +8,4 @@ edition = "2021"
|
|||
[dependencies]
|
||||
anyhow = "1.0.68"
|
||||
clap = { version = "4.1.4", features = ["derive"] }
|
||||
num = { version = "0.4.0", features = ["serde"] }
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
mod input_file;
|
||||
mod ray;
|
||||
mod scene_data;
|
||||
mod view;
|
||||
mod vec3;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
use crate::scene_data::{Sphere, Vec3};
|
||||
use crate::scene_data::Sphere;
|
||||
use crate::vec3::Vec3;
|
||||
|
||||
/// A normalized Ray
|
||||
/// A normalized parametric Ray of the form (origin + direction * time)
|
||||
///
|
||||
/// That means at any time t: f64, the point represented by origin + direction * time occurs on the
|
||||
/// ray.
|
||||
pub struct Ray {
|
||||
origin: Vec3,
|
||||
direction: Vec3,
|
||||
}
|
||||
|
||||
impl Ray {
|
||||
/// Evaluate the ray at a certain point in time, yielding a point
|
||||
pub fn eval(&self, time: f64) -> Vec3 {
|
||||
self.origin + self.direction * time
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a ray and a sphere, returns the first point at which this ray intersects the sphere.
|
||||
/// Given a ray and a sphere, returns the first time at which this ray intersects the sphere.
|
||||
///
|
||||
/// If there is no intersection point, returns None.
|
||||
pub fn ray_intersection_time(ray: &Ray, sphere: &Sphere) -> Option<f64> {
|
||||
|
@ -43,13 +48,16 @@ pub fn ray_intersection_time(ray: &Ray, sphere: &Sphere) -> Option<f64> {
|
|||
|
||||
return Some(solution_1.min(solution_2));
|
||||
}
|
||||
|
||||
// Probably hit some NaN or Infinity value due to faulty inputs...
|
||||
_ => unreachable!("Invalid determinant value: {discriminant}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::scene_data::{Sphere, Vec3};
|
||||
use crate::scene_data::Sphere;
|
||||
use crate::vec3::Vec3;
|
||||
|
||||
use super::{ray_intersection_time, Ray};
|
||||
|
||||
|
@ -64,7 +72,24 @@ mod tests {
|
|||
radius: 4.0,
|
||||
};
|
||||
|
||||
let t = ray_intersection_time(&ray, &sphere).unwrap();
|
||||
assert_eq!(ray.eval(t), Vec3::new(0.0, 0.0, -6.0));
|
||||
let point = ray_intersection_time(&ray, &sphere).map(|t| ray.eval(t));
|
||||
|
||||
// the intersection point in this case is (0, 0, –6)
|
||||
assert_eq!(point, Some(Vec3::new(0.0, 0.0, -6.0)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn practice_problem_slide_158() {
|
||||
let ray = Ray {
|
||||
origin: Vec3::new(0.0, 0.0, 0.0),
|
||||
direction: Vec3::new(0.0, 0.5, -1.0),
|
||||
};
|
||||
let sphere = Sphere {
|
||||
center: Vec3::new(0.0, 0.0, -10.0),
|
||||
radius: 4.0,
|
||||
};
|
||||
|
||||
// oops! In this case, the ray does not intersect the sphere.
|
||||
assert_eq!(ray_intersection_time(&ray, &sphere), None);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +1,4 @@
|
|||
use std::ops::{Add, Mul};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Vec3<T = f64> {
|
||||
pub x: T,
|
||||
pub y: T,
|
||||
pub z: T,
|
||||
}
|
||||
|
||||
impl<T> Vec3<T> {
|
||||
pub fn new(x: T, y: T, z: T) -> Self {
|
||||
Vec3 { x, y, z }
|
||||
}
|
||||
}
|
||||
|
||||
/// Vector addition
|
||||
impl<T> Add<Vec3<T>> for Vec3<T>
|
||||
where
|
||||
T: Add<T>,
|
||||
{
|
||||
type Output = Vec3<T::Output>;
|
||||
|
||||
fn add(self, rhs: Vec3<T>) -> Self::Output {
|
||||
Vec3::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
|
||||
}
|
||||
}
|
||||
|
||||
/// Scalar multiplication
|
||||
impl<T, U> Mul<U> for Vec3<T>
|
||||
where
|
||||
T: Mul<U, Output = U>,
|
||||
U: Copy,
|
||||
{
|
||||
type Output = Vec3<U>;
|
||||
|
||||
fn mul(self, rhs: U) -> Self::Output {
|
||||
Vec3::new(self.x * rhs, self.y * rhs, self.z * rhs)
|
||||
}
|
||||
}
|
||||
use crate::vec3::Vec3;
|
||||
|
||||
pub struct Sphere {
|
||||
pub center: Vec3,
|
||||
|
|
65
assignment-1/src/vec3.rs
Normal file
65
assignment-1/src/vec3.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use std::ops::{Add, Mul};
|
||||
|
||||
use num::Float;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Vec3<T = f64> {
|
||||
pub x: T,
|
||||
pub y: T,
|
||||
pub z: T,
|
||||
}
|
||||
|
||||
impl<T> Vec3<T> {
|
||||
pub fn new(x: T, y: T, z: T) -> Self {
|
||||
Vec3 { x, y, z }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Float> Vec3<T> {
|
||||
pub fn cross(u: Self, v: Self) -> Self {
|
||||
Vec3::new(
|
||||
u.y * v.z - u.z * v.y,
|
||||
u.z * v.x - u.x * v.z,
|
||||
u.x * v.y - u.y * v.x,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Vector addition
|
||||
impl<T> Add<Vec3<T>> for Vec3<T>
|
||||
where
|
||||
T: Add<T>,
|
||||
{
|
||||
type Output = Vec3<T::Output>;
|
||||
|
||||
fn add(self, rhs: Vec3<T>) -> Self::Output {
|
||||
Vec3::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
|
||||
}
|
||||
}
|
||||
|
||||
/// Scalar multiplication
|
||||
impl<T, U> Mul<U> for Vec3<T>
|
||||
where
|
||||
T: Mul<U, Output = U>,
|
||||
U: Copy,
|
||||
{
|
||||
type Output = Vec3<U>;
|
||||
|
||||
fn mul(self, rhs: U) -> Self::Output {
|
||||
Vec3::new(self.x * rhs, self.y * rhs, self.z * rhs)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Vec3;
|
||||
|
||||
#[test]
|
||||
fn test_cross() {
|
||||
let u = Vec3::new(1.0, 0.0, 0.0);
|
||||
let v = Vec3::new(0.0, 1.0, 0.0);
|
||||
|
||||
assert_eq!(Vec3::cross(u, v), Vec3::new(0.0, 0.0, 1.0));
|
||||
assert_eq!(Vec3::cross(v, u), Vec3::new(0.0, 0.0, -1.0));
|
||||
}
|
||||
}
|
12
assignment-1/src/view.rs
Normal file
12
assignment-1/src/view.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
use crate::vec3::Vec3;
|
||||
|
||||
pub struct Rect {
|
||||
pub upper_left: Vec3,
|
||||
pub upper_right: Vec3,
|
||||
pub lower_left: Vec3,
|
||||
pub lower_right: Vec3,
|
||||
}
|
||||
|
||||
pub fn compute_viewing_rect() {
|
||||
|
||||
}
|
Loading…
Reference in a new issue