109 lines
2.8 KiB
C++
109 lines
2.8 KiB
C++
#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);
|
|
}
|
|
|