~starkingdoms/starkingdoms

ref: e63e7423514ab61346a5feab69bf6f0e349c816b starkingdoms/server/src/orbit/orbit.rs -rw-r--r-- 2.2 KiB
e63e7423 — ghostlyzsh Merge branch 'master' of https://gitlab.com/starkingdoms.tk/starkingdoms.tk 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// 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> {
    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 * 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<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]]
}