use phyz_math::Vec3;
#[derive(Clone, Debug)]
pub struct GravityParticle {
pub x: Vec3,
pub v: Vec3,
pub f: Vec3,
pub m: f64,
}
impl GravityParticle {
pub fn new(x: Vec3, v: Vec3, m: f64) -> Self {
Self {
x,
v,
f: Vec3::zeros(),
m,
}
}
pub fn reset_force(&mut self) {
self.f = Vec3::zeros();
}
pub fn add_force(&mut self, f: Vec3) {
self.f += f;
}
pub fn velocity_verlet_step(&mut self, dt: f64) {
self.v += self.f / self.m * (dt / 2.0);
self.x += self.v * dt;
}
pub fn velocity_verlet_complete(&mut self, dt: f64) {
self.v += self.f / self.m * (dt / 2.0);
}
pub fn kinetic_energy(&self) -> f64 {
0.5 * self.m * self.v.norm_squared()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_particle_creation() {
let p = GravityParticle::new(Vec3::new(1.0, 2.0, 3.0), Vec3::zeros(), 1.0);
assert_eq!(p.x, Vec3::new(1.0, 2.0, 3.0));
assert_eq!(p.m, 1.0);
}
#[test]
fn test_kinetic_energy() {
let p = GravityParticle::new(Vec3::zeros(), Vec3::new(1.0, 0.0, 0.0), 2.0);
assert!((p.kinetic_energy() - 1.0).abs() < 1e-10);
}
#[test]
fn test_velocity_verlet() {
let mut p = GravityParticle::new(Vec3::zeros(), Vec3::new(1.0, 0.0, 0.0), 1.0);
p.f = Vec3::new(1.0, 0.0, 0.0);
let dt = 0.1;
p.velocity_verlet_step(dt);
assert!((p.x.x - 0.105).abs() < 1e-10);
}
}