Compare commits

...

2 Commits

Author SHA1 Message Date
Jon Janzen
bf1afc092e Created a Projectile and allowed it to be operated on by wind and gravity 2021-02-07 14:49:14 -07:00
Jon Janzen
c863cf5a8b Made methods pub so I could use them 2021-02-07 14:48:45 -07:00
4 changed files with 127 additions and 16 deletions

34
Cargo.lock generated
View File

@@ -1,5 +1,39 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # 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",
]
[[package]] [[package]]
name = "tuples" name = "tuples"
version = "0.1.0" version = "0.1.0"
dependencies = [
"structs",
]

View File

@@ -7,3 +7,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
structs = { path = "structs" }

View File

@@ -1,3 +1,71 @@
fn main() { use structs::Tuple;
println!("Hello, world!");
use std::fmt;
#[derive(Debug)]
struct Environment {
gravity: Tuple,
wind: Tuple,
}
#[derive(Debug, Clone, Copy)]
struct Projectile {
position: Tuple,
velocity: Tuple,
}
impl Projectile {
fn new(position: Tuple, velocity: Tuple) -> Projectile {
if !position.is_point() {
panic!("position can not be a vector");
}
if !velocity.is_vector() {
panic!("velocity can not be point");
}
Projectile {
position: position,
velocity: velocity,
}
}
}
impl Projectile {
fn tick(&mut self, env: &Environment) {
self.position = self.position + self.velocity;
self.velocity = env.wind + env.gravity;
}
}
impl fmt::Display for Projectile {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> fmt::Result {
write!(f, "pos: {}, vel {}", self.position, self.velocity)
}
}
fn init_env() -> Environment {
Environment {
gravity: Tuple::vector(0.0, 0.0, -0.98),
wind: Tuple::vector(0.0, 0.0, 0.0),
}
}
fn main() {
let env = init_env();
let mut ball = Projectile::new(
Tuple::point(0.0, 0.0, 1.0),
Tuple::vector(1.0, 0.0, 0.0),
);
let mut tick = 0;
println!("tick {} the ball {}", tick, ball);
while ball.position.z() > 0.0 {
ball.tick(&env);
println!("tick {} the ball {}", tick, ball);
tick += 1;
}
} }

View File

@@ -1,10 +1,11 @@
#[macro_use] #[macro_use]
extern crate approx; extern crate approx;
use std::fmt;
use std::ops; use std::ops;
#[derive(Debug)] #[derive(Debug, Copy, Clone)]
struct Tuple { pub struct Tuple {
x: f32, x: f32,
y: f32, y: f32,
z: f32, z: f32,
@@ -12,7 +13,7 @@ struct Tuple {
} }
impl Tuple { impl Tuple {
fn new(x: f32, y: f32, z: f32, w: f32) -> Tuple { pub fn new(x: f32, y: f32, z: f32, w: f32) -> Tuple {
Tuple { Tuple {
x, x,
y, y,
@@ -22,7 +23,7 @@ impl Tuple {
} }
fn point(x: f32, y: f32, z: f32) -> Tuple { pub fn point(x: f32, y: f32, z: f32) -> Tuple {
Tuple { Tuple {
x, x,
y, y,
@@ -31,7 +32,7 @@ impl Tuple {
} }
} }
fn vector(x: f32, y: f32, z: f32) -> Tuple { pub fn vector(x: f32, y: f32, z: f32) -> Tuple {
Tuple { Tuple {
x, x,
y, y,
@@ -42,27 +43,27 @@ impl Tuple {
} }
impl Tuple { impl Tuple {
fn x(&self) -> f32 { pub fn x(&self) -> f32 {
self.x self.x
} }
fn y(&self) -> f32 { pub fn y(&self) -> f32 {
self.y self.y
} }
fn z(&self) -> f32 { pub fn z(&self) -> f32 {
self.z self.z
} }
fn is_point(&self) -> bool { pub fn is_point(&self) -> bool {
self.w == 1.0 self.w == 1.0
} }
fn is_vector(&self) -> bool { pub fn is_vector(&self) -> bool {
self.w == 0.0 self.w == 0.0
} }
fn magnitude(&self) -> f32 { pub fn magnitude(&self) -> f32 {
( (
(self.x * self.x) + (self.x * self.x) +
(self.y * self.y) + (self.y * self.y) +
@@ -71,7 +72,7 @@ impl Tuple {
).sqrt() ).sqrt()
} }
fn normalize(&self) -> Tuple { pub fn normalize(&self) -> Tuple {
let m = self.magnitude(); let m = self.magnitude();
Tuple::new( Tuple::new(
self.x / m, self.x / m,
@@ -81,14 +82,14 @@ impl Tuple {
) )
} }
fn dot(&self, rhs: &Tuple) -> f32 { pub fn dot(&self, rhs: &Tuple) -> f32 {
self.x * rhs.x + self.x * rhs.x +
self.y * rhs.y + self.y * rhs.y +
self.z * rhs.z + self.z * rhs.z +
self.w * rhs.w self.w * rhs.w
} }
fn cross(&self, rhs: &Tuple) -> Tuple { pub fn cross(&self, rhs: &Tuple) -> Tuple {
Tuple::vector( Tuple::vector(
self.y * rhs.z - self.z * rhs.y, self.y * rhs.z - self.z * rhs.y,
self.z * rhs.x - self.x * rhs.z, self.z * rhs.x - self.x * rhs.z,
@@ -97,6 +98,12 @@ impl Tuple {
} }
} }
impl fmt::Display for Tuple {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {}, {}) {}", self.x, self.y, self.z, if self.is_point() { "p" } else { "v" } )
}
}
impl PartialEq for Tuple { impl PartialEq for Tuple {
fn eq(&self, _rhs: &Self) -> bool { fn eq(&self, _rhs: &Self) -> bool {
relative_eq!(self.x, _rhs.x) relative_eq!(self.x, _rhs.x)
@@ -184,6 +191,7 @@ impl ops::Div<f32> for Tuple {
} }
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;