From 0000045030d3d1d470050c2834537f3629a7a051 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Wed, 15 Feb 2023 19:22:17 -0600 Subject: [PATCH] Reimplement dot + cross --- assignment-1b/src/scene/data.rs | 5 ++-- assignment-1b/src/scene/illumination.rs | 7 +++-- assignment-1b/src/utils.rs | 28 +++++++++++++++----- participation/2023-02-15.py | 34 +++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 participation/2023-02-15.py diff --git a/assignment-1b/src/scene/data.rs b/assignment-1b/src/scene/data.rs index 66fd149..2ae887f 100644 --- a/assignment-1b/src/scene/data.rs +++ b/assignment-1b/src/scene/data.rs @@ -5,6 +5,7 @@ use nalgebra::Vector3; use crate::image::Color; use crate::ray::Ray; +use crate::utils::cross; use super::cylinder::Cylinder; use super::illumination::IntersectionContext; @@ -134,8 +135,8 @@ impl Scene { /// Determine the boundaries of the viewing window in world coordinates pub fn compute_viewing_window(&self, distance: f64) -> Rect { // Compute viewing directions - let u = self.view_dir.cross(&self.up_dir).normalize(); - let v = u.cross(&self.view_dir).normalize(); + let u = cross(self.view_dir, self.up_dir).normalize(); + let v = cross(u, self.view_dir).normalize(); // Compute dimensions of viewing window based on field of view let viewing_width = { diff --git a/assignment-1b/src/scene/illumination.rs b/assignment-1b/src/scene/illumination.rs index ba1dd00..424fee9 100644 --- a/assignment-1b/src/scene/illumination.rs +++ b/assignment-1b/src/scene/illumination.rs @@ -8,7 +8,7 @@ use rayon::prelude::{ ParallelIterator, }; -use crate::{image::Color, ray::Ray}; +use crate::{image::Color, ray::Ray, utils::dot}; use super::{ data::{DepthCueing, Light, LightKind, Object}, @@ -53,12 +53,11 @@ impl Scene { let diffuse_component = material.k_d * material.diffuse_color - * normal.dot(&light_direction).max(0.0); + * dot(normal, light_direction).max(0.0); let specular_component = material.k_s * material.specular_color - * normal - .dot(&halfway_direction) + * dot(normal, halfway_direction) .max(0.0) .powf(material.exponent); diff --git a/assignment-1b/src/utils.rs b/assignment-1b/src/utils.rs index 21f183b..c2ab9f1 100644 --- a/assignment-1b/src/utils.rs +++ b/assignment-1b/src/utils.rs @@ -24,6 +24,21 @@ where .map(|i| i.into_inner()) } +/// Dot-product between two 3D vectors. +#[inline] +pub fn dot(a: Vector3, b: Vector3) -> f64 { + a.x * b.x + a.y * b.y + a.z * b.z +} + +/// Cross-product between two 3D vectors. +#[inline] +pub fn cross(a: Vector3, b: Vector3) -> Vector3 { + let x = a.y * b.z - a.z * b.y; + let y = a.z * b.x - a.x * b.z; + let z = a.x * b.y - a.y * b.x; + Vector3::new(x, y, z) +} + /// Calculate the rotation matrix between the 2 given vectors /// /// Based on the method given [here][1]. @@ -39,15 +54,15 @@ pub fn compute_rotation_matrix( return Ok(Matrix3::identity()); } - let cos_t = a.dot(&b); - let sin_t = a.cross(&b).norm(); + let cos_t = dot(a, b); + let sin_t = cross(a, b).norm(); let g = Matrix3::new(cos_t, -sin_t, 0.0, sin_t, cos_t, 0.0, 0.0, 0.0, 1.0); // New basis vectors let u = a; - let v = (b - a.dot(&b) * a).normalize(); - let w = b.cross(&a); + let v = (b - cos_t * a).normalize(); + let w = cross(b, a); // Not sure if this is required to be invertible? let f_inverse = Matrix3::from_columns(&[u, v, w]); @@ -56,8 +71,9 @@ pub fn compute_rotation_matrix( None => { // So I ran into this case trying to compute the rotation matrix where one // of the vector endpoints was (0, 0, 0). I'm pretty sure this case makes - // no sense in reality, so going to just error out here and screw - // recovering. + // no sense in reality, which means if I ever encounter this case, I + // probably made a mistake somewhere before. So going to just error + // out here and screw recovering. // // println!("Failed to compute inverse matrix."); // println!("- Initial: a = {a}, b = {b}"); diff --git a/participation/2023-02-15.py b/participation/2023-02-15.py new file mode 100644 index 000000000..7005134 --- /dev/null +++ b/participation/2023-02-15.py @@ -0,0 +1,34 @@ +class Point: + def __init__(self, x, y, z): + self.x = x + self.y = y + self.z = z + + def __sub__(self, o): + return Point(self.x - o.x, self.y - o.y, self.z - o.z) + + def __str__(self): + return f"({self.x}, {self.y}, {self.z})" + + def cross(self, o): + x = self.y * o.z - self.z * o.y + y = self.z * o.x - self.x * o.z + z = self.x * o.y - self.y * o.x + return Point(x, y, z) + +p0 = Point(1, 1, 0) +p1 = Point(0, 1, 1) +p2 = Point(1, 0, 1) + +e1 = p1 - p0 +print(e1) + +e2 = p2 - p0 +print(e2) + +n = e1.cross(e2) +print(n) + +# Find A, B, C and D +D = -(n.x * p0.x + n.y * p0.y + n.z * p0.z) +print(n.x, n.y, n.z, D)