// Mostly stolen from SebLague's plane game // thanks use log::debug; use nalgebra::{vector, Vector2}; use crate::orbit::newtonian::solve_kepler_with_newtonian; use crate::orbit::vis_viva::vis_viva; use crate::planet::GRAVITY; pub fn calculate_vector_of_orbit(periapsis: f64, apoapsis: f64, t: f64, mass_of_bigger: f64, current_x_vel: f64, current_y_vel: f64, delta_t: f64, mass_of_orbiter: f64) -> Vector2 { let semi_major_length = (apoapsis + periapsis) / 2.0; let linear_eccentricity = semi_major_length - periapsis; // distance between center and focus let distances = calculate_point_on_orbit(periapsis, apoapsis, t); let distance_x = distances[0]; let distance_y = distances[1]; let distance = (distance_x * distance_x + distance_y * distance_y).sqrt(); let velocity = vis_viva(distance, semi_major_length, GRAVITY, mass_of_bigger); let ellipse_center_x = -linear_eccentricity; let ellipse_center_y = apoapsis - semi_major_length; let theta = (ellipse_center_x / ellipse_center_y).atan() - std::f64::consts::PI / 2.0; let x_vel = velocity * theta.sin(); let y_vel = velocity * theta.cos(); let x_accel = current_x_vel - x_vel / delta_t; let y_accel = current_y_vel - y_vel / delta_t; let x_force = mass_of_orbiter * x_accel; let y_force = mass_of_orbiter * y_accel; vector![x_force, y_force] } 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]] }