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

Nomenclature plot fixes #3342

Merged
merged 13 commits into from
Aug 6, 2023
7 changes: 5 additions & 2 deletions guide/ch_interface.tex
Original file line number Diff line number Diff line change
Expand Up @@ -684,10 +684,13 @@ \subsection{The Solar System Objects (SSO) Tab}
\item[Show planetary nomenclature] displays positions and names of
surface features officially named by the IAU (See
Appendix~\ref{ch:Nomenclature}). When the sun is below the horizon
at the location of the feature, the label is attenuated. Features like
craters are best visible when they are illuminated by a low sun.
at the location of the feature, the label is attenuated. A few special markers
show Centre, North and South poles, east and west points along the equator,
and the subsolar point (where the sun is at the zenith as seen from that feature).
Features like craters are best visible when they are illuminated by a low sun.
You can therefore limit the display\newFeature{1.2} to items along the
\indexterm{terminator} (the border between light and dark on the surface).
You can also\newFeature{23.3} mark craters and lunar \emph{maria} (the dark ``seas'') with circles.
\item[GRS details\ldots]: The Great Red Spot (GRS) is slowly
drifting along Jupiter's System~II coordinate system. This button
opens a new dialog in which you can adjust the longitude (Jupiter system~II)
Expand Down
Binary file modified guide/pictures/view_dialog_sso_tab.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions src/core/StelPainter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1681,6 +1681,43 @@ void StelPainter::drawCircle(float x, float y, float r)
enableClientStates(false);
}

// rx: radius in x axis
// ry: radius in y axis
// angle rotation (counterclockwise), radians [0..2pi]
void StelPainter::drawEllipse(double x, double y, double rX, double rY, double angle)
{
if (rX <= 1.0 || rY <= 1.0)
return;
// Taken largely from Nebula::renderEllipticMarker()
const double scale = StelApp::getInstance().getGlobalScalingRatio();
rX *= scale;
rY *= scale;

//const float radiusY = 0.35 * size;
//const float radiusX = aspectRatio * radiusY;
const int numPoints = std::lround(std::clamp(qMax(rX, rY)/3, 32., 1024.));
std::vector<float> vertexData;
vertexData.reserve(numPoints*2);
const float*const cossin = StelUtils::ComputeCosSinTheta(numPoints);
const auto cosa = std::cos(angle);
const auto sina = std::sin(angle);
for(int n = 0; n < numPoints; ++n)
{
const auto cosb = cossin[2*n], sinb = cossin[2*n+1];
const auto pointX = rX*sinb;
const auto pointY = rY*cosb;
vertexData.push_back(x + pointX*cosa - pointY*sina);
vertexData.push_back(y + pointY*cosa + pointX*sina);
}
const auto vertCount = vertexData.size() / 2;
setLineSmooth(true);
setLineWidth(scale * std::clamp(qMax(rX, rY)/40, 1., 2.));
enableClientStates(true);
setVertexPointer(2, GL_FLOAT, vertexData.data());
drawFromArray(StelPainter::LineLoop, vertCount, 0, false);
enableClientStates(false);
}

void StelPainter::drawSprite2dMode(float x, float y, float radius)
{
static float vertexData[] = {-10.,-10.,10.,-10., 10.,10., -10.,10.};
Expand Down
6 changes: 6 additions & 0 deletions src/core/StelPainter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ class StelPainter : protected QOpenGLFunctions
//! Draw a simple circle, 2d viewport coordinates in pixel
void drawCircle(float x, float y, float r);

//! Draw a simple ellipse, 2d viewport coordinates in pixel
//! @param rx: radius in x axis
//! @param ry: radius in y axis
//! @param angle: rotation (counterclockwise), radians [0..2pi]
void drawEllipse(double x, double y, double rx, double ry, double angle);

//! Draw a square using the current texture at the given projected 2d position.
//! This method is not thread safe.
//! @param x x position in the viewport in pixel.
Expand Down
76 changes: 55 additions & 21 deletions src/core/modules/NomenclatureItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
*/

#include "NomenclatureItem.hpp"
#include "StelModuleMgr.hpp"
#include "StelMovementMgr.hpp"
#include "StelObject.hpp"
#include "StelObserver.hpp"
#include "StelPainter.hpp"
#include "StelApp.hpp"
#include "StelCore.hpp"
Expand All @@ -28,6 +31,7 @@

const QString NomenclatureItem::NOMENCLATURE_TYPE = QStringLiteral("NomenclatureItem");
Vec3f NomenclatureItem::color = Vec3f(0.1f,1.0f,0.1f);
bool NomenclatureItem::flagOutlineCraters = false;
bool NomenclatureItem::hideLocalNomenclature = false;
bool NomenclatureItem::showTerminatorZoneOnly = false;
int NomenclatureItem::terminatorMinAltitude=-2;
Expand Down Expand Up @@ -342,7 +346,7 @@ Vec3d NomenclatureItem::getJ2000EquatorialPos(const StelCore* core) const
return XYZ;
}

// Return apparent semidiameter
// Return apparent semidiameter in degrees
double NomenclatureItem::getAngularRadius(const StelCore* core) const
{
return std::atan2(0.5*size*planet->getSphereScale()/AU, getJ2000EquatorialPos(core).norm()) * M_180_PI;
Expand All @@ -355,46 +359,76 @@ float NomenclatureItem::getAngularDiameterRatio(const StelCore *core) const

void NomenclatureItem::draw(StelCore* core, StelPainter *painter)
{
// show special points only?
if (getFlagShowSpecialNomenclatureOnly() && nType<NomenclatureItem::niSpecialPointPole)
return;

if (getFlagHideLocalNomenclature() && planet==core->getCurrentPlanet())
return;

// Called by NomenclatureMgr, so we don't need to check if labelsFader is true.
// The painter has been set to enable blending.
const Vec3d equPos = planet->getJ2000EquatorialPos(core);
Vec3d XYZ = getJ2000EquatorialPos(core);
const Vec3d XYZ = getJ2000EquatorialPos(core);

// In case we are located at a labeled site, don't show this label or any labels within 150 km. Else we have bad flicker...
if (XYZ.normSquared() < 150.*150.*AU_KM*AU_KM )
return;

if (getFlagHideLocalNomenclature())
{
// Check the state when needed only!
if (planet==core->getCurrentPlanet())
return;
}
const double screenRadius = getAngularRadius(core)*M_PI_180*static_cast<double>(painter->getProjector()->getPixelPerRadAtCenter());

// We can use ratio of angular size to the FOV to checking visibility of features also!
// double scale = getAngularSize(core)/painter->getProjector()->getFov();
// if (painter->getProjector()->projectCheck(XYZ, srcPos) && (dist >= XYZ.length()) && (scale>0.04 && scale<0.5))

// check visibility of feature
Vec3d srcPos;
const float scale = getAngularDiameterRatio(core);
NomenclatureItem::NomenclatureItemType niType = getNomenclatureType();

if (getFlagShowSpecialNomenclatureOnly())
{
// show special points only
if (niType<NomenclatureItem::niSpecialPointPole)
return;
}

if (painter->getProjector()->projectCheck(XYZ, srcPos) && (equPos.normSquared() >= XYZ.normSquared())
&& (scale>0.04f && (scale<0.5f || niType>=NomenclatureItem::niSpecialPointPole )))
&& (scale>0.04f && (scale<0.5f || nType>=NomenclatureItem::niSpecialPointPole )))
{
const float solarAltitude=getSolarAltitude(core);
// Throw out real items if not along the terminator?
if ( (niType<NomenclatureItem::niSpecialPointPole) && showTerminatorZoneOnly && (solarAltitude > terminatorMaxAltitude || solarAltitude < terminatorMinAltitude) )
if ( (nType<NomenclatureItem::niSpecialPointPole) && showTerminatorZoneOnly && (solarAltitude > terminatorMaxAltitude || solarAltitude < terminatorMinAltitude) )
return;
float brightness=(solarAltitude<0. ? 0.25f : 1.0f);
if (niType>=NomenclatureItem::niSpecialPointPole)
brightness = 0.5f;
const float brightness=(nType>=NomenclatureItem::niSpecialPointPole ? 0.5f : (solarAltitude<0. ? 0.25f : 1.0f));
painter->setColor(color*brightness, labelsFader.getInterstate());
painter->drawCircle(static_cast<float>(srcPos[0]), static_cast<float>(srcPos[1]), 2.f);
// Highlight a few mostly circular classes with ellipses:
// - Craters
// - Satellite features (presumably all of these are satellite craters)
// - Lunar Maria. Mare Frigoris is elongated, and an ellipse would look stupid.
if (flagOutlineCraters && (nType==niCrater || nType==niSatelliteFeature || (nType==niMare && englishName!="Mare Frigoris")))
{
// Compute aspectRatio and angle from position of planet and own position, parallactic angle, ...
const double distDegrees=equPos.angle(XYZ)*M_180_PI; // angular distance from planet centre position
const double plRadiusDeg=planet->getAngularRadius(core);
const double sinDistCenter= distDegrees/plRadiusDeg; // should be 0...1
if (sinDistCenter<0.9999) // exclude any edge ellipses which would be hanging over the limb.
{
const double angleDistCenterRad=asin(qMin(0.9999, sinDistCenter)); // 0..pi/2 on the lunar/planet sphere
const double aspectRatio=cos(angleDistCenterRad);
// Exclude further ellipses which would overshoot limb.
if (getAngularRadius(core)*qMax(0.0001,aspectRatio)+distDegrees < plRadiusDeg )
{
const Vec3d equPosNow = planet->getEquinoxEquatorialPos(core);
const Vec3d XYZNow = getEquinoxEquatorialPos(core);
double ra, de, raPl, dePl;
StelUtils::rectToSphe(&ra, &de, XYZNow);
StelUtils::rectToSphe(&raPl, &dePl, equPosNow);
double dRA=StelUtils::fmodpos(ra-raPl, 2.*M_PI);
if(dRA>M_PI)
dRA-=2.*M_PI;
const double angle=atan2(dRA, de-dePl);
StelMovementMgr::MountMode mountMode=GETSTELMODULE(StelMovementMgr)->getMountMode();
const double par = mountMode==StelMovementMgr::MountAltAzimuthal ? static_cast<double>(getParallacticAngle(core)) : 0.;
painter->drawEllipse(srcPos[0], srcPos[1], screenRadius, screenRadius*qMax(0.0001,aspectRatio), angle-par );
}
}
//else
// qWarning() << "Sine of Distance" << sinDistCenter << ">0.99975 encountered for crater " << englishName << "at " << longitude << "/" << latitude;
}
painter->drawText(static_cast<float>(srcPos[0]), static_cast<float>(srcPos[1]), nameI18n, 0, 5.f, 5.f, false);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/core/modules/NomenclatureItem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class NomenclatureItem : public StelObject
mutable Vec3d XYZ; // holds J2000 position in space (i.e. including planet position, offset from planetocenter)
mutable double jde; // jde time of XYZ value
static Vec3f color;
static bool flagOutlineCraters; // draw craters and satellite features as ellipses?
static bool hideLocalNomenclature;
static bool showTerminatorZoneOnly;
static int terminatorMinAltitude;
Expand Down
55 changes: 33 additions & 22 deletions src/core/modules/NomenclatureMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
NomenclatureMgr::NomenclatureMgr() : StelObjectModule()
{
setObjectName("NomenclatureMgr");
conf = StelApp::getInstance().getSettings();
font.setPixelSize(StelApp::getInstance().getScreenFontSize());
connect(&StelApp::getInstance(), SIGNAL(screenFontSizeChanged(int)), this, SLOT(setFontSize(int)));
ssystem = GETSTELMODULE(SolarSystem);
Expand All @@ -66,12 +65,14 @@ void NomenclatureMgr::init()
loadNomenclature();
loadSpecialNomenclature();

setColor(Vec3f(conf->value("color/planet_nomenclature_color", "0.1,1.0,0.1").toString()));
setFlagShowNomenclature(conf->value("astro/flag_planets_nomenclature", false).toBool());
setFlagShowTerminatorZoneOnly(conf->value("astro/flag_planets_nomenclature_terminator_only", false).toBool());
setTerminatorMinAltitude(conf->value("astro/planet_nomenclature_solar_altitude_min", -5).toInt());
setTerminatorMaxAltitude(conf->value("astro/planet_nomenclature_solar_altitude_max", 40).toInt());
setFlagHideLocalNomenclature(conf->value("astro/flag_hide_local_nomenclature", true).toBool());
QSettings *conf = StelApp::getInstance().getSettings();
setColor(Vec3f( conf->value("color/planet_nomenclature_color", "0.1,1.0,0.1").toString()));
setFlagShowNomenclature( conf->value("astro/flag_planets_nomenclature", false).toBool());
setFlagShowTerminatorZoneOnly( conf->value("astro/flag_planets_nomenclature_terminator_only", false).toBool());
setTerminatorMinAltitude( conf->value("astro/planet_nomenclature_solar_altitude_min", -5).toInt());
setTerminatorMaxAltitude( conf->value("astro/planet_nomenclature_solar_altitude_max", 40).toInt());
setFlagOutlineCraters( conf->value("astro/flag_planets_nomenclature_outline_craters", false).toBool());
setFlagHideLocalNomenclature( conf->value("astro/flag_hide_local_nomenclature", true).toBool());
setFlagShowSpecialNomenclatureOnly(conf->value("astro/flag_special_nomenclature_only", false).toBool());

GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this);
Expand Down Expand Up @@ -188,7 +189,7 @@ void NomenclatureMgr::loadNomenclature()
QString name, planet = "", planetName = "", context = "";
NomenclatureItem::NomenclatureItemType ntype;
double latitude, longitude, size;
QStringList faultPlanets;
QStringList missingPlanets;

while (!buf.atEnd())
{
Expand All @@ -205,11 +206,9 @@ void NomenclatureMgr::loadNomenclature()
qWarning() << "ERROR - cannot parse record at line" << lineNumber << "in surface nomenclature file" << QDir::toNativeSeparators(surfNamesFile);
else
{
// Read the planet name
// Read planet name, feature ID, context
planet = recMatch.captured(1).trimmed();
// Read the ID of feature
featureId = recMatch.captured(2).toInt();
// Read the name of feature and context
QString ctxt = recMatch.captured(3).trimmed();
QRegularExpressionMatch ctxMatch=ctxRx.match(ctxt);
if (ctxMatch.hasMatch())
Expand All @@ -225,11 +224,9 @@ void NomenclatureMgr::loadNomenclature()
// Read the type of feature
QString ntypecode = recMatch.captured(4).trimmed();
ntype = NomenclatureItem::getNomenclatureItemType(ntypecode.toUpper());
// Read the latitude of feature
// Read lat/long/size of feature
latitude = recMatch.captured(5).toDouble();
// Read the longitude of feature
longitude = recMatch.captured(6).toDouble();
// Read the size of feature
size = recMatch.captured(7).toDouble();

if (planetName.isEmpty() || planet!=planetName)
Expand All @@ -249,17 +246,17 @@ void NomenclatureMgr::loadNomenclature()
readOk++;
}
else
faultPlanets << planet;
missingPlanets.append(planet);
}
}

buf.close();
qDebug() << "Loaded" << readOk << "/" << totalRecords << "items of planetary surface nomenclature";

faultPlanets.removeDuplicates();
int err = faultPlanets.size();
if (err>0)
qDebug().noquote() << "WARNING - These planets to assign nomenclature items were not found:" << faultPlanets.join(", ");
missingPlanets.removeDuplicates();
if (!missingPlanets.isEmpty())
// Nothing to worry about - We still don't include all objects.
qInfo() << "INFO: Cannot find these planetary objects to assign nomenclature items:" << missingPlanets.join(", ");
}
}

Expand Down Expand Up @@ -516,7 +513,7 @@ void NomenclatureMgr::setFlagShowTerminatorZoneOnly(bool b)
if (b!=NomenclatureItem::showTerminatorZoneOnly)
{
NomenclatureItem::showTerminatorZoneOnly=b;
conf->setValue("astro/flag_planets_nomenclature_terminator_only", b);
StelApp::immediateSave("astro/flag_planets_nomenclature_terminator_only", b);
emit flagShowTerminatorZoneOnlyChanged(b);
}
}
Expand All @@ -532,7 +529,7 @@ void NomenclatureMgr::setTerminatorMinAltitude(int deg)
if (deg!=NomenclatureItem::terminatorMinAltitude)
{
NomenclatureItem::terminatorMinAltitude=qBound(-90, deg, 90);
conf->setValue("astro/planet_nomenclature_solar_altitude_min", NomenclatureItem::terminatorMinAltitude);
StelApp::immediateSave("astro/planet_nomenclature_solar_altitude_min", NomenclatureItem::terminatorMinAltitude);
emit terminatorMinAltitudeChanged(NomenclatureItem::terminatorMinAltitude);
}
}
Expand All @@ -548,7 +545,7 @@ void NomenclatureMgr::setTerminatorMaxAltitude(int deg)
if (deg!=NomenclatureItem::terminatorMaxAltitude)
{
NomenclatureItem::terminatorMaxAltitude=qBound(-90, deg, 90);
conf->setValue("astro/planet_nomenclature_solar_altitude_max", NomenclatureItem::terminatorMaxAltitude);
StelApp::immediateSave("astro/planet_nomenclature_solar_altitude_max", NomenclatureItem::terminatorMaxAltitude);
emit terminatorMaxAltitudeChanged(NomenclatureItem::terminatorMaxAltitude);
}
}
Expand All @@ -558,9 +555,22 @@ int NomenclatureMgr::getTerminatorMaxAltitude() const
return NomenclatureItem::terminatorMaxAltitude;
}

void NomenclatureMgr::setFlagOutlineCraters(bool b)
{
NomenclatureItem::flagOutlineCraters = b;
StelApp::immediateSave("astro/flag_planets_nomenclature_outline_craters", b);
emit flagOutlineCratersChanged(b);
}

bool NomenclatureMgr::getFlagOutlineCraters() const
{
return NomenclatureItem::flagOutlineCraters;
}

void NomenclatureMgr::setFlagHideLocalNomenclature(bool b)
{
NomenclatureItem::hideLocalNomenclature = b;
StelApp::immediateSave("astro/flag_hide_local_nomenclature", b);
emit localNomenclatureHidingChanged(b);
}

Expand All @@ -572,6 +582,7 @@ bool NomenclatureMgr::getFlagHideLocalNomenclature() const
void NomenclatureMgr::setFlagShowSpecialNomenclatureOnly(bool b)
{
NomenclatureItem::showSpecialNomenclatureOnly = b;
StelApp::immediateSave("astro/flag_special_nomenclature_only", b);
emit specialNomenclatureOnlyDisplayingChanged(b);
}

Expand Down
8 changes: 7 additions & 1 deletion src/core/modules/NomenclatureMgr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class NomenclatureMgr : public StelObjectModule
Q_PROPERTY(bool flagShowTerminatorZoneOnly READ getFlagShowTerminatorZoneOnly WRITE setFlagShowTerminatorZoneOnly NOTIFY flagShowTerminatorZoneOnlyChanged)
Q_PROPERTY(int terminatorMinAltitude READ getTerminatorMinAltitude WRITE setTerminatorMinAltitude NOTIFY terminatorMinAltitudeChanged)
Q_PROPERTY(int terminatorMaxAltitude READ getTerminatorMaxAltitude WRITE setTerminatorMaxAltitude NOTIFY terminatorMaxAltitudeChanged)
Q_PROPERTY(bool flagOutlineCraters READ getFlagOutlineCraters WRITE setFlagOutlineCraters NOTIFY flagOutlineCratersChanged)
Q_PROPERTY(bool flagHideLocalNomenclature READ getFlagHideLocalNomenclature WRITE setFlagHideLocalNomenclature NOTIFY localNomenclatureHidingChanged)
Q_PROPERTY(bool specialNomenclatureOnlyDisplayed READ getFlagShowSpecialNomenclatureOnly WRITE setFlagShowSpecialNomenclatureOnly NOTIFY specialNomenclatureOnlyDisplayingChanged)
Q_PROPERTY(Vec3f nomenclatureColor READ getColor WRITE setColor NOTIFY nomenclatureColorChanged)
Expand Down Expand Up @@ -119,6 +120,11 @@ public slots:
//! Get maximum solar altitude (degrees) to draw only nomenclature along the terminator.
int getTerminatorMaxAltitude() const;

//! Set flag which determines if craters and satellite features (which are usually also craters) are outlined as ellipses.
void setFlagOutlineCraters(bool b);
//! Get the current value of the flag which determines if craters and satellite features (which are usually also craters) are outlined as ellipses.
bool getFlagOutlineCraters() const;

//! Set flag which determines if nomenclature labels are drawn or hidden on the celestial body of observer.
void setFlagHideLocalNomenclature(bool b);
//! Get the current value of the flag which determines if nomenclature labels are drawn or hidden on the celestial body of observer.
Expand All @@ -139,6 +145,7 @@ public slots:
void flagShowTerminatorZoneOnlyChanged(bool b);
void terminatorMinAltitudeChanged(int deg);
void terminatorMaxAltitudeChanged(int deg);
void flagOutlineCratersChanged(bool b);
void localNomenclatureHidingChanged(bool b);
void specialNomenclatureOnlyDisplayingChanged(bool b);
void nomenclatureColorChanged(const Vec3f & color) const;
Expand All @@ -157,7 +164,6 @@ private slots:

// Font used for displaying our text
QFont font;
QSettings* conf;
StelTextureSP texPointer;
QMultiHash<PlanetP, NomenclatureItemP> nomenclatureItems;
};
Expand Down
1 change: 1 addition & 0 deletions src/gui/ConfigurationDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,7 @@ void ConfigurationDialog::saveAllSettings()
conf->setValue("astro/flag_show_obj_self_shadows", propMgr->getStelPropertyValue("SolarSystem.flagShowObjSelfShadows").toBool());
conf->setValue("astro/apparent_magnitude_algorithm", Planet::getApparentMagnitudeAlgorithmString());
conf->setValue("astro/flag_planets_nomenclature", propMgr->getStelPropertyValue("NomenclatureMgr.flagShowNomenclature").toBool());
conf->setValue("astro/flag_planets_nomenclature_outline_craters",propMgr->getStelPropertyValue("NomenclatureMgr.flagOutlineCraters").toBool());
conf->setValue("astro/flag_hide_local_nomenclature", propMgr->getStelPropertyValue("NomenclatureMgr.flagHideLocalNomenclature").toBool());
conf->setValue("astro/flag_special_nomenclature_only", propMgr->getStelPropertyValue("NomenclatureMgr.specialNomenclatureOnlyDisplayed").toBool());
conf->setValue("astro/flag_planets_nomenclature_terminator_only",propMgr->getStelPropertyValue("NomenclatureMgr.flagShowTerminatorZoneOnly").toBool());
Expand Down