use crate::body::Body; const G: f64 = 6.67430e-11; pub struct Simulator { pub bodies: Vec, pub time: f64, pub timestep: f64, } pub fn distance_squared(a: [f64; 2], b: [f64; 2]) -> f64 { let dx = a[0] - b[0]; let dy = a[1] - b[1]; dx * dx + dy * dy } impl Simulator { pub fn new(timestep: f64) -> Self { Self { bodies: Vec::new(), time: 0.0, timestep, } } pub fn add_body(&mut self, body: Body) { self.bodies.push(body); } pub fn step(&mut self) { let n = self.bodies.len(); let dt = self.timestep; let mut accelerations = vec![[0.0, 0.0]; n]; for i in 0..n { for j in 0..n { if i == j { continue; } let (bi, bj) = (&self.bodies[i], &self.bodies[j]); let dx = bj.position[0] - bi.position[0]; let dy = bj.position[1] - bi.position[1]; let dist_sq = distance_squared(bi.position, bj.position); let dist = dist_sq.sqrt(); if dist < 1e-3 { continue; } let force = G * bi.mass * bj.mass / dist_sq; let accel = force / bi.mass; let ax = accel * dx / dist; let ay = accel * dy / dist; accelerations[i][0] += ax; accelerations[i][1] += ay; } } for i in 0..n { let a = accelerations[i]; let body = &mut self.bodies[i]; body.velocity[0] += a[0] * dt; body.velocity[1] += a[1] * dt; body.position[0] += body.velocity[0] * dt; body.position[1] += body.velocity[1] * dt; } self.time += dt; } }