Conquer Space 0.0.0
A space themed grand strategy game set in the near future, with realistic orbital mechanics, and an emphasis on economics and politics.
orbit.h
Go to the documentation of this file.
1/* Conquer Space
2 * Copyright (C) 2021-2025 Conquer Space
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17#pragma once
18
19#include <math.h>
20
21#include <ostream>
22
23#include <entt/entt.hpp>
24#include <glm/vec3.hpp>
25
29
34typedef glm::dvec3 Vec3AU;
35
36double GetOrbitingRadius(const double e, const kilometer a, const radian v);
37
41struct Orbit {
47 double eccentricity = 0;
48
55
62
69
75 radian w = 0;
76
83
84 double epoch = 0;
85
93 radian v = 0;
94
102 double GM = SunMu;
103
104 // So we can prepare for moons and stuff
105 entt::entity reference_body = entt::null;
106
107 Orbit() = default;
108
109 // TODO(EhWhoAmI): Mean anomaly is not the true anomaly, we need to convert
110 // mean anomaly to true anomaly
114 inclination(std::fmod(inclination, PI)),
115 LAN(std::fmod(LAN, TWOPI)),
116 w(w),
117 M0(M0),
118 v(M0),
119 epoch(0),
120 reference_body(entt::null) {}
121
123 entt::entity reference)
126 inclination(std::fmod(inclination, PI)),
127 LAN(std::fmod(LAN, TWOPI)),
128 w(w),
129 M0(M0),
130 v(M0),
131 epoch(0),
132 reference_body(reference) {}
133
134 Orbit(const Orbit& orbit)
135 : eccentricity(orbit.eccentricity),
138 LAN(orbit.LAN),
139 w(orbit.w),
140 M0(orbit.M0),
141 v(orbit.M0),
142 epoch(orbit.epoch),
143 GM(orbit.GM),
145
146 double GetMtElliptic(double time) const { return normalize_radian(M0 + (time - epoch) * nu()); }
147
148 double GetOrbitingRadius() const;
149
150 double GetOrbitingRadius(double v) const;
151
152 // Orbital period
153 double T() const { return 2 * PI * sqrt(semi_major_axis * semi_major_axis * semi_major_axis / GM); }
154
155 // Mean motion
156 double nu() const { return sqrt(GM / abs(semi_major_axis * semi_major_axis * semi_major_axis)); }
157
158 double GetApoapsis() const { return semi_major_axis * (1 + eccentricity); }
159
160 double GetPeriapsis() const { return semi_major_axis * (1 - eccentricity); }
161
162 double TimeToTrueAnomaly(double v2) const;
163
164 double OrbitalVelocity() const;
165
166 double OrbitalVelocityAtTrueAnomaly(double true_anomaly) const;
167
168 std::string ToHumanString() const;
169};
170
171inline std::ostream& operator<<(std::ostream& outs, const Orbit& orb) {
172 return outs << "(a=" << orb.semi_major_axis << ", e=" << orb.eccentricity << ", i=" << orb.inclination
173 << ", LAN=" << orb.LAN << ", w=" << orb.w << ", GM=" << orb.GM << ", v=" << orb.v << ", M0=" << orb.M0
174 << ", t=" << orb.epoch << ", ref=" << (uint32_t)orb.reference_body << ")";
175}
176
180constexpr double apoapsis = PI;
184constexpr double periapsis = 0;
185
188};
189
198glm::dvec3 ConvertOrbParams(const double LAN, const double i, const double w, const glm::dvec3& vec);
199
200glm::dvec3 ConvertToOrbitalVector(const double LAN, const double i, const double w, const double v,
201 const glm::dvec3& vec);
202
203glm::dvec3 MatrixConvertOrbParams(const double LAN, const double i, const double w, const glm::dvec3& vec);
204
211void UpdateOrbit(Orbit& orb, const second& time);
212
218double GetTrueAnomaly(const Orbit& orb, const second& epoch);
219
227glm::dvec3 CalculateVelocity(const double& E, const kilometer& r, const double& GM, const kilometer& a,
228 const double& e);
229
230glm::dvec3 CalculateVelocityElliptic(const double& E, const kilometer& r, const double& GM, const kilometer& a,
231 const double& e);
232
233glm::dvec3 CalculateVelocityHyperbolic(const double& E, const double& r, const double& GM, const double& a,
234 const double& e);
235
237double GetCircularOrbitingVelocity(const double& GM, const double& radius);
238
244double GetTrueAnomalyToAsymptope(const Orbit& orbit);
245
253Orbit Vec3ToOrbit(const glm::dvec3& position, const glm::dvec3& velocity, const double& GM, const double& time);
254
265glm::dvec3 OrbitToVec3(const double& a, const double& e, const radian& i, const radian& LAN, const radian& w,
266 const radian& v);
267
268double OrbitVelocity(const double v, const double e, const double a, const double GM);
269double OrbitVelocityAtR(const double GM, const double a, const double r);
270double AvgOrbitalVelocity(const Orbit& orb);
271
272glm::dvec3 OrbitVelocityToVec3(const Orbit& orb, double v);
273glm::dvec3 OrbitVelocityToVec3(const Orbit& orb);
274
283double SolveKeplerElliptic(const double& mean_anomaly, const double& ecc, const int steps = 200);
284
293double SolveKeplerHyperbolic(const double& mean_anomaly, const double& ecc, const int steps = 200);
294
300double EccentricAnomalyToTrueAnomaly(const double& ecc, const double& E);
301
302double HyperbolicAnomalyToTrueAnomaly(const double& ecc, const double& H);
303
311double GetMtElliptic(const double& M0, const double& nu, const double& time, const double& epoch);
312
320double GetMtHyperbolic(const double& M0, const double& nu, const double& time, const double& epoch);
321
326radian TrueAnomalyElliptic(const Orbit& orbit, const second& time);
327radian TrueAnomalyElliptic(const Orbit& orbit, const second& time, double& E_out);
328
329radian TrueAnomalyHyperbolic(const Orbit& orbit, const second& time);
330
337radian EccentricAnomaly(double v, double e);
338radian HyperbolicAnomaly(double v, double e);
345inline Vec3AU toVec3AU(const Orbit& orb, radian theta) {
346 glm::dvec3 vec = OrbitToVec3(orb.semi_major_axis, orb.eccentricity, orb.inclination, orb.LAN, orb.w, theta);
347 return vec / KmInAu;
348}
349
360Orbit ApplyImpulse(const Orbit& orbit, const glm::dvec3& impulse, double time);
361
368inline glm::dvec3 toVec3(const Orbit& orb, radian theta) {
369 return OrbitToVec3(orb.semi_major_axis, orb.eccentricity, orb.inclination, orb.LAN, orb.w, theta);
370}
371
372glm::dvec3 OrbitTimeToVec3(const Orbit& orb, const second time = 0);
373glm::dvec3 OrbitTimeToVelocityVec3(const Orbit& orb, const second time = 0);
374
375inline glm::dvec3 toVec3(const Orbit& orb) { return toVec3(orb, orb.v); }
381inline Vec3AU toVec3AU(const Orbit& orb) { return toVec3AU(orb, orb.v); }
382
388inline void UpdatePos(Kinematics& kin, const Orbit& orb) {
389 // Calculate time
390 kin.position = toVec3AU(orb);
391}
392
393double CalculateTransferTime(const Orbit& orb1, const Orbit& orb2);
394double CalculateTransferAngle(const Orbit& start_orbit, const Orbit& end_orbit);
395double CalculatePhaseAngle(const Orbit& start_orbit, const Orbit& end_orbit, double epoch);
396
397// https://orbital-mechanics.space/the-orbit-equation/hyperbolic-trajectories.html
398// True anomaly of the asymptope for a hyperbolic orbit
399// The hyperbolic asymtope is defined by -GetHyperbolicAsymtope < v <GetHyperbolicAsymtope
400double GetHyperbolicAsymptopeAnomaly(double eccentricity);
401
402double FlightPathAngle(double eccentricity, double v);
403
404glm::dvec3 GetOrbitNormal(const Orbit& orbit);
405glm::dvec3 GetRadialVector(const Orbit& orbit);
406glm::dvec3 GetRadialVector(const Orbit& orbit, double true_anomaly);
407glm::dvec3 InvertOrbitalVector(const double LAN, const double i, const double w, const double v, const glm::dvec3& vec);
408double AngleWith(const Orbit& orbit, const Orbit& second_orbit);
409double TrueAnomalyFromVector(const Orbit& orbit, const glm::dvec3& vec);
410
411double AscendingTrueAnomaly(const Orbit& start, const Orbit& dest);
412double GetEccentricity(double apoapsis, double periapsis);
413glm::dvec3 GetEccentricityVector(const glm::dvec3& h, const glm::dvec3& r, const glm::dvec3& v, const double GM);
414glm::dvec3 GetEccentricityVector(const glm::dvec3& r, const glm::dvec3& v, const double GM);
415} // namespace cqsp::common::components::types
Definition: coordinates.cpp:22
glm::dvec3 InvertOrbitalVector(const double LAN, const double i, const double w, const double v, const glm::dvec3 &vec)
Definition: orbit.cpp:486
double TrueAnomalyFromVector(const Orbit &orbit, const glm::dvec3 &vec)
Definition: orbit.cpp:406
double GetTrueAnomalyToAsymptope(const Orbit &orbit)
Calculates v_inf, the true anomaly for the asymtope for a hyperbolic orbit The orbit is bouded within...
Definition: orbit.cpp:161
double CalculateTransferAngle(const Orbit &start_orbit, const Orbit &end_orbit)
Definition: orbit.cpp:380
glm::dvec3 CalculateVelocityHyperbolic(const double &E, const double &r, const double &GM, const double &a, const double &e)
Definition: orbit.cpp:321
radian HyperbolicAnomaly(double v, double e)
Definition: orbit.cpp:288
double GetEccentricity(double apoapsis, double periapsis)
Definition: orbit.cpp:429
glm::dvec3 ConvertOrbParams(const double LAN, const double i, const double w, const glm::dvec3 &vec)
Transforms a vector to the orbital plane vector
Definition: orbit.cpp:48
glm::dvec3 ConvertToOrbitalVector(const double LAN, const double i, const double w, const double v, const glm::dvec3 &vec)
Definition: orbit.cpp:53
glm::dvec3 GetOrbitNormal(const Orbit &orbit)
Definition: orbit.cpp:402
double GetHyperbolicAsymptopeAnomaly(double eccentricity)
Definition: orbit.cpp:396
double second
Definition: units.h:42
double GetMtHyperbolic(const double &M0, const double &nu, const double &time, const double &epoch)
Calculate mean anomaly from time for a hyperbolic object
Definition: orbit.cpp:255
constexpr double apoapsis
Definition: orbit.h:180
Orbit ApplyImpulse(const Orbit &orbit, const glm::dvec3 &impulse, double time)
Applies impulse based on the vector impulse For some reason y is prograde, I'm not sure what the othe...
Definition: orbit.cpp:334
glm::dvec3 GetRadialVector(const Orbit &orbit)
Definition: orbit.cpp:478
glm::vec3 toVec3(const SurfaceCoordinate &coord, const float &radius)
Converts surface coordinate to vector3 in space so that we can get the surface coordinate to render i...
Definition: coordinates.cpp:33
glm::dvec3 OrbitToVec3(const double &a, const double &e, const radian &i, const radian &LAN, const radian &w, const radian &v)
Converts an orbit to a vec3.
Definition: orbit.cpp:164
std::ostream & operator<<(std::ostream &outs, const Orbit &orb)
Definition: orbit.h:171
constexpr double KmInAu
Definition: units.h:49
double AscendingTrueAnomaly(const Orbit &start, const Orbit &dest)
Definition: orbit.cpp:422
glm::dvec3 OrbitTimeToVec3(const Orbit &orb, const second time)
Definition: orbit.cpp:351
constexpr double SunMu
Definition: units.h:57
double GetMtElliptic(const double &M0, const double &nu, const double &time, const double &epoch)
Gets the Mean anomaly from the time
Definition: orbit.cpp:249
double kilometer
Definition: units.h:34
glm::dvec3 MatrixConvertOrbParams(const double LAN, const double i, const double w, const glm::dvec3 &vec)
Definition: orbit.cpp:40
glm::dvec3 OrbitTimeToVelocityVec3(const Orbit &orb, const second time)
Definition: orbit.cpp:361
double radian
Definition: units.h:37
double SolveKeplerHyperbolic(const double &mean_anomaly, const double &ecc, const int steps)
Computes eccentric anomaly for a hyperbolic or parabolic orbit (e > 1) in radians given mean anomaly ...
Definition: orbit.cpp:219
double AngleWith(const Orbit &orbit, const Orbit &second_orbit)
Definition: orbit.cpp:493
radian EccentricAnomaly(double v, double e)
Calculates Eccentric anomaly
Definition: orbit.cpp:286
double OrbitVelocity(const double v, const double e, const double a, const double GM)
Definition: orbit.cpp:177
constexpr radian normalize_radian(const radian &radian)
Normalizes a radian to [0, PI*2)
Definition: units.h:70
constexpr double periapsis
Definition: orbit.h:184
double SolveKeplerElliptic(const double &mean_anomaly, const double &ecc, const int steps)
Computes eccentric anomaly for a elliptic or circular orbit (e < 1) in radians given mean anomaly and...
Definition: orbit.cpp:199
constexpr double TWOPI
Definition: units.h:46
double GetTrueAnomaly(const Orbit &orb, const second &epoch)
Get anomaly at epoch
Definition: orbit.cpp:302
constexpr double PI
Definition: units.h:45
double CalculateTransferTime(const Orbit &orb1, const Orbit &orb2)
Definition: orbit.cpp:371
radian TrueAnomalyHyperbolic(const Orbit &orbit, const second &time)
Definition: orbit.cpp:275
void UpdateOrbit(Orbit &orb, const second &time)
Updates the orbit's true anomaly.
Definition: orbit.cpp:293
double GetCircularOrbitingVelocity(const double &GM, const double &radius)
Get the circular orbiting velocity for the radius.
Definition: orbit.cpp:273
double HyperbolicAnomalyToTrueAnomaly(const double &ecc, const double &H)
Definition: orbit.cpp:243
double GetOrbitingRadius(const double e, const kilometer a, const radian v)
Definition: orbit.cpp:32
glm::dvec3 CalculateVelocity(const double &E, const kilometer &r, const double &GM, const kilometer &a, const double &e)
Definition: orbit.cpp:312
Orbit Vec3ToOrbit(const glm::dvec3 &position, const glm::dvec3 &velocity, const double &GM, const double &time)
Converts position and velocity to orbit. Note: you will have to set the reference body after the orbi...
Definition: orbit.cpp:81
double AvgOrbitalVelocity(const Orbit &orb)
Definition: orbit.cpp:184
double FlightPathAngle(double eccentricity, double v)
Definition: orbit.cpp:398
glm::dvec3 Vec3AU
A vector3 where the units are astronomical units
Definition: orbit.h:34
glm::dvec3 GetEccentricityVector(const glm::dvec3 &h, const glm::dvec3 &r, const glm::dvec3 &v, const double GM)
Definition: orbit.cpp:66
double CalculatePhaseAngle(const Orbit &start_orbit, const Orbit &end_orbit, double epoch)
Definition: orbit.cpp:389
Vec3AU toVec3AU(const Orbit &orb, radian theta)
Convert orbit to AU coordinates
Definition: orbit.h:345
glm::dvec3 CalculateVelocityElliptic(const double &E, const kilometer &r, const double &GM, const kilometer &a, const double &e)
Definition: orbit.cpp:326
radian TrueAnomalyElliptic(const Orbit &orbit, const second &time)
Definition: orbit.cpp:260
double EccentricAnomalyToTrueAnomaly(const double &ecc, const double &E)
Calculates true anomaly from eccentricity and eccentric anomaly
Definition: orbit.cpp:239
glm::dvec3 OrbitVelocityToVec3(const Orbit &orb, double v)
Definition: orbit.cpp:186
void UpdatePos(Kinematics &kin, const Orbit &orb)
Updates the position of an orbit, in AU.
Definition: orbit.h:388
double OrbitVelocityAtR(const double GM, const double a, const double r)
Definition: orbit.cpp:349
Relative position from the parent orbiting object.
Definition: coordinates.h:32
glm::dvec3 position
Definition: coordinates.h:33
double eccentricity
Definition: orbit.h:47
std::string ToHumanString() const
Definition: orbit.cpp:497
radian M0
Definition: orbit.h:82
double GM
Gravitational constant of the reference body this is orbiting Graviational constant * mass of orbitin...
Definition: orbit.h:102
radian LAN
Definition: orbit.h:68
kilometer semi_major_axis
Definition: orbit.h:54
Orbit(kilometer semi_major_axis, double eccentricity, radian inclination, radian LAN, radian w, radian M0)
Definition: orbit.h:111
double OrbitalVelocity() const
Definition: orbit.cpp:472
double GetOrbitingRadius() const
Definition: orbit.cpp:431
double nu() const
Definition: orbit.h:156
double OrbitalVelocityAtTrueAnomaly(double true_anomaly) const
Definition: orbit.cpp:474
double GetApoapsis() const
Definition: orbit.h:158
Orbit(kilometer semi_major_axis, double eccentricity, radian inclination, radian LAN, radian w, radian M0, entt::entity reference)
Definition: orbit.h:122
Orbit(const Orbit &orbit)
Definition: orbit.h:134
radian inclination
Definition: orbit.h:61
entt::entity reference_body
Definition: orbit.h:105
double GetPeriapsis() const
Definition: orbit.h:160
double epoch
Definition: orbit.h:84
double GetMtElliptic(double time) const
Definition: orbit.h:146
radian v
True anomaly v Radians
Definition: orbit.h:93
double T() const
Definition: orbit.h:153
radian w
Definition: orbit.h:75
double TimeToTrueAnomaly(double v2) const
Definition: orbit.cpp:436
double true_anomaly
Definition: orbit.h:187