Compare commits

...

3 Commits

Author SHA1 Message Date
ktyl 7749e5cda4 chore: extract retrieving cartesian elements 2023-10-13 23:30:31 +01:00
ktyl 68e26c64c9 feat(orbit): cycle animation 2023-10-08 00:13:32 +01:00
ktyl 4d4830f82f feat(orbit): update orbit vertices over time 2023-10-07 23:54:05 +01:00
3 changed files with 85 additions and 28 deletions

View File

@ -37,6 +37,7 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <astro/stateVectorIndices.hpp>
#include "gfx.hpp" #include "gfx.hpp"
#include "icosphere.hpp" #include "icosphere.hpp"
@ -54,7 +55,14 @@ int main()
Icosphere planet(0.2, 3, litProgram); Icosphere planet(0.2, 3, litProgram);
Icosphere orbiter(0.07, 2, litProgram); Icosphere orbiter(0.07, 2, litProgram);
Orbit orbit(100);
std::vector<float> keplerianElements(6);
keplerianElements[astro::semiMajorAxisIndex] = .75;
keplerianElements[astro::eccentricityIndex] = .5;
keplerianElements[astro::inclinationIndex] = 3.142 / 2.0 + 1;
keplerianElements[astro::argumentOfPeriapsisIndex] = 2.0;
keplerianElements[astro::longitudeOfAscendingNodeIndex] = 0;
Orbit orbit(keplerianElements);
Widget widget(orbit, unlitProgram); Widget widget(orbit, unlitProgram);
@ -65,8 +73,25 @@ int main()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float time = glfwGetTime(); float time = glfwGetTime();
const float orbitalPeriod = 6.284;
glm::vec3 pos = orbit.getPosition(time); const int ANIM_ORBITING = 0;
const int ANIM_ECCENTRICITY = 1;
int animation = (int)(time / orbitalPeriod) % 2 == 1;
glm::vec3 pos;
if (animation == ANIM_ORBITING)
{
pos = orbit.getPosition(time);
}
else if (animation == ANIM_ECCENTRICITY)
{
float e = .25 + .2 * sin(time);
keplerianElements[astro::eccentricityIndex] = e;
orbit.setElements(keplerianElements);
pos = orbit.getPosition(0);
}
orbiter.setPosition(pos); orbiter.setPosition(pos);
// Render lit objects // Render lit objects

View File

@ -3,18 +3,22 @@
#include "astro/stateVectorIndices.hpp" #include "astro/stateVectorIndices.hpp"
#include "astro/orbitalElementConversions.hpp" #include "astro/orbitalElementConversions.hpp"
Orbit::Orbit(int vertexCount) : Orbit::Orbit(Vector6 keplerianElements) :
_keplerianElements(std::vector<float>(6)) _keplerianElements(keplerianElements)
{ {
_keplerianElements[astro::semiMajorAxisIndex] = .75; glGenVertexArrays(1, &_vao);
_keplerianElements[astro::eccentricityIndex] = .5; glGenBuffers(1, &_vbo);
_keplerianElements[astro::inclinationIndex] = _pi / 2.0 + 1;
_keplerianElements[astro::argumentOfPeriapsisIndex] = 2.0;
_keplerianElements[astro::longitudeOfAscendingNodeIndex] = 0;
for (int i = 0; i < vertexCount; i++) regenerateVertices();
}
void Orbit::regenerateVertices()
{
_vertices.clear();
for (int i = 0; i < _vertexCount; i++)
{ {
float t = (float)i / (float)vertexCount * 2.0 * _pi; 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);
@ -22,9 +26,6 @@ Orbit::Orbit(int vertexCount) :
_vertices.push_back(pos.z); _vertices.push_back(pos.z);
} }
glGenVertexArrays(1, &_vao);
glGenBuffers(1, &_vbo);
glBindVertexArray(_vao); glBindVertexArray(_vao);
glBindBuffer(GL_ARRAY_BUFFER, _vbo); glBindBuffer(GL_ARRAY_BUFFER, _vbo);
@ -38,11 +39,14 @@ Orbit::Orbit(int vertexCount) :
glBindVertexArray(0); glBindVertexArray(0);
} }
// Interpolate a position around the orbit. void Orbit::setElements(Vector6 keplerianElements)
// t is in range 0..1 and wraps. {
glm::vec3 Orbit::getPosition(const float meanAnomaly) _keplerianElements = keplerianElements;
regenerateVertices();
}
float Orbit::getEccentricAnomaly(const float meanAnomaly)
{ {
// Get eccentric anomaly from elliptical mean anomaly
const float eccentricity = _keplerianElements[astro::eccentricityIndex]; const float eccentricity = _keplerianElements[astro::eccentricityIndex];
float eccentricAnomaly = astro::convertEllipticalMeanAnomalyToEccentricAnomaly( float eccentricAnomaly = astro::convertEllipticalMeanAnomalyToEccentricAnomaly(
eccentricity, eccentricity,
@ -50,21 +54,36 @@ glm::vec3 Orbit::getPosition(const float meanAnomaly)
(float)10e-3, (float)10e-3,
100); 100);
// Get true anomaly from eccentric anomaly return eccentricAnomaly;
float trueAnomaly = astro::convertEccentricAnomalyToTrueAnomaly( }
eccentricAnomaly,
eccentricity);
std::vector<float> kepler(_keplerianElements); // Interpolate a position around the orbit.
kepler[astro::trueAnomalyIndex] = trueAnomaly; // t is in range 0..1 and wraps.
glm::vec3 Orbit::getPosition(const float meanAnomaly)
std::vector<float> cartesian = astro::convertKeplerianToCartesianElements(kepler, 1.0); {
Vector6 cartesian = getCartesianCoordinates(meanAnomaly);
return glm::vec3( return glm::vec3(
cartesian[astro::xPositionIndex], cartesian[astro::xPositionIndex],
cartesian[astro::yPositionIndex], cartesian[astro::yPositionIndex],
cartesian[astro::zPositionIndex]); cartesian[astro::zPositionIndex]);
} }
float Orbit::getTrueAnomaly(const float meanAnomaly)
{
const float eccentricAnomaly = getEccentricAnomaly(meanAnomaly);
const float eccentricity = _keplerianElements[astro::eccentricityIndex];
return astro::convertEccentricAnomalyToTrueAnomaly(
eccentricAnomaly,
eccentricity);
}
Vector6 Orbit::getCartesianCoordinates(const float meanAnomaly)
{
Vector6 kepler(_keplerianElements);
kepler[astro::trueAnomalyIndex] = getTrueAnomaly(meanAnomaly);
return astro::convertKeplerianToCartesianElements(kepler, 1.0);
}
glm::vec3 Orbit::getTangent(const float meanAnomaly) glm::vec3 Orbit::getTangent(const float meanAnomaly)
{ {
float epsilon = 0.01; float epsilon = 0.01;

View File

@ -5,22 +5,35 @@
#include "glm/glm.hpp" #include "glm/glm.hpp"
typedef std::vector<float> Vector6;
class Orbit class Orbit
{ {
public: public:
Orbit(int vertexCount); Orbit(Vector6 keplerianElements);
void render(); void render();
// TODO: meanAnomaly in all these arguments actually means eccentricMeanAnomaly,
// will have to change that when adding non-ellipctical orbits - don't get confused!
glm::vec3 getPosition(const float meanAnomaly); glm::vec3 getPosition(const float meanAnomaly);
glm::vec3 getTangent(const float meanAnomaly); glm::vec3 getTangent(const float meanAnomaly);
void setElements(Vector6 keplerianElements);
~Orbit(); ~Orbit();
private: private:
const float _pi = 3.14159265359; const float _pi = 3.14159265359;
const int _vertexCount = 100;
GLuint _vbo; GLuint _vbo;
GLuint _vao; GLuint _vao;
std::vector<float> _vertices; std::vector<float> _vertices;
std::vector<float> _keplerianElements; Vector6 _keplerianElements;
void regenerateVertices();
float getEccentricAnomaly(const float meanAnomaly);
float getTrueAnomaly(const float meanAnomaly);
Vector6 getCartesianCoordinates(const float meanAnomaly);
}; };