#[cfg(not(feature = "std"))]
use num_traits::Float;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct Perturbations {
kx0: f64,
kx1: f64,
kx2: f64,
kx3: f64,
kx4: f64,
kx5: f64,
kx6: f64,
kx7: f64,
kx8: f64,
kx9: f64,
kx10: f64,
kx11: f64,
third_body_mean_anomaly_0: f64,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct Dots {
pub(crate) inclination: f64,
pub(crate) right_ascension: f64,
pub(crate) eccentricity: f64,
pub(crate) argument_of_perigee: f64,
pub(crate) mean_anomaly: f64,
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn perturbations_and_dots(
inclination_0: f64,
eccentricity_0: f64,
argument_of_perigee_0: f64,
n0: f64,
third_body_inclination_sine: f64,
third_body_inclination_cosine: f64,
delta_right_ascension_sine: f64,
delta_right_ascension_cosine: f64,
third_body_eccentricity: f64,
third_body_argument_of_perigee_sine: f64,
third_body_argument_of_perigee_cosine: f64,
third_body_perturbation_coefficient: f64,
third_body_mean_motion: f64,
third_body_mean_anomaly_0: f64,
p1: f64,
b0: f64,
) -> (Perturbations, Dots) {
let ax1 = third_body_argument_of_perigee_cosine * delta_right_ascension_cosine
+ third_body_argument_of_perigee_sine
* third_body_inclination_cosine
* delta_right_ascension_sine;
let ax3 = -third_body_argument_of_perigee_sine * delta_right_ascension_cosine
+ third_body_argument_of_perigee_cosine
* third_body_inclination_cosine
* delta_right_ascension_sine;
let ax7 = -third_body_argument_of_perigee_cosine * delta_right_ascension_sine
+ third_body_argument_of_perigee_sine
* third_body_inclination_cosine
* delta_right_ascension_cosine;
let ax8 = third_body_argument_of_perigee_sine * third_body_inclination_sine;
let ax9 = third_body_argument_of_perigee_sine * delta_right_ascension_sine
+ third_body_argument_of_perigee_cosine
* third_body_inclination_cosine
* delta_right_ascension_cosine;
let ax10 = third_body_argument_of_perigee_cosine * third_body_inclination_sine;
let ax2 = inclination_0.cos() * ax7 + inclination_0.sin() * ax8;
let ax4 = inclination_0.cos() * ax9 + inclination_0.sin() * ax10;
let ax5 = -inclination_0.sin() * ax7 + inclination_0.cos() * ax8;
let ax6 = -inclination_0.sin() * ax9 + inclination_0.cos() * ax10;
let xx1 = ax1 * argument_of_perigee_0.cos() + ax2 * argument_of_perigee_0.sin();
let xx2 = ax3 * argument_of_perigee_0.cos() + ax4 * argument_of_perigee_0.sin();
let xx3 = -ax1 * argument_of_perigee_0.sin() + ax2 * argument_of_perigee_0.cos();
let xx4 = -ax3 * argument_of_perigee_0.sin() + ax4 * argument_of_perigee_0.cos();
let xx5 = ax5 * argument_of_perigee_0.sin();
let xx6 = ax6 * argument_of_perigee_0.sin();
let xx7 = ax5 * argument_of_perigee_0.cos();
let xx8 = ax6 * argument_of_perigee_0.cos();
let zx31 = 12.0 * xx1.powi(2) - 3.0 * xx3.powi(2);
let zx32 = 24.0 * xx1 * xx2 - 6.0 * xx3 * xx4;
let zx33 = 12.0 * xx2.powi(2) - 3.0 * xx4.powi(2);
let zx11 = -6.0 * ax1 * ax5 + eccentricity_0.powi(2) * (-24.0 * xx1 * xx7 - 6.0 * xx3 * xx5);
let zx13 = -6.0 * ax3 * ax6 + eccentricity_0.powi(2) * (-24.0 * xx2 * xx8 - 6.0 * xx4 * xx6);
let zx21 = 6.0 * ax2 * ax5 + eccentricity_0.powi(2) * (24.0 * xx1 * xx5 - 6.0 * xx3 * xx7);
let zx23 = 6.0 * ax4 * ax6 + eccentricity_0.powi(2) * (24.0 * xx2 * xx6 - 6.0 * xx4 * xx8);
let zx1 = (3.0 * (ax1.powi(2) + ax2.powi(2)) + zx31 * eccentricity_0.powi(2)) * 2.0 + p1 * zx31;
let zx3 = (3.0 * (ax3.powi(2) + ax4.powi(2)) + zx33 * eccentricity_0.powi(2)) * 2.0 + p1 * zx33;
let px0 = third_body_perturbation_coefficient / n0;
let px1 = -0.5 * px0 / b0;
let px2 = px0 * b0;
let px3 = -15.0 * eccentricity_0 * px2;
let third_body_right_ascension_dot =
if !(5.2359877e-2..=core::f64::consts::PI - 5.2359877e-2).contains(&inclination_0) {
0.0
} else {
-third_body_mean_motion * px1 * (zx21 + zx23) / inclination_0.sin()
};
(
Perturbations {
kx0: 2.0 * px3 * (xx2 * xx3 + xx1 * xx4),
kx1: 2.0 * px3 * (xx2 * xx4 - xx1 * xx3),
kx2: 2.0
* px1
* (-6.0 * (ax1 * ax6 + ax3 * ax5)
+ eccentricity_0.powi(2)
* (-24.0 * (xx2 * xx7 + xx1 * xx8) - 6.0 * (xx3 * xx6 + xx4 * xx5))),
kx3: 2.0 * px1 * (zx13 - zx11),
kx4: -2.0
* px0
* ((6.0 * (ax1 * ax3 + ax2 * ax4) + zx32 * eccentricity_0.powi(2)) * 2.0
+ p1 * zx32),
kx5: -2.0 * px0 * (zx3 - zx1),
kx6: -2.0 * px0 * (-21.0 - 9.0 * eccentricity_0.powi(2)) * third_body_eccentricity,
kx7: 2.0 * px2 * zx32,
kx8: 2.0 * px2 * (zx33 - zx31),
kx9: -18.0 * px2 * third_body_eccentricity,
kx10: -2.0
* px1
* (6.0 * (ax4 * ax5 + ax2 * ax6)
+ eccentricity_0.powi(2)
* (24.0 * (xx2 * xx5 + xx1 * xx6) - 6.0 * (xx4 * xx7 + xx3 * xx8))),
kx11: -2.0 * px1 * (zx23 - zx21),
third_body_mean_anomaly_0,
},
Dots {
inclination: px1 * third_body_mean_motion * (zx11 + zx13),
right_ascension: third_body_right_ascension_dot,
eccentricity: px3 * third_body_mean_motion * (xx1 * xx3 + xx2 * xx4),
argument_of_perigee: px2 * third_body_mean_motion * (zx31 + zx33 - 6.0)
- inclination_0.cos() * third_body_right_ascension_dot,
mean_anomaly: -third_body_mean_motion
* px0
* (zx1 + zx3 - 14.0 - 6.0 * eccentricity_0.powi(2)),
},
)
}
impl Perturbations {
pub(crate) fn long_period_periodic_effects(
&self,
third_body_eccentricity: f64,
third_body_mean_motion: f64,
t: f64,
) -> (f64, f64, f64, f64, f64) {
let third_body_mean_anomaly = self.third_body_mean_anomaly_0 + third_body_mean_motion * t;
let fx =
third_body_mean_anomaly + 2.0 * third_body_eccentricity * third_body_mean_anomaly.sin();
let fx2 = 0.5 * fx.sin().powi(2) - 0.25;
let fx3 = -0.5 * fx.sin() * fx.cos();
(
self.kx0 * fx2 + self.kx1 * fx3,
self.kx2 * fx2 + self.kx3 * fx3,
self.kx4 * fx2 + self.kx5 * fx3 + self.kx6 * fx.sin(),
self.kx7 * fx2 + self.kx8 * fx3 + self.kx9 * fx.sin(),
self.kx10 * fx2 + self.kx11 * fx3,
)
}
}