160 lines
2.4 KiB
Rust
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
|
|
}
|
|
}
|