use na::{DefaultAllocator, RealField}; use crate::aliases::{TVec, TVec3}; use crate::traits::{Alloc, Dimension, Number}; /// The cross product of two vectors. pub fn cross(x: &TVec3, y: &TVec3) -> TVec3 { x.cross(y) } /// The distance between two points. /// /// # See also: /// /// * [`distance2`](fn.distance2.html) pub fn distance(p0: &TVec, p1: &TVec) -> N where DefaultAllocator: Alloc { (p1 - p0).norm() } /// The dot product of two vectors. pub fn dot(x: &TVec, y: &TVec) -> N where DefaultAllocator: Alloc { x.dot(y) } /// If `dot(nref, i) < 0.0`, return `n`, otherwise, return `-n`. pub fn faceforward( n: &TVec, i: &TVec, nref: &TVec, ) -> TVec where DefaultAllocator: Alloc, { if nref.dot(i) < N::zero() { n.clone() } else { -n.clone() } } /// The magnitude of a vector. /// /// A synonym for [`magnitude`](fn.magnitude.html). /// /// # See also: /// /// * [`length2`](fn.length2.html) /// * [`magnitude`](fn.magnitude.html) /// * [`magnitude2`](fn.magnitude2.html) pub fn length(x: &TVec) -> N where DefaultAllocator: Alloc { x.norm() } /// The magnitude of a vector. /// /// A wrapper around [`nalgebra::norm`](../nalgebra/fn.norm.html). /// /// # See also: /// /// * [`length`](fn.length.html) /// * [`magnitude2`](fn.magnitude2.html) /// * [`nalgebra::norm`](../nalgebra/fn.norm.html) pub fn magnitude(x: &TVec) -> N where DefaultAllocator: Alloc { x.norm() } /// Normalizes a vector. pub fn normalize(x: &TVec) -> TVec where DefaultAllocator: Alloc { x.normalize() } /// For the incident vector `i` and surface orientation `n`, returns the reflection direction : `result = i - 2.0 * dot(n, i) * n`. pub fn reflect_vec(i: &TVec, n: &TVec) -> TVec where DefaultAllocator: Alloc { let _2 = N::one() + N::one(); i - n * (n.dot(i) * _2) } /// For the incident vector `i` and surface normal `n`, and the ratio of indices of refraction `eta`, return the refraction vector. pub fn refract_vec(i: &TVec, n: &TVec, eta: N) -> TVec where DefaultAllocator: Alloc { let ni = n.dot(i); let k = N::one() - eta * eta * (N::one() - ni * ni); if k < N::zero() { TVec::<_, D>::zeros() } else { i * eta - n * (eta * dot(n, i) + k.sqrt()) } }