#include "orbit.hpp" #include "astro/stateVectorIndices.hpp" #include "astro/orbitalElementConversions.hpp" Orbit::Orbit(Vector6 keplerianElements) : _keplerianElements(keplerianElements) { glGenVertexArrays(1, &_vao); glGenBuffers(1, &_vbo); regenerateVertices(); } void Orbit::regenerateVertices() { _vertices.clear(); for (int i = 0; i < _vertexCount; i++) { float t = (float)i / (float)_vertexCount * 2.0 * _pi; glm::vec3 pos = getPosition(t); _vertices.push_back(pos.x); _vertices.push_back(pos.y); _vertices.push_back(pos.z); } glBindVertexArray(_vao); glBindBuffer(GL_ARRAY_BUFFER, _vbo); size_t vboBufferSize = _vertices.size() * sizeof(float); glBufferData(GL_ARRAY_BUFFER, vboBufferSize, &_vertices[0], GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } void Orbit::setElements(Vector6 keplerianElements) { _keplerianElements = keplerianElements; regenerateVertices(); } float Orbit::getEccentricAnomaly(const float meanAnomaly) { const float eccentricity = _keplerianElements[astro::eccentricityIndex]; float eccentricAnomaly = astro::convertEllipticalMeanAnomalyToEccentricAnomaly( eccentricity, meanAnomaly, (float)10e-3, 100); return eccentricAnomaly; } // Interpolate a position around the orbit. // t is in range 0..1 and wraps. glm::vec3 Orbit::getPosition(const float meanAnomaly) { Vector6 cartesian = getCartesianCoordinates(meanAnomaly); return glm::vec3( cartesian[astro::xPositionIndex], cartesian[astro::yPositionIndex], 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) { float epsilon = 0.01; glm::vec3 ahead = getPosition(meanAnomaly + epsilon); glm::vec3 behind = getPosition(meanAnomaly - epsilon); return glm::normalize(ahead - behind); } void Orbit::render() { glBindVertexArray(_vao); glBindBuffer(GL_ARRAY_BUFFER, _vbo); glDrawArrays(GL_LINE_LOOP, 0, _vertices.size() / 3); } Orbit::~Orbit() { glDeleteVertexArrays(1, &_vao); glDeleteBuffers(1, &_vbo); }