create structs lib, mimics tuple lib, but implements Tuple.
This allows for operator overloading. It will make it significantly easier to write code for Tuple objects.
This commit is contained in:
32
structs/Cargo.lock
generated
Normal file
32
structs/Cargo.lock
generated
Normal file
@@ -0,0 +1,32 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f2a05fd1bd10b2527e20a2cd32d8873d115b8b39fe219ee25f42a8aca6ba278"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "structs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"approx",
|
||||
]
|
||||
10
structs/Cargo.toml
Normal file
10
structs/Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "structs"
|
||||
version = "0.1.0"
|
||||
authors = ["Jon Janzen <jonjanzen@me.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
approx = "0.4"
|
||||
297
structs/src/lib.rs
Normal file
297
structs/src/lib.rs
Normal file
@@ -0,0 +1,297 @@
|
||||
#[macro_use]
|
||||
extern crate approx;
|
||||
|
||||
use std::ops;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Tuple {
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
w: f32,
|
||||
}
|
||||
|
||||
impl Tuple {
|
||||
fn new(x: f32, y: f32, z: f32, w: f32) -> Tuple {
|
||||
Tuple {
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
w,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn point(x: f32, y: f32, z: f32) -> Tuple {
|
||||
Tuple {
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
w: 1.0,
|
||||
}
|
||||
}
|
||||
|
||||
fn vector(x: f32, y: f32, z: f32) -> Tuple {
|
||||
Tuple {
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
w: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Tuple {
|
||||
fn x(&self) -> f32 {
|
||||
self.x
|
||||
}
|
||||
|
||||
fn y(&self) -> f32 {
|
||||
self.y
|
||||
}
|
||||
|
||||
fn z(&self) -> f32 {
|
||||
self.z
|
||||
}
|
||||
|
||||
fn is_point(&self) -> bool {
|
||||
self.w == 1.0
|
||||
}
|
||||
|
||||
fn is_vector(&self) -> bool {
|
||||
self.w == 0.0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl PartialEq for Tuple {
|
||||
fn eq(&self, _rhs: &Self) -> bool {
|
||||
relative_eq!(self.x, _rhs.x)
|
||||
&& relative_eq!(self.y, _rhs.y)
|
||||
&& relative_eq!(self.z, _rhs.z)
|
||||
&& relative_eq!(self.w, _rhs.w)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Add<Tuple> for Tuple {
|
||||
type Output = Tuple;
|
||||
|
||||
fn add(self, _rhs: Tuple) -> Tuple {
|
||||
Tuple::new(
|
||||
self.x + _rhs.x,
|
||||
self.y + _rhs.y,
|
||||
self.z + _rhs.z,
|
||||
self.w + _rhs.w,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Sub<Tuple> for Tuple {
|
||||
type Output = Tuple;
|
||||
|
||||
fn sub(self, _rhs: Tuple) -> Tuple {
|
||||
Tuple::new(
|
||||
self.x - _rhs.x,
|
||||
self.y - _rhs.y,
|
||||
self.z - _rhs.z,
|
||||
self.w - _rhs.w,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Neg for Tuple {
|
||||
type Output = Tuple;
|
||||
|
||||
fn neg(self) -> Tuple {
|
||||
Tuple::new(
|
||||
-self.x,
|
||||
-self.y,
|
||||
-self.z,
|
||||
-self.w,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Mul<f32> for Tuple {
|
||||
type Output = Tuple;
|
||||
|
||||
fn mul(self, _rhs: f32) -> Tuple {
|
||||
Tuple::new(
|
||||
self.x * _rhs,
|
||||
self.y * _rhs,
|
||||
self.z * _rhs,
|
||||
self.w * _rhs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Mul<Tuple> for f32 {
|
||||
type Output = Tuple;
|
||||
|
||||
fn mul(self, _rhs: Tuple) -> Tuple {
|
||||
Tuple::new(
|
||||
_rhs.x * self,
|
||||
_rhs.y * self,
|
||||
_rhs.z * self,
|
||||
_rhs.w * self,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Div<f32> for Tuple {
|
||||
type Output = Tuple;
|
||||
|
||||
fn div(self, _rhs: f32) -> Tuple {
|
||||
Tuple::new(
|
||||
self.x / _rhs,
|
||||
self.y / _rhs,
|
||||
self.z / _rhs,
|
||||
self.w / _rhs,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn get_point() {
|
||||
let tuple = Tuple::new(4.3, -4.2, 3.1, 1.0);
|
||||
|
||||
assert_relative_eq!( 4.3, tuple.x);
|
||||
assert_relative_eq!(-4.2, tuple.y());
|
||||
assert_relative_eq!( 3.1, tuple.z());
|
||||
assert_eq!(true, tuple.is_point());
|
||||
assert_eq!(false, tuple.is_vector());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_point() {
|
||||
let tuple = Tuple::point(4.3, -4.2, 3.1);
|
||||
assert_eq!(true, tuple.is_point());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_vector() {
|
||||
let tuple = Tuple::new(4.3, -4.2, 3.1, 0.0);
|
||||
|
||||
assert_relative_eq!( 4.3, tuple.x());
|
||||
assert_relative_eq!(-4.2, tuple.y());
|
||||
assert_relative_eq!( 3.1, tuple.z());
|
||||
assert_eq!(false, tuple.is_point());
|
||||
assert_eq!(true, tuple.is_vector());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_vector() {
|
||||
let vector = Tuple::vector(4.0, -4.0, 3.0);
|
||||
assert_eq!(true, vector.is_vector());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuples_equal() {
|
||||
let lhs = Tuple::point(1.0, 2.0, 3.0);
|
||||
let rhs = Tuple::point(1.0, 2.0, 3.0);
|
||||
assert_eq!(lhs, rhs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuples_relative_equal() {
|
||||
let lhs = Tuple::point(1.0000001, 2.0, 3.0);
|
||||
let rhs = Tuple::point(1.0, 2.0, 3.0);
|
||||
assert_eq!(lhs, rhs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuples_not_equal() {
|
||||
let lhs = Tuple::point(1.0, 2.0, 3.0);
|
||||
let rhs = Tuple::vector(1.0, 2.0, 3.0);
|
||||
assert_ne!(lhs, rhs);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_two_tuples() {
|
||||
let a1 = Tuple::point(3.0, -2.0, 5.0);
|
||||
let a2 = Tuple::vector(-2.0, 3.0, 1.0);
|
||||
|
||||
let result = Tuple::point(1.0, 1.0, 6.0);
|
||||
assert_eq!(result, a1 + a2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subtract_two_points() {
|
||||
let a1 = Tuple::point(3.0, 2.0, 1.0);
|
||||
let a2 = Tuple::point(5.0, 6.0, 7.0);
|
||||
|
||||
let result = Tuple::vector(-2.0, -4.0, -6.0);
|
||||
assert_eq!(result, a1 - a2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subract_vector_from_point() {
|
||||
let a1 = Tuple::point(3.0, 2.0, 1.0);
|
||||
let a2 = Tuple::vector(5.0, 6.0, 7.0);
|
||||
|
||||
let result = Tuple::point(-2.0, -4.0, -6.0);
|
||||
assert_eq!(result, a1 - a2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subract_vector_from_vector() {
|
||||
let a1 = Tuple::vector(3.0, 2.0, 1.0);
|
||||
let a2 = Tuple::vector(5.0, 6.0, 7.0);
|
||||
|
||||
let result = Tuple::vector(-2.0, -4.0, -6.0);
|
||||
assert_eq!(result, a1 - a2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subtract_vector_from_zero_vector() {
|
||||
let a1 = Tuple::vector(0.0, 0.0, 0.0);
|
||||
let a2 = Tuple::vector(5.0, 6.0, 7.0);
|
||||
|
||||
let result = Tuple::vector(-5.0, -6.0, -7.0);
|
||||
assert_eq!(result, a1 - a2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn negate_tuple() {
|
||||
let a = Tuple::new(1.0, -2.0, 3.0, -4.0);
|
||||
let result = Tuple::new(-1.0, 2.0, -3.0, 4.0);
|
||||
|
||||
assert_eq!(result, -a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiply_tuple_by_scalar() {
|
||||
let a = Tuple::new(1.0, -2.0, 3.0, -4.0);
|
||||
let result = Tuple::new(3.5, -7.0, 10.5, -14.0);
|
||||
|
||||
assert_eq!(result, a * 3.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiply_scalar_by_tuple() {
|
||||
let a = Tuple::new(1.0, -2.0, 3.0, -4.0);
|
||||
let result = Tuple::new(3.5, -7.0, 10.5, -14.0);
|
||||
|
||||
assert_eq!(result, 3.5 * a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiply_tuple_by_fraction() {
|
||||
let a = Tuple::new(1.0, -2.0, 3.0, -4.0);
|
||||
let result = Tuple::new(0.5, -1.0, 1.5, -2.0);
|
||||
|
||||
assert_eq!(result, a * 0.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn divide_tuple() {
|
||||
let a = Tuple::new(1.0, -2.0, 3.0, -4.0);
|
||||
let result = Tuple::new(0.5, -1.0, 1.5, -2.0);
|
||||
|
||||
assert_eq!(result, a / 2.0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user