// Mostly stolen from SebLague's plane game
// thanks
use crate::orbit::newtonian::solve_kepler_with_newtonian;
use nalgebra::{vector, Vector2};
#[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<f64> {
// this doesnt actually do anything
//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<f64> {
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
.mul_add(
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()
.mul_add(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<f64>,
orbiting_on: Vector2<f64>,
) -> Vector2<f64> {
// 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]]
}