Change the Tuple to a tuple without field names
This helps out when I go to use the same data structure as the backing for colors.
This commit is contained in:
parent
2a38ca38e1
commit
d0a8be63e9
|
@ -29,15 +29,15 @@ fn main() {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut p = start;
|
let mut p = start;
|
||||||
while p.position.y > 0. {
|
while p.position.y() > 0. {
|
||||||
p = tick(&e, &p);
|
p = tick(&e, &p);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"distance travelled: [{}] {} {} {}",
|
"distance travelled: [{}] {} {} {}",
|
||||||
(p.position - start.position).magnitude(),
|
(p.position - start.position).magnitude(),
|
||||||
p.position.x,
|
p.position.x(),
|
||||||
p.position.y,
|
p.position.y(),
|
||||||
p.position.z
|
p.position.z(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,52 +26,16 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_two_tuples() {
|
fn add_two_tuples() {
|
||||||
let a = Tuple {
|
let a = Tuple(3., -2., 5., 1.);
|
||||||
x: 3.,
|
let b = Tuple(-2., 3., 1., 0.);
|
||||||
y: -2.,
|
assert_eq!(a + b, Tuple(1., 1., 6., 1.));
|
||||||
z: 5.,
|
|
||||||
w: 1.,
|
|
||||||
};
|
|
||||||
let b = Tuple {
|
|
||||||
x: -2.,
|
|
||||||
y: 3.,
|
|
||||||
z: 1.,
|
|
||||||
w: 0.,
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
a + b,
|
|
||||||
Tuple {
|
|
||||||
x: 1.,
|
|
||||||
y: 1.,
|
|
||||||
z: 6.,
|
|
||||||
w: 1.
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn subtracts_two_tuples() {
|
fn subtracts_two_tuples() {
|
||||||
let a = Tuple {
|
let a = Tuple(3., 2., 1., 1.);
|
||||||
x: 3.,
|
let b = Tuple(5., 6., 7., 1.);
|
||||||
y: 2.,
|
assert_eq!(a - b, Tuple(-2., -4., -6., 0.));
|
||||||
z: 1.,
|
|
||||||
w: 1.,
|
|
||||||
};
|
|
||||||
let b = Tuple {
|
|
||||||
x: 5.,
|
|
||||||
y: 6.,
|
|
||||||
z: 7.,
|
|
||||||
w: 1.,
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
a - b,
|
|
||||||
Tuple {
|
|
||||||
x: -2.,
|
|
||||||
y: -4.,
|
|
||||||
z: -6.,
|
|
||||||
w: 0.
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -104,56 +68,17 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_negates_primitives() {
|
fn it_negates_primitives() {
|
||||||
assert_eq!(
|
assert_eq!(-Tuple(1., 2., 3., 4.), Tuple(-1., -2., -3., -4.),);
|
||||||
-Tuple {
|
|
||||||
x: 1.,
|
|
||||||
y: 2.,
|
|
||||||
z: 3.,
|
|
||||||
w: 4.
|
|
||||||
},
|
|
||||||
Tuple {
|
|
||||||
x: -1.,
|
|
||||||
y: -2.,
|
|
||||||
z: -3.,
|
|
||||||
w: -4.
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn multiply_tuple_by_scalar() {
|
fn multiply_tuple_by_scalar() {
|
||||||
assert_eq!(
|
assert_eq!(Tuple(1., -2., 3., -4.) * 3.5, Tuple(3.5, -7., 10.5, -14.));
|
||||||
Tuple {
|
|
||||||
x: 1.,
|
|
||||||
y: -2.,
|
|
||||||
z: 3.,
|
|
||||||
w: -4.
|
|
||||||
} * 3.5,
|
|
||||||
Tuple {
|
|
||||||
x: 3.5,
|
|
||||||
y: -7.,
|
|
||||||
z: 10.5,
|
|
||||||
w: -14.
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn divide_tuple_by_scalar() {
|
fn divide_tuple_by_scalar() {
|
||||||
assert_eq!(
|
assert_eq!(Tuple(1., -2., 3., -4.) / 2., Tuple(0.5, -1., 1.5, -2.));
|
||||||
Tuple {
|
|
||||||
x: 1.,
|
|
||||||
y: -2.,
|
|
||||||
z: 3.,
|
|
||||||
w: -4.
|
|
||||||
} / 2.,
|
|
||||||
Tuple {
|
|
||||||
x: 0.5,
|
|
||||||
y: -1.,
|
|
||||||
z: 1.5,
|
|
||||||
w: -2.
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -5,7 +5,22 @@ pub struct Point(Tuple);
|
||||||
|
|
||||||
impl Point {
|
impl Point {
|
||||||
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
||||||
Self(Tuple { x, y, z, w: 1.0 })
|
Self(Tuple(x, y, z, 1.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn x(&self) -> f64 {
|
||||||
|
self.0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn y(&self) -> f64 {
|
||||||
|
self.0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn z(&self) -> f64 {
|
||||||
|
self.0.2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +32,7 @@ impl Default for Point {
|
||||||
|
|
||||||
impl From<Tuple> for Point {
|
impl From<Tuple> for Point {
|
||||||
fn from(tuple: Tuple) -> Self {
|
fn from(tuple: Tuple) -> Self {
|
||||||
assert_eq!(tuple.w, 1.0);
|
assert_eq!(tuple.3, 1.0);
|
||||||
Self(tuple)
|
Self(tuple)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +69,7 @@ impl std::ops::Neg for Point {
|
||||||
type Output = Point;
|
type Output = Point;
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
let mut t = -self.0;
|
let mut t = -self.0;
|
||||||
t.w = 1.;
|
t.3 = 1.;
|
||||||
Point::from(t)
|
Point::from(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +1,37 @@
|
||||||
use crate::types::eq_f64;
|
use crate::types::eq_f64;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Tuple {
|
pub struct Tuple(
|
||||||
pub x: f64,
|
pub f64, // x or red
|
||||||
pub y: f64,
|
pub f64, // y or green
|
||||||
pub z: f64,
|
pub f64, // z or blue
|
||||||
pub w: f64, // Used for very low-level math. w = 1.0 indicates a point, w = 0.0 indicates a vector.
|
pub f64, // w, the flag which
|
||||||
// Theoretically the type system should make this redundant, so operations on points
|
// indicates point vs vec, or alpha
|
||||||
// and vectors can always assert the correct value.
|
);
|
||||||
}
|
|
||||||
|
|
||||||
impl Tuple {
|
impl Tuple {
|
||||||
pub fn dot(&self, r: &Tuple) -> f64 {
|
pub fn dot(&self, r: &Tuple) -> f64 {
|
||||||
self.x * r.x + self.y * r.y + self.z * r.z + self.w * r.w
|
self.0 * r.0 + self.1 * r.1 + self.2 * r.2 + self.3 * r.3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Tuple {
|
impl PartialEq for Tuple {
|
||||||
fn eq(&self, r: &Tuple) -> bool {
|
fn eq(&self, r: &Tuple) -> bool {
|
||||||
eq_f64(self.x, r.x) && eq_f64(self.y, r.y) && eq_f64(self.z, r.z) && eq_f64(self.w, r.w)
|
eq_f64(self.0, r.0) && eq_f64(self.1, r.1) && eq_f64(self.2, r.2) && eq_f64(self.3, r.3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Add for Tuple {
|
impl std::ops::Add for Tuple {
|
||||||
type Output = Tuple;
|
type Output = Tuple;
|
||||||
fn add(self, r: Tuple) -> Self::Output {
|
fn add(self, r: Tuple) -> Self::Output {
|
||||||
return Self::Output {
|
Tuple(self.0 + r.0, self.1 + r.1, self.2 + r.2, self.3 + r.3)
|
||||||
x: self.x + r.x,
|
|
||||||
y: self.y + r.y,
|
|
||||||
z: self.z + r.z,
|
|
||||||
w: self.w + r.w,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Sub for Tuple {
|
impl std::ops::Sub for Tuple {
|
||||||
type Output = Tuple;
|
type Output = Tuple;
|
||||||
fn sub(self, r: Tuple) -> Self::Output {
|
fn sub(self, r: Tuple) -> Self::Output {
|
||||||
return Self::Output {
|
Tuple(self.0 - r.0, self.1 - r.1, self.2 - r.2, self.3 - r.3)
|
||||||
x: self.x - r.x,
|
|
||||||
y: self.y - r.y,
|
|
||||||
z: self.z - r.z,
|
|
||||||
w: self.w - r.w,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,10 +39,10 @@ impl std::ops::Neg for Tuple {
|
||||||
type Output = Tuple;
|
type Output = Tuple;
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
return Self::Output {
|
return Self::Output {
|
||||||
x: -self.x,
|
0: -self.0,
|
||||||
y: -self.y,
|
1: -self.1,
|
||||||
z: -self.z,
|
2: -self.2,
|
||||||
w: -self.w,
|
3: -self.3,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,23 +50,23 @@ impl std::ops::Neg for Tuple {
|
||||||
impl std::ops::Mul<f64> for Tuple {
|
impl std::ops::Mul<f64> for Tuple {
|
||||||
type Output = Tuple;
|
type Output = Tuple;
|
||||||
fn mul(self, scalar: f64) -> Self::Output {
|
fn mul(self, scalar: f64) -> Self::Output {
|
||||||
return Self::Output {
|
Tuple(
|
||||||
x: self.x * scalar,
|
self.0 * scalar,
|
||||||
y: self.y * scalar,
|
self.1 * scalar,
|
||||||
z: self.z * scalar,
|
self.2 * scalar,
|
||||||
w: self.w * scalar,
|
self.3 * scalar,
|
||||||
};
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Div<f64> for Tuple {
|
impl std::ops::Div<f64> for Tuple {
|
||||||
type Output = Tuple;
|
type Output = Tuple;
|
||||||
fn div(self, scalar: f64) -> Self::Output {
|
fn div(self, scalar: f64) -> Self::Output {
|
||||||
return Self::Output {
|
Tuple(
|
||||||
x: self.x / scalar,
|
self.0 / scalar,
|
||||||
y: self.y / scalar,
|
self.1 / scalar,
|
||||||
z: self.z / scalar,
|
self.2 / scalar,
|
||||||
w: self.w / scalar,
|
self.3 / scalar,
|
||||||
};
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,31 @@ pub struct Vector(Tuple);
|
||||||
|
|
||||||
impl Vector {
|
impl Vector {
|
||||||
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
pub fn new(x: f64, y: f64, z: f64) -> Self {
|
||||||
Self(Tuple { x, y, z, w: 0.0 })
|
Self(Tuple(x, y, z, 0.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn x(&self) -> f64 {
|
||||||
|
self.0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn y(&self) -> f64 {
|
||||||
|
self.0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn z(&self) -> f64 {
|
||||||
|
self.0.2
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn magnitude(&self) -> f64 {
|
pub fn magnitude(&self) -> f64 {
|
||||||
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
|
(self.x() * self.x() + self.y() * self.y() + self.z() * self.z()).sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn normalize(&self) -> Self {
|
pub fn normalize(&self) -> Self {
|
||||||
let mag = self.magnitude();
|
let mag = self.magnitude();
|
||||||
Self::new(self.x / mag, self.y / mag, self.z / mag)
|
Self::new(self.x() / mag, self.y() / mag, self.z() / mag)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dot(&self, r: &Vector) -> f64 {
|
pub fn dot(&self, r: &Vector) -> f64 {
|
||||||
|
@ -22,9 +37,9 @@ impl Vector {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cross(&self, r: &Vector) -> Self {
|
pub fn cross(&self, r: &Vector) -> Self {
|
||||||
let x = self.y * r.z - self.z * r.y;
|
let x = self.y() * r.z() - self.z() * r.y();
|
||||||
let y = self.z * r.x - self.x * r.z;
|
let y = self.z() * r.x() - self.x() * r.z();
|
||||||
let z = self.x * r.y - self.y * r.x;
|
let z = self.x() * r.y() - self.y() * r.x();
|
||||||
Self::new(x, y, z)
|
Self::new(x, y, z)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +52,7 @@ impl Default for Vector {
|
||||||
|
|
||||||
impl From<Tuple> for Vector {
|
impl From<Tuple> for Vector {
|
||||||
fn from(tuple: Tuple) -> Self {
|
fn from(tuple: Tuple) -> Self {
|
||||||
assert_eq!(tuple.w, 0.0);
|
assert_eq!(tuple.3, 0.0);
|
||||||
Self(tuple)
|
Self(tuple)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +82,7 @@ impl std::ops::Neg for Vector {
|
||||||
type Output = Vector;
|
type Output = Vector;
|
||||||
fn neg(self) -> Self::Output {
|
fn neg(self) -> Self::Output {
|
||||||
let mut t = -self.0;
|
let mut t = -self.0;
|
||||||
t.w = 0.;
|
t.0 = 0.;
|
||||||
Vector::from(t)
|
Vector::from(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue