feat: update orbit based on current velocity
wip: planet position is not conserved
This commit is contained in:
parent
30ddb673ca
commit
788b03b2c6
|
@ -25,14 +25,20 @@ public:
|
||||||
void setLongitudeOfAscendingNode(double longitudeOfAscendingNode);
|
void setLongitudeOfAscendingNode(double longitudeOfAscendingNode);
|
||||||
|
|
||||||
glm::dvec3 getPosition(double gravitationalParameter, double time) const;
|
glm::dvec3 getPosition(double gravitationalParameter, double time) const;
|
||||||
glm::dvec3 getPositionFromMeanAnomaly(double meanAnomaly) const;
|
glm::dvec3 getPositionFromMeanAnomaly(double meanAnomaly, double gravitationalParameter) const;
|
||||||
|
|
||||||
|
glm::dvec3 getVelocity(double gravitationalParameter, double time) const;
|
||||||
|
glm::dvec3 getVelocityFromMeanAnomaly(double meanAnomaly, double gravitationalParameter) const;
|
||||||
|
|
||||||
//glm::dvec3 getTangent(const double meanAnomaly) const;
|
//glm::dvec3 getTangent(const double meanAnomaly) const;
|
||||||
//glm::mat4 getLookAlongMatrix(const double meanAnomaly) const;
|
//glm::mat4 getLookAlongMatrix(const double meanAnomaly) const;
|
||||||
|
|
||||||
|
const Vector6 getCartesianCoordinates(const double meanAnomaly, const double gravitationalParameter) const;
|
||||||
|
const double getMeanAnomaly(const double gravitationalParameter, const double time) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector6 _keplerianElements;
|
Vector6 _keplerianElements;
|
||||||
|
|
||||||
const double getEccentricAnomaly(const double meanAnomaly) const;
|
const double getEccentricAnomaly(const double meanAnomaly) const;
|
||||||
const double getTrueAnomaly(const double meanAnomaly) const;
|
const double getTrueAnomaly(const double meanAnomaly) const;
|
||||||
const Vector6 getCartesianCoordinates(const double meanAnomaly) const;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,11 +15,14 @@ class ParticleMap
|
||||||
// is just done for setup
|
// is just done for setup
|
||||||
const Particle& getParticle(const std::string& id) const;
|
const Particle& getParticle(const std::string& id) const;
|
||||||
const Particle& getParent(const std::string& id) const;
|
const Particle& getParent(const std::string& id) const;
|
||||||
|
glm::dvec3 getParticleLocalPosition(const std::string& id, double time) const;
|
||||||
glm::dvec3 getParticlePosition(const std::string& id, double time) const;
|
glm::dvec3 getParticlePosition(const std::string& id, double time) const;
|
||||||
|
glm::dvec3 getParticleLocalVelocity(const std::string& id, double time) const;
|
||||||
const Orbit& getOrbit(const std::string& id) const;
|
const Orbit& getOrbit(const std::string& id) const;
|
||||||
|
|
||||||
void setParticle(const Particle& particle);
|
void setParticle(const Particle& particle);
|
||||||
void setRelationship(const std::string& parentId, const std::string& childId, const Orbit& orbit);
|
void setRelationship(const std::string& parentId, const std::string& childId, const Orbit& orbit);
|
||||||
|
void setParticleLocalVelocity(const std::string& id, const double& time, const glm::dvec3& velocity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, Particle> _particles;
|
std::map<std::string, Particle> _particles;
|
||||||
|
|
|
@ -88,9 +88,9 @@ const double Orbit::getEccentricAnomaly(const double meanAnomaly) const
|
||||||
return eccentricAnomaly;
|
return eccentricAnomaly;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::dvec3 Orbit::getPositionFromMeanAnomaly(const double meanAnomaly) const
|
glm::dvec3 Orbit::getPositionFromMeanAnomaly(const double meanAnomaly, double gravitationalParameter) const
|
||||||
{
|
{
|
||||||
Vector6 cartesian = getCartesianCoordinates(meanAnomaly);
|
Vector6 cartesian = getCartesianCoordinates(meanAnomaly, gravitationalParameter);
|
||||||
return glm::dvec3(
|
return glm::dvec3(
|
||||||
cartesian[astro::xPositionIndex],
|
cartesian[astro::xPositionIndex],
|
||||||
cartesian[astro::yPositionIndex],
|
cartesian[astro::yPositionIndex],
|
||||||
|
@ -98,10 +98,28 @@ glm::dvec3 Orbit::getPositionFromMeanAnomaly(const double meanAnomaly) const
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::dvec3 Orbit::getPosition(double gravitationalParameter, double time) const
|
glm::dvec3 Orbit::getPosition(double gravitationalParameter, double time) const
|
||||||
|
{
|
||||||
|
return getPositionFromMeanAnomaly(getMeanAnomaly(gravitationalParameter, time), gravitationalParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::dvec3 Orbit::getVelocityFromMeanAnomaly(const double meanAnomaly, double gravitationalParameter) const
|
||||||
|
{
|
||||||
|
Vector6 cartesian = getCartesianCoordinates(meanAnomaly, gravitationalParameter);
|
||||||
|
return glm::dvec3(
|
||||||
|
cartesian[astro::xVelocityIndex],
|
||||||
|
cartesian[astro::yVelocityIndex],
|
||||||
|
cartesian[astro::zVelocityIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::dvec3 Orbit::getVelocity(double gravitationalParameter, double time) const
|
||||||
|
{
|
||||||
|
return getVelocityFromMeanAnomaly(getMeanAnomaly(gravitationalParameter, time), gravitationalParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
const double Orbit::getMeanAnomaly(const double gravitationalParameter, const double time) const
|
||||||
{
|
{
|
||||||
double meanMotion = astro::computeKeplerMeanMotion(getSemiMajorAxis(), gravitationalParameter);
|
double meanMotion = astro::computeKeplerMeanMotion(getSemiMajorAxis(), gravitationalParameter);
|
||||||
double meanAnomaly = meanMotion * time;
|
return meanMotion * time;
|
||||||
return getPositionFromMeanAnomaly(meanAnomaly);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const double Orbit::getTrueAnomaly(const double meanAnomaly) const
|
const double Orbit::getTrueAnomaly(const double meanAnomaly) const
|
||||||
|
@ -113,11 +131,11 @@ const double Orbit::getTrueAnomaly(const double meanAnomaly) const
|
||||||
eccentricity);
|
eccentricity);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vector6 Orbit::getCartesianCoordinates(const double meanAnomaly) const
|
const Vector6 Orbit::getCartesianCoordinates(const double meanAnomaly, const double gravitationalParameter) const
|
||||||
{
|
{
|
||||||
Vector6 kepler(_keplerianElements);
|
Vector6 kepler(_keplerianElements);
|
||||||
kepler[astro::trueAnomalyIndex] = getTrueAnomaly(meanAnomaly);
|
kepler[astro::trueAnomalyIndex] = getTrueAnomaly(meanAnomaly);
|
||||||
return astro::convertKeplerianToCartesianElements(kepler, 1.0);
|
return astro::convertKeplerianToCartesianElements(kepler, gravitationalParameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
//glm::dvec3 Orbit::getTangent(const double meanAnomaly) const
|
//glm::dvec3 Orbit::getTangent(const double meanAnomaly) const
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "skein/particlemap.h"
|
#include "skein/particlemap.h"
|
||||||
#include "skein/particle.h"
|
#include "skein/particle.h"
|
||||||
|
#include "astro/orbitalElementConversions.hpp"
|
||||||
|
|
||||||
const Particle& ParticleMap::getParticle(const std::string& id) const
|
const Particle& ParticleMap::getParticle(const std::string& id) const
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,25 @@ const Orbit& ParticleMap::getOrbit(const std::string& id) const
|
||||||
return _orbits.at(id);
|
return _orbits.at(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::dvec3 ParticleMap::getParticleLocalPosition(const std::string& id, double time) const
|
||||||
|
{
|
||||||
|
if (_orbits.find(id) == _orbits.end())
|
||||||
|
return {0,0,0};
|
||||||
|
|
||||||
|
const Particle* particle = &(_particles.at(id));
|
||||||
|
glm::dvec3 pos(0,0,0);
|
||||||
|
|
||||||
|
//const std::string& id = particle->getId();
|
||||||
|
const std::string& parentId = _relationships.at(id);
|
||||||
|
const Particle& parent = _particles.at(parentId);
|
||||||
|
const double gravitationalParameter = parent.getGravitationalParameter();
|
||||||
|
const Orbit& orbit = _orbits.at(id);
|
||||||
|
|
||||||
|
pos += orbit.getPosition(gravitationalParameter, time);
|
||||||
|
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
glm::dvec3 ParticleMap::getParticlePosition(const std::string& id, double time) const
|
glm::dvec3 ParticleMap::getParticlePosition(const std::string& id, double time) const
|
||||||
{
|
{
|
||||||
if (_orbits.find(id) == _orbits.end())
|
if (_orbits.find(id) == _orbits.end())
|
||||||
|
@ -27,6 +47,7 @@ glm::dvec3 ParticleMap::getParticlePosition(const std::string& id, double time)
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
// TODO: this is shadowing a parameter with the same name
|
||||||
const std::string& id = particle->getId();
|
const std::string& id = particle->getId();
|
||||||
const std::string& parentId = _relationships.at(id);
|
const std::string& parentId = _relationships.at(id);
|
||||||
const Particle& parent = _particles.at(parentId);
|
const Particle& parent = _particles.at(parentId);
|
||||||
|
@ -49,6 +70,54 @@ glm::dvec3 ParticleMap::getParticlePosition(const std::string& id, double time)
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::dvec3 ParticleMap::getParticleLocalVelocity(const std::string& id, double time) const
|
||||||
|
{
|
||||||
|
if (_orbits.find(id) == _orbits.end())
|
||||||
|
return {0,0,0};
|
||||||
|
|
||||||
|
const Particle* particle = &(_particles.at(id));
|
||||||
|
glm::dvec3 vel(0,0,0);
|
||||||
|
|
||||||
|
//const std::string& id = particle->getId();
|
||||||
|
const std::string& parentId = _relationships.at(id);
|
||||||
|
const Particle& parent = _particles.at(parentId);
|
||||||
|
const double gravitationalParameter = parent.getGravitationalParameter();
|
||||||
|
const Orbit& orbit = _orbits.at(id);
|
||||||
|
|
||||||
|
vel += orbit.getVelocity(gravitationalParameter, time);
|
||||||
|
|
||||||
|
return vel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParticleMap::setParticleLocalVelocity(const std::string& id, const double& time, const glm::dvec3& velocity)
|
||||||
|
{
|
||||||
|
// we want to convert a local position and velocity into a new set of keplerian elements.
|
||||||
|
|
||||||
|
// first, get the local position of the e
|
||||||
|
const Orbit& orbit = _orbits.at(id);
|
||||||
|
const std::string& parentId = _relationships.at(id);
|
||||||
|
const Particle& parent = _particles.at(parentId);
|
||||||
|
const double gravitationalParameter = parent.getGravitationalParameter();
|
||||||
|
const double meanAnomaly = orbit.getMeanAnomaly(gravitationalParameter, time);
|
||||||
|
Vector6 cartesian(orbit.getCartesianCoordinates(meanAnomaly, gravitationalParameter));
|
||||||
|
|
||||||
|
// update velocity, leave position as it is
|
||||||
|
cartesian[astro::xVelocityIndex] = velocity.x;
|
||||||
|
cartesian[astro::yVelocityIndex] = velocity.y;
|
||||||
|
cartesian[astro::zVelocityIndex] = velocity.z;
|
||||||
|
|
||||||
|
const Vector6 keplerian = astro::convertCartesianToKeplerianElements(cartesian, gravitationalParameter);
|
||||||
|
|
||||||
|
Orbit newOrbit;
|
||||||
|
newOrbit.setSemiMajorAxis(keplerian[astro::semiMajorAxisIndex]);
|
||||||
|
newOrbit.setEccentricity(keplerian[astro::eccentricityIndex]);
|
||||||
|
newOrbit.setInclination(keplerian[astro::inclinationIndex]);
|
||||||
|
newOrbit.setArgumentOfPeriapsis(keplerian[astro::argumentOfPeriapsisIndex]);
|
||||||
|
newOrbit.setLongitudeOfAscendingNode(keplerian[astro::longitudeOfAscendingNodeIndex]);
|
||||||
|
|
||||||
|
setRelationship(parentId, id, newOrbit);
|
||||||
|
}
|
||||||
|
|
||||||
void ParticleMap::setParticle(const Particle& particle)
|
void ParticleMap::setParticle(const Particle& particle)
|
||||||
{
|
{
|
||||||
_particles.insert({particle.getId(), particle});
|
_particles.insert({particle.getId(), particle});
|
||||||
|
@ -58,6 +127,6 @@ void ParticleMap::setRelationship(const std::string& parentId, const std::string
|
||||||
{
|
{
|
||||||
// map children to parent - children can only have one parent, so we use the map to
|
// map children to parent - children can only have one parent, so we use the map to
|
||||||
// identify the parent directly using the child as the key
|
// identify the parent directly using the child as the key
|
||||||
_relationships.insert({childId, parentId});
|
_relationships.insert_or_assign(childId, parentId);
|
||||||
_orbits.insert({childId, orbit});
|
_orbits.insert_or_assign(childId, orbit);
|
||||||
}
|
}
|
||||||
|
|
31
src/main.cpp
31
src/main.cpp
|
@ -35,20 +35,23 @@
|
||||||
struct Input
|
struct Input
|
||||||
{
|
{
|
||||||
bool pauseTime;
|
bool pauseTime;
|
||||||
|
bool printCartesian;
|
||||||
} input;
|
} input;
|
||||||
|
|
||||||
|
|
||||||
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||||
{
|
{
|
||||||
if (key == GLFW_KEY_SPACE && action == GLFW_PRESS)
|
if (action == GLFW_PRESS)
|
||||||
{
|
{
|
||||||
input.pauseTime = true;
|
input.pauseTime = key == GLFW_KEY_SPACE;
|
||||||
|
input.printCartesian = key == GLFW_KEY_W;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearInput()
|
void clearInput()
|
||||||
{
|
{
|
||||||
input.pauseTime = false;
|
input.pauseTime = false;
|
||||||
|
input.printCartesian = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// now should always increase linearly with real world time, this should not be modified by input
|
// now should always increase linearly with real world time, this should not be modified by input
|
||||||
|
@ -69,6 +72,11 @@ void updateTime()
|
||||||
engineTime.now = now;
|
engineTime.now = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printVector(const glm::dvec3& vector)
|
||||||
|
{
|
||||||
|
std::cout << "(" << vector.x << ", " << vector.y << ", " << vector.z << ")";
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
GLFWwindow* window = nullptr;
|
GLFWwindow* window = nullptr;
|
||||||
|
@ -150,7 +158,24 @@ int main()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("maneouvre mode!\n");
|
if (input.printCartesian)
|
||||||
|
{
|
||||||
|
|
||||||
|
const glm::dvec3 p = map.getParticleLocalPosition("station", time);
|
||||||
|
printVector(p);
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
// TODO: what unit is this in lol
|
||||||
|
const glm::dvec3 v = map.getParticleLocalVelocity("station", time);
|
||||||
|
const glm::dvec3 newVelocity = v * 0.9;
|
||||||
|
|
||||||
|
printVector(v);
|
||||||
|
std::cout << " -> ";
|
||||||
|
printVector(newVelocity);
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
map.setParticleLocalVelocity("station", time, newVelocity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rendering
|
// rendering
|
||||||
|
|
|
@ -36,7 +36,7 @@ void OrbitVisualizer::regenerateVertices(const glm::vec3& basePos)
|
||||||
// better to actually create a first-class ellipse object and use that to generate
|
// better to actually create a first-class ellipse object and use that to generate
|
||||||
// a nice continuous mesh, instead of using orbital positions.
|
// a nice continuous mesh, instead of using orbital positions.
|
||||||
float t = (float)i / (float)_vertexCount * 2.0 * _pi;
|
float t = (float)i / (float)_vertexCount * 2.0 * _pi;
|
||||||
glm::vec3 pos = orbit.getPositionFromMeanAnomaly(t);
|
glm::vec3 pos = orbit.getPositionFromMeanAnomaly(t, 1);
|
||||||
pos += basePos;
|
pos += basePos;
|
||||||
|
|
||||||
// Vertices come out of the library with X and Y being in the 'flat' plane. Re-order them
|
// Vertices come out of the library with X and Y being in the 'flat' plane. Re-order them
|
||||||
|
|
Loading…
Reference in New Issue