rtc/src/tuple/mod.rs

160 lines
2.4 KiB
Rust

mod tests;
use std::ops::{Add, Div, Mul, Neg, Sub};
use crate::float::{self, Float};
#[derive(Debug)]
pub struct Tuple {
x: Float,
y: Float,
z: Float,
w: Float,
}
pub fn tuple(x: Float, y: Float, z: Float, w: Float) -> Tuple {
Tuple { x, y, z, w }
}
pub fn point(x: Float, y: Float, z: Float) -> Tuple {
tuple(x, y, z, 1.0)
}
pub fn vector(x: Float, y: Float, z: Float) -> Tuple {
tuple(x, y, z, 0.0)
}
pub fn dot(a: Tuple, b: Tuple) -> Float {
a.x * b.x +
a.y * b.y +
a.z * b.z +
a.w * b.w
}
pub fn cross(a: &Tuple, b: &Tuple) -> Tuple {
vector(
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x,
)
}
impl Tuple {
pub fn magnitude(&self) -> Float {
Float::sqrt(self.x.powf(2.0) + self.y.powf(2.0) + self.z.powf(2.0) + self.w.powf(2.0))
}
pub fn normalise(&self) -> Self {
self / self.magnitude()
}
}
impl PartialEq for Tuple {
fn eq(&self, other: &Self) -> bool {
float::eq(self.x, other.x)
&& float::eq(self.y, other.y)
&& float::eq(self.z, other.z)
&& float::eq(self.w, other.w)
}
}
impl Add for &Tuple {
type Output = Tuple;
fn add(self, other: &Tuple) -> Tuple {
tuple(
self.x + other.x,
self.y + other.y,
self.z + other.z,
self.w + other.w,
)
}
}
impl Add for Tuple {
type Output = Tuple;
fn add(self, other: Tuple) -> Tuple {
&self + &other
}
}
impl Sub for &Tuple {
type Output = Tuple;
fn sub(self, other: &Tuple) -> Tuple {
tuple(
self.x - other.x,
self.y - other.y,
self.z - other.z,
self.w - other.w,
)
}
}
impl Sub for Tuple {
type Output = Tuple;
fn sub(self, other: Tuple) -> Tuple {
&self - &other
}
}
impl Neg for &Tuple {
type Output = Tuple;
fn neg(self) -> Tuple {
tuple(-self.x, -self.y, -self.z, -self.w)
}
}
impl Neg for Tuple {
type Output = Tuple;
fn neg(self) -> Tuple {
-&self
}
}
impl Mul<Float> for &Tuple {
type Output = Tuple;
fn mul(self, scalar: Float) -> Tuple {
tuple(
self.x * scalar,
self.y * scalar,
self.z * scalar,
self.w * scalar,
)
}
}
impl Mul<Float> for Tuple {
type Output = Tuple;
fn mul(self, scalar: Float) -> Tuple {
&self * scalar
}
}
impl Div<Float> for &Tuple {
type Output = Tuple;
fn div(self, scalar: Float) -> Tuple {
tuple(
self.x / scalar,
self.y / scalar,
self.z / scalar,
self.w / scalar,
)
}
}
impl Div<Float> for Tuple {
type Output = Tuple;
fn div(self, scalar: Float) -> Tuple {
&self / scalar
}
}