diff --git a/src/physics/body.rs b/src/physics/body.rs new file mode 100644 index 0000000..0dfad4f --- /dev/null +++ b/src/physics/body.rs @@ -0,0 +1,48 @@ +use crate::physics::PhysVec; +use std::f64::consts::{PI, TAU}; + +pub struct PhysBody { + pub pos: PhysVec, + pub vel: PhysVec, + pub mass: f64, + pub angle: f64, // In radians +} + +impl PhysBody { + pub fn new() -> Self { + return PhysBody { + pos: PhysVec { x: 200.0, y: 200.0 }, + vel: PhysVec::zero(), + mass: 1.0, + angle: 0.0, + }; + } + + /// Calculate the state of this body after t seconds. + pub fn tick(&mut self, t: f64) { + self.pos += self.vel * t; + } + + /// Apply an instantaneous force to this object + pub fn force(&mut self, v: PhysVec) { + self.vel += v / self.mass; + } + + /// Apply force in the direction this object is pointing. + pub fn thrust(&mut self, f: f64) { + self.force( + PhysVec { + x: self.angle.sin(), + y: -self.angle.cos(), + } * f, + ); + } + + // Rotate this object by `a` radians. + pub fn rot(&mut self, a: f64) { + self.angle -= a; + if self.angle.abs() > PI { + self.angle -= self.angle.signum() * TAU; + } + } +} diff --git a/src/physics/mod.rs b/src/physics/mod.rs new file mode 100644 index 0000000..33dbd22 --- /dev/null +++ b/src/physics/mod.rs @@ -0,0 +1,5 @@ +mod body; +mod physvec; + +pub use body::PhysBody; +pub use physvec::PhysVec; diff --git a/src/physics/physvec.rs b/src/physics/physvec.rs new file mode 100644 index 0000000..49d4fe5 --- /dev/null +++ b/src/physics/physvec.rs @@ -0,0 +1,92 @@ +use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; + +#[derive(Debug, Clone, Copy)] +pub struct PhysVec { + pub x: f64, + pub y: f64, +} + +impl PhysVec { + pub fn zero() -> Self { + return PhysVec { x: 0f64, y: 0f64 }; + } +} + +impl From<(u32, u32)> for PhysVec { + fn from(value: (u32, u32)) -> Self { + PhysVec { + x: value.0 as f64, + y: value.1 as f64, + } + } +} + +impl Add for PhysVec { + type Output = Self; + + fn add(self, other: Self) -> Self { + Self { + x: self.x + other.x, + y: self.y + other.y, + } + } +} + +impl AddAssign for PhysVec { + fn add_assign(&mut self, rhs: Self) { + self.x += rhs.x; + self.y += rhs.y; + } +} + +impl Sub for PhysVec { + type Output = Self; + + fn sub(self, other: Self) -> Self { + Self { + x: self.x - other.x, + y: self.y - other.y, + } + } +} + +impl SubAssign for PhysVec { + fn sub_assign(&mut self, rhs: Self) { + self.x += rhs.x; + self.y += rhs.y; + } +} + +impl Mul for PhysVec { + type Output = PhysVec; + fn mul(self, rhs: f64) -> Self::Output { + Self { + x: self.x * rhs, + y: self.y * rhs, + } + } +} + +impl MulAssign for PhysVec { + fn mul_assign(&mut self, rhs: f64) { + self.x *= rhs; + self.y *= rhs; + } +} + +impl Div for PhysVec { + type Output = PhysVec; + fn div(self, rhs: f64) -> Self::Output { + Self { + x: self.x / rhs, + y: self.y / rhs, + } + } +} + +impl DivAssign for PhysVec { + fn div_assign(&mut self, rhs: f64) { + self.x /= rhs; + self.y /= rhs; + } +}