Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Densely sampling orbit of parent planet if on its moon #4013

Merged
merged 5 commits into from
Dec 24, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions src/core/modules/Planet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4876,9 +4876,12 @@ void Planet::drawOrbit(const StelCore* core)
if (!hasValidPositionalData(lastJDE, PositionQuality::OrbitPlotting))
return;
}

// Update the orbit positions to the current planet date.
computeOrbit();
bool fromMoonPerspective = false;
if (core->getCurrentPlanet()->pType == isMoon || core->getCurrentPlanet()->pType == isObserver) // if I am a moon or observer of a planet
{
// only if we are also drawing my parent
fromMoonPerspective = core->getCurrentPlanet()->getParent() == this;
}

const StelProjectorP prj = core->getProjection(StelCore::FrameHeliocentricEclipticJ2000);
KeplerOrbit *keplerOrbit=static_cast<KeplerOrbit*>(orbitPtr);
Expand All @@ -4890,13 +4893,44 @@ void Planet::drawOrbit(const StelCore* core)

sPainter.setColor(getCurrentOrbitColor(), orbitFader.getInterstate());
Vec3d onscreen;

if (fromMoonPerspective) {
alex-w marked this conversation as resolved.
Show resolved Hide resolved
double dateJDE = lastJDE;
double calc_date;

Vec3d myPos = core->getCurrentPlanet()->getHeliocentricEclipticPos(dateJDE);
Vec3d myparentPos = getHeliocentricEclipticPos(dateJDE);
// orbital plane normal of parent planet, computed with the pos ~quarter of the orbit later
Vec3d orbitalNormal = myparentPos ^ getHeliocentricEclipticPos(dateJDE + deltaOrbitJDE*ORBIT_SEGMENTS/4);
orbitalNormal.normalize();
// project myPos into the orbital plane of parent planet using the normal of orbital plane
Vec3d myPosProjected = myPos - myPos.dot(orbitalNormal) * orbitalNormal;
// angle between myPos already projected onto the orbital plane of parent planet and the plane
// we should concentrate on this theta when sampling orbit
double theta = (atan2((myparentPos ^ myPosProjected).dot(orbitalNormal), myparentPos.dot(myPosProjected))) / M_PI;

double f;
alex-w marked this conversation as resolved.
Show resolved Hide resolved
for(int d = 0; d < ORBIT_SEGMENTS; d++)
{
f = (d - ORBIT_SEGMENTS/2.) / (ORBIT_SEGMENTS/2.);
// make sure only sample half of the orbit forward and half backward
// the sampling spacing is trial and error, but power of 13 seems to be good (i.e., densely sample around the current date)
calc_date = dateJDE + pow(f, 13)*deltaOrbitJDE*ORBIT_SEGMENTS/2. + theta*deltaOrbitJDE*ORBIT_SEGMENTS/2;
orbit[d] = getEclipticPos(calc_date);
}
}
else {
alex-w marked this conversation as resolved.
Show resolved Hide resolved
// Update the orbit positions to the current planet date.
computeOrbit();
}
alex-w marked this conversation as resolved.
Show resolved Hide resolved
const Vec3d savePos = orbit[ORBIT_SEGMENTS/2];
if (closeOrbit)
{
if (!keplerOrbit || keplerOrbit->getEccentricity()<=0.3)
if ((!keplerOrbit || keplerOrbit->getEccentricity()<=0.3) && !fromMoonPerspective) {
alex-w marked this conversation as resolved.
Show resolved Hide resolved
// special case - use current Planet position as center vertex so that draws
// on its orbit all the time (since orbit is shown as segmented rather than smooth curve)
orbit[ORBIT_SEGMENTS/2]=getHeliocentricEclipticPos()+aberrationPush;
}
alex-w marked this conversation as resolved.
Show resolved Hide resolved
orbit[ORBIT_SEGMENTS]=orbit[0];
}
int nbIter = closeOrbit ? ORBIT_SEGMENTS : ORBIT_SEGMENTS-1;
Expand Down
Loading