78 lines
1.8 KiB
Rust
Raw Normal View History

2025-05-04 01:04:46 +02:00
use crate::body::Body;
const G: f64 = 6.67430e-11;
pub struct Simulator {
pub bodies: Vec<Body>,
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;
}
}