feat: update orbit based on current velocity

wip: planet position is not conserved
This commit is contained in:
Cat Flynn 2024-09-24 00:46:46 +01:00
parent 30ddb673ca
commit 788b03b2c6
6 changed files with 135 additions and 14 deletions

View File

@ -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;
}; };

View File

@ -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;

View File

@ -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

View File

@ -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);
} }

View File

@ -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

View File

@ -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