Compare commits

...

1 Commits

Author SHA1 Message Date
Jon Janzen
334e2ef3ea 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.
2021-01-23 20:13:34 -07:00
3 changed files with 339 additions and 0 deletions

32
structs/Cargo.lock generated Normal file
View 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
View 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
View 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);
}
}