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:
Generated
+32
@@ -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",
|
||||
]
|
||||
@@ -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"
|
||||
@@ -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