// Mostly stolen from SebLague's plane game // thanks use nalgebra::{vector, Vector2}; use crate::orbit::newtonian::solve_kepler_with_newtonian; #[allow(clippy::too_many_arguments)] pub fn calculate_vector_of_orbit(periapsis: f64, apoapsis: f64, t: f64, current_x: f64, current_y: f64, orbiting_x: f64, orbiting_y: f64, mass: f64, step: f64) -> Vector2 { let semi_major_length = (apoapsis + periapsis) / 2.0; let _linear_eccentricity = semi_major_length - periapsis; // distance between center and focus let target = calculate_world_position_of_orbit(calculate_point_on_orbit(periapsis, apoapsis, t), vector![orbiting_x, orbiting_y]); let target_x = target[0]; let target_y = target[1]; let delta_x = target_x - current_x; let delta_y = target_y - current_y; let velocity_x = delta_x / step; let velocity_y = delta_y / step; let accel_x = velocity_x / step; let accel_y = velocity_y / step; let fx = accel_x * mass; let fy = accel_y * mass; vector![fx, fy] } pub fn calculate_point_on_orbit(periapsis: f64, apoapsis: f64, t: f64) -> Vector2 { let semi_major_length = (apoapsis + periapsis) / 2.0; let linear_eccentricity = semi_major_length - periapsis; // distance between center and focus let eccentricity = linear_eccentricity / semi_major_length; // 0: circle. 1: parabola. in between: ellipse let semi_minor_length = (semi_major_length * semi_major_length - linear_eccentricity * linear_eccentricity).sqrt(); let mean_anomaly = t * std::f64::consts::PI * 2.0; let eccentric_anomaly = solve_kepler_with_newtonian(mean_anomaly, eccentricity, 100); let ellipse_center_x = -linear_eccentricity; let point_x = eccentric_anomaly.cos() * semi_major_length + ellipse_center_x; let point_y = eccentric_anomaly.sin() * semi_minor_length; vector![point_x, point_y] } pub fn calculate_world_position_of_orbit(point: Vector2, orbiting_on: Vector2) -> Vector2 { // i have no idea if this is actually right or not // we'll find out vector![point[0] + orbiting_on[0], point[1] + orbiting_on[1]] }