Reimplement dot + cross
This commit is contained in:
parent
000004404e
commit
0000045030
4 changed files with 62 additions and 12 deletions
|
@ -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 = {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -24,6 +24,21 @@ where
|
|||
.map(|i| i.into_inner())
|
||||
}
|
||||
|
||||
/// Dot-product between two 3D vectors.
|
||||
#[inline]
|
||||
pub fn dot(a: Vector3<f64>, b: Vector3<f64>) -> 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<f64>, b: Vector3<f64>) -> Vector3<f64> {
|
||||
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}");
|
||||
|
|
34
participation/2023-02-15.py
Normal file
34
participation/2023-02-15.py
Normal file
|
@ -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)
|
Loading…
Reference in a new issue