From 6d9bdae160dd171b115e6b7cc67debe2f309b513 Mon Sep 17 00:00:00 2001 From: Verox001 Date: Tue, 6 May 2025 19:04:30 +0200 Subject: [PATCH] Fixed 3D rendering --- solar_engine/src/simulator.rs | 79 ++++++++++++----------------------- 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/solar_engine/src/simulator.rs b/solar_engine/src/simulator.rs index 2fe54f1..6bfa553 100644 --- a/solar_engine/src/simulator.rs +++ b/solar_engine/src/simulator.rs @@ -1,5 +1,5 @@ use std::sync::Mutex; -use cgmath::Vector3; +use cgmath::{InnerSpace, Vector3}; use crate::body::Body; use rayon::prelude::*; @@ -11,10 +11,9 @@ pub struct Simulator { timewarp: u32 } -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 +pub fn distance_squared(a: Vector3, b: Vector3) -> f64 { + let d = a - b; + d.magnitude2() } const MAX_TIMEWARP: u32 = 536870912; @@ -52,78 +51,62 @@ impl Simulator { let masses: Vec = self.bodies.iter().map(|b| b.mass).collect(); - fn compute_accelerations(states: &[State], masses: &[f64]) -> Vec<[f64; 2]> { + fn compute_accelerations(states: &[State], masses: &[f64]) -> Vec> { let n = states.len(); - let accels = (0..n).map(|_| Mutex::new([0.0, 0.0])).collect::>(); + let accels = (0..n).map(|_| Mutex::new(Vector3::new(0.0, 0.0, 0.0))).collect::>(); (0..n).into_par_iter().for_each(|i| { for j in (i + 1)..n { - let dx = states[j].position[0] - states[i].position[0]; - let dy = states[j].position[1] - states[i].position[1]; - let dist_sq = dx * dx + dy * dy; + let r = states[j].position - states[i].position; + let dist_sq = r.magnitude2(); let dist = dist_sq.sqrt(); - if dist < 1e-3 { + if dist < 1e-8 { continue; } let force = G * masses[i] * masses[j] / dist_sq; - let ax = force * dx / dist; - let ay = force * dy / dist; + let accel = force * r / (dist * masses[i]); + let accel_j = -force * r / (dist * masses[j]); { let mut a_i_lock = accels[i].lock().unwrap(); - a_i_lock[0] += ax / masses[i]; - a_i_lock[1] += ay / masses[i]; + *a_i_lock += accel; } { let mut a_j_lock = accels[j].lock().unwrap(); - a_j_lock[0] -= ax / masses[j]; - a_j_lock[1] -= ay / masses[j]; + *a_j_lock += accel_j; } } }); - accels - .into_iter() - .map(|mutex| mutex.into_inner().unwrap()) - .collect() + accels.into_iter().map(|mutex| mutex.into_inner().unwrap()).collect() } let k1_pos = original_states.iter().map(|s| s.velocity).collect::>(); let k1_vel = compute_accelerations(&original_states, &masses); - let mut temp_states = original_states - .iter() - .enumerate() - .map(|(i, s)| State { - position: Vector3::new(s.position[0], s.position[1], 0.0), - velocity: Vector3::new( - s.velocity[0] + k1_vel[i][0] * dt / 2.0, - s.velocity[1] + k1_vel[i][1] * dt / 2.0, - 0.0, - ), - }) - .collect::>(); + let mut temp_states: Vec = original_states.iter().enumerate().map(|(i, s)| { + State { + position: s.position + k1_pos[i] * (dt / 2.0), + velocity: s.velocity + k1_vel[i] * (dt / 2.0), + } + }).collect(); let k2_pos = temp_states.iter().map(|s| s.velocity).collect::>(); let k2_vel = compute_accelerations(&temp_states, &masses); for i in 0..n { - temp_states[i].position[0] = original_states[i].position[0] + k2_pos[i][0] * dt / 2.0; - temp_states[i].position[1] = original_states[i].position[1] + k2_pos[i][1] * dt / 2.0; - temp_states[i].velocity[0] = original_states[i].velocity[0] + k2_vel[i][0] * dt / 2.0; - temp_states[i].velocity[1] = original_states[i].velocity[1] + k2_vel[i][1] * dt / 2.0; + temp_states[i].position = original_states[i].position + k2_pos[i] * (dt / 2.0); + temp_states[i].velocity = original_states[i].velocity + k2_vel[i] * (dt / 2.0); } let k3_pos = temp_states.iter().map(|s| s.velocity).collect::>(); let k3_vel = compute_accelerations(&temp_states, &masses); for i in 0..n { - temp_states[i].position[0] = original_states[i].position[0] + k3_pos[i][0] * dt; - temp_states[i].position[1] = original_states[i].position[1] + k3_pos[i][1] * dt; - temp_states[i].velocity[0] = original_states[i].velocity[0] + k3_vel[i][0] * dt; - temp_states[i].velocity[1] = original_states[i].velocity[1] + k3_vel[i][1] * dt; + temp_states[i].position = original_states[i].position + k3_pos[i] * dt; + temp_states[i].velocity = original_states[i].velocity + k3_vel[i] * dt; } let k4_pos = temp_states.iter().map(|s| s.velocity).collect::>(); @@ -132,15 +115,8 @@ impl Simulator { for i in 0..n { let body = &mut self.bodies[i]; - body.position[0] += (dt / 6.0) - * (k1_pos[i][0] + 2.0 * k2_pos[i][0] + 2.0 * k3_pos[i][0] + k4_pos[i][0]); - body.position[1] += (dt / 6.0) - * (k1_pos[i][1] + 2.0 * k2_pos[i][1] + 2.0 * k3_pos[i][1] + k4_pos[i][1]); - - body.velocity[0] += (dt / 6.0) - * (k1_vel[i][0] + 2.0 * k2_vel[i][0] + 2.0 * k3_vel[i][0] + k4_vel[i][0]); - body.velocity[1] += (dt / 6.0) - * (k1_vel[i][1] + 2.0 * k2_vel[i][1] + 2.0 * k3_vel[i][1] + k4_vel[i][1]); + body.position += (k1_pos[i] + 2.0 * k2_pos[i] + 2.0 * k3_pos[i] + k4_pos[i]) * (dt / 6.0); + body.velocity += (k1_vel[i] + 2.0 * k2_vel[i] + 2.0 * k3_vel[i] + k4_vel[i]) * (dt / 6.0); } self.time += dt; @@ -170,11 +146,10 @@ impl Simulator { } } - pub fn reset_timewarp(&mut self) { self.timewarp = 1; } - + pub fn get_timewarp(&self) -> u32 { self.timewarp }