feat: correct elliptical orbital motion

This commit is contained in:
ktyl 2023-08-15 00:14:19 +02:00
parent 75cf44e2fd
commit 9f2c05bf6f
3 changed files with 20 additions and 9 deletions

View File

@ -51,8 +51,8 @@ int main()
GLuint litProgram = compileShaderProgram("./frag_lit.glsl"); GLuint litProgram = compileShaderProgram("./frag_lit.glsl");
GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl"); GLuint unlitProgram = compileShaderProgram("./frag_unlit.glsl");
Icosphere planet(0.3, 3, litProgram); Icosphere planet(0.2, 3, litProgram);
Icosphere orbiter(0.1, 2, litProgram); Icosphere orbiter(0.07, 2, litProgram);
Orbit orbit(100); Orbit orbit(100);
// Main loop // Main loop
@ -63,7 +63,7 @@ int main()
float time = glfwGetTime(); float time = glfwGetTime();
glm::vec3 pos = orbit.getPosition(time * .3); glm::vec3 pos = orbit.getPosition(time);
orbiter.setPosition(pos); orbiter.setPosition(pos);
// Render lit objects // Render lit objects

View File

@ -7,14 +7,14 @@ Orbit::Orbit(int vertexCount) :
_keplerianElements(std::vector<float>(6)) _keplerianElements(std::vector<float>(6))
{ {
_keplerianElements[astro::semiMajorAxisIndex] = .75; _keplerianElements[astro::semiMajorAxisIndex] = .75;
_keplerianElements[astro::eccentricityIndex] = .3; _keplerianElements[astro::eccentricityIndex] = .5;
_keplerianElements[astro::inclinationIndex] = _pi / 2.0 + 1; _keplerianElements[astro::inclinationIndex] = _pi / 2.0 + 1;
_keplerianElements[astro::argumentOfPeriapsisIndex] = 2.0; _keplerianElements[astro::argumentOfPeriapsisIndex] = 2.0;
_keplerianElements[astro::longitudeOfAscendingNodeIndex] = 0; _keplerianElements[astro::longitudeOfAscendingNodeIndex] = 0;
for (int i = 0; i < vertexCount; i++) for (int i = 0; i < vertexCount; i++)
{ {
float t = (float)i / (float)vertexCount; float t = (float)i / (float)vertexCount * 2.0 * _pi;
glm::vec3 pos = getPosition(t); glm::vec3 pos = getPosition(t);
_vertices.push_back(pos.x); _vertices.push_back(pos.x);
@ -40,12 +40,23 @@ Orbit::Orbit(int vertexCount) :
// Interpolate a position around the orbit. // Interpolate a position around the orbit.
// t is in range 0..1 and wraps. // t is in range 0..1 and wraps.
glm::vec3 Orbit::getPosition(float t) glm::vec3 Orbit::getPosition(const float meanAnomaly)
{ {
float a = t * 2.0 * _pi; // Get eccentric anomaly from elliptical mean anomaly
const float eccentricity = _keplerianElements[astro::eccentricityIndex];
float eccentricAnomaly = astro::convertEllipticalMeanAnomalyToEccentricAnomaly(
eccentricity,
meanAnomaly,
(float)10e-3,
100);
// Get true anomaly from eccentric anomaly
float trueAnomaly = astro::convertEccentricAnomalyToTrueAnomaly(
eccentricAnomaly,
eccentricity);
std::vector<float> kepler(_keplerianElements); std::vector<float> kepler(_keplerianElements);
kepler[astro::trueAnomalyIndex] = a; kepler[astro::trueAnomalyIndex] = trueAnomaly;
std::vector<float> cartesian = astro::convertKeplerianToCartesianElements(kepler, 1.0); std::vector<float> cartesian = astro::convertKeplerianToCartesianElements(kepler, 1.0);
return glm::vec3( return glm::vec3(

View File

@ -11,7 +11,7 @@ public:
Orbit(int vertexCount); Orbit(int vertexCount);
void render(); void render();
glm::vec3 getPosition(float t); glm::vec3 getPosition(const float meanAnomaly);
~Orbit(); ~Orbit();
private: private: