Kstars

ksplanetbase.cpp
1/*
2 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "ksplanetbase.h"
8
9#include "ksnumbers.h"
10#include "kstarsdata.h"
11#include "ksutils.h"
12#include "Options.h"
13#include "skymap.h"
14#include "ksasteroid.h"
15#include "kscomet.h"
16#include "ksmoon.h"
17#include "ksplanet.h"
18#include "kssun.h"
19#include "texturemanager.h"
20#include "skycomponents/skymapcomposite.h"
21
22QVector<QColor> KSPlanetBase::planetColor = QVector<QColor>() << QColor("slateblue") << //Mercury
23 QColor("lightgreen") << //Venus
24 QColor("red") << //Mars
25 QColor("goldenrod") << //Jupiter
26 QColor("khaki") << //Saturn
27 QColor("lightseagreen") << //Uranus
28 QColor("skyblue") << //Neptune
29 QColor("grey") << //Pluto
30 QColor("yellow") << //Sun
31 QColor("white"); //Moon
32
36
37KSPlanetBase::KSPlanetBase(const QString &s, const QString &image_file, const QColor &c, double pSize)
38 : TrailObject(2, 0.0, 0.0, 0.0, s)
39{
40 init(s, image_file, c, pSize);
41}
42
43void KSPlanetBase::init(const QString &s, const QString &image_file, const QColor &c, double pSize)
44{
45 m_image = TextureManager::getImage(image_file);
46 PositionAngle = 0.0;
47 PhysicalSize = pSize;
48 m_Color = c;
49 setName(s);
50 setLongName(s);
51}
52
53KSPlanetBase *KSPlanetBase::createPlanet(int n)
54{
55 switch (n)
56 {
57 case KSPlanetBase::MERCURY:
58 case KSPlanetBase::VENUS:
59 case KSPlanetBase::MARS:
60 case KSPlanetBase::JUPITER:
61 case KSPlanetBase::SATURN:
62 case KSPlanetBase::URANUS:
63 case KSPlanetBase::NEPTUNE:
64 return new KSPlanet(n);
65 /*case KSPlanetBase::PLUTO:
66 return new KSPluto();
67 break;*/
68 case KSPlanetBase::SUN:
69 return new KSSun();
70 case KSPlanetBase::MOON:
71 return new KSMoon();
72 }
73 return nullptr;
74}
75
77{
78 findEcliptic(Obliquity, ep.longitude, ep.latitude);
79}
80
82{
83 setFromEcliptic(Obliquity, ep.longitude, ep.latitude);
84}
85
86void KSPlanetBase::updateCoords(const KSNumbers *num, bool includePlanets, const CachingDms *lat, const CachingDms *LST,
87 bool)
88{
89 KStarsData *kd = KStarsData::Instance();
90
91 if (kd == nullptr || !includePlanets)
92 return;
93
94 kd->skyComposite()->earth()->findPosition(num); //since we don't pass lat & LST, localizeCoords will be skipped
95
96 if (lat && LST)
97 {
98 findPosition(num, lat, LST, kd->skyComposite()->earth());
99 // Don't add to the trail this time
100 if (hasTrail())
101 Trail.takeLast();
102 }
103 else
104 {
105 findGeocentricPosition(num, kd->skyComposite()->earth());
106 }
107}
108
109void KSPlanetBase::findPosition(const KSNumbers *num, const CachingDms *lat, const CachingDms *LST,
110 const KSPlanetBase *Earth)
111{
112
113 lastPrecessJD = num->julianDay();
114
115 findGeocentricPosition(num, Earth); //private function, reimplemented in each subclass
116 findPhase();
117 setAngularSize(findAngularSize()); //angular size in arcmin
118
119 if (lat && LST)
120 localizeCoords(num, lat, LST); //correct for figure-of-the-Earth
121
122 if (hasTrail())
123 {
124 addToTrail(KStarsDateTime(num->getJD()).toString("yyyy.MM.dd hh:mm") +
125 i18nc("Universal time", "UT")); // TODO: Localize date/time format?
126 if (Trail.size() > TrailObject::MaxTrail)
127 clipTrail();
128 }
129
130 findMagnitude(num);
131
132 if (type() == SkyObject::COMET)
133 {
134 // Compute tail size
135 KSComet *me = static_cast<KSComet *>(this);
136 double comaAngSize;
137 // Convert the tail size in km to angular tail size (degrees)
138 comaAngSize = asin(physicalSize() / Rearth / AU_KM) * 60.0 * 180.0 / dms::PI;
139 // Find the apparent length as projected on the celestial sphere (the comet's tail points away from the sun)
140 me->setComaAngSize(comaAngSize * fabs(sin(phase().radians())));
141 }
142}
143
145{
146 if (name() == i18n("Mercury") || name() == i18n("Venus") || name() == i18n("Mars") || name() == i18n("Jupiter") ||
147 name() == i18n("Saturn") || name() == i18n("Uranus") || name() == i18n("Neptune"))
148 return true;
149 return false;
150}
151
152void KSPlanetBase::localizeCoords(const KSNumbers *num, const CachingDms *lat, const CachingDms *LST)
153{
154 //convert geocentric coordinates to local apparent coordinates (topocentric coordinates)
155 dms HA, HA2; //Hour Angle, before and after correction
156 double rsinp, rcosp, u, sinHA, cosHA, sinDec, cosDec, D;
157 double cosHA2;
158 double r = Rearth * AU_KM; //distance from Earth, in km
159 u = atan(0.996647 * tan(lat->radians()));
160 rsinp = 0.996647 * sin(u);
161 rcosp = cos(u);
162 HA.setD(LST->Degrees() - ra().Degrees());
163 HA.SinCos(sinHA, cosHA);
164 dec().SinCos(sinDec, cosDec);
165
166 D = atan2(rcosp * sinHA, r * cosDec / 6378.14 - rcosp * cosHA);
167 dms temp;
168 temp.setRadians(ra().radians() - D);
169 setRA(temp);
170
171 HA2.setD(LST->Degrees() - ra().Degrees());
172 cosHA2 = cos(HA2.radians());
173
174 //temp.setRadians( atan2( cosHA2*( r*sinDec/6378.14 - rsinp ), r*cosDec*cosHA/6378.14 - rcosp ) );
175 // The atan2() version above makes the planets move crazy in the htm branch -jbb
176 temp.setRadians(atan(cosHA2 * (r * sinDec / 6378.14 - rsinp) / (r * cosDec * cosHA / 6378.14 - rcosp)));
177
178 setDec(temp);
179
180 //Make sure Dec is between -90 and +90
181 if (dec().Degrees() > 90.0)
182 {
183 setDec(180.0 - dec().Degrees());
184 setRA(ra().Hours() + 12.0);
185 ra().reduce();
186 }
187 if (dec().Degrees() < -90.0)
188 {
189 setDec(180.0 + dec().Degrees());
190 setRA(ra().Hours() + 12.0);
191 ra().reduce();
192 }
193
195}
196
198{
199 double sinL, sinB, sinL0, sinB0;
200 double cosL, cosB, cosL0, cosB0;
201 double x, y, z;
202
203 //The Moon's Rearth is set in its findGeocentricPosition()...
204 if (name() == i18n("Moon"))
205 {
206 return;
207 }
208
209 if (name() == i18n("Earth"))
210 {
211 Rearth = 0.0;
212 return;
213 }
214
215 if (!Earth)
216 {
217 qDebug() << Q_FUNC_INFO << "KSPlanetBase::setRearth(): Error: Need an Earth pointer. (" << name() << ")";
218 Rearth = 1.0;
219 return;
220 }
221
222 Earth->ecLong().SinCos(sinL0, cosL0);
223 Earth->ecLat().SinCos(sinB0, cosB0);
224 double eX = Earth->rsun() * cosB0 * cosL0;
225 double eY = Earth->rsun() * cosB0 * sinL0;
226 double eZ = Earth->rsun() * sinB0;
227
228 helEcLong().SinCos(sinL, cosL);
229 helEcLat().SinCos(sinB, cosB);
230 x = rsun() * cosB * cosL - eX;
231 y = rsun() * cosB * sinL - eY;
232 z = rsun() * sinB - eZ;
233
234 Rearth = sqrt(x * x + y * y + z * z);
235
236 //Set angular size, in arcmin
237 AngularSize = asin(PhysicalSize / Rearth / AU_KM) * 60. * 180. / dms::PI;
238}
239
241{
242 //Determine position angle of planet (assuming that it is aligned with
243 //the Ecliptic, which is only roughly correct).
244 //Displace a point along +Ecliptic Latitude by 1 degree
245 SkyPoint test;
246 dms newELat(ecLat().Degrees() + 1.0);
247 test.setFromEcliptic(num->obliquity(), ecLong(), newELat);
248 double dx = ra().Degrees() - test.ra().Degrees();
249 double dy = test.dec().Degrees() - dec().Degrees();
250 double pa;
251 if (dy)
252 {
253 pa = atan2(dx, dy) * 180.0 / dms::PI;
254 }
255 else
256 {
257 pa = dx < 0 ? 90.0 : -90.0;
258 }
259 setPA(pa);
260}
261
263{
264 double size = angSize() * dms::PI * Options::zoomFactor() / 10800.0;
265
266 //Determine minimum size for offset
267 double minsize = 4.;
268 if (type() == SkyObject::ASTEROID || type() == SkyObject::COMET)
269 minsize = 2.;
270 if (name() == i18n("Sun") || name() == i18n("Moon"))
271 minsize = 8.;
272 if (size < minsize)
273 size = minsize;
274
275 //Inflate offset for Saturn
276 if (name() == i18n("Saturn"))
277 size = int(2.5 * size);
278
279 return 0.5 * size + 4.;
280}
281
283{
284 if (2 * rsun()*rearth() == 0)
285 {
286 Phase = std::numeric_limits<double>::quiet_NaN();
287 return;
288 }
289 /* Compute the phase of the planet in degrees */
290 double earthSun = KStarsData::Instance()->skyComposite()->earth()->rsun();
291 double cosPhase = (rsun() * rsun() + rearth() * rearth() - earthSun * earthSun) / (2 * rsun() * rearth());
292
293 Phase = acos(cosPhase) * 180.0 / dms::PI;
294 /* More elegant way of doing it, but requires the Sun.
295 TODO: Switch to this if and when we make KSSun a singleton */
296 // Phase = ecLong()->Degrees() - Sun->ecLong()->Degrees();
297}
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition cachingdms.h:19
void SinCos(double &s, double &c) const
Get the sine and cosine together.
Definition cachingdms.h:175
A subclass of KSPlanetBase that implements comets.
Definition kscomet.h:44
void setComaAngSize(double comaAngSize)
Sets the comet's apparent tail length in degrees.
Definition kscomet.h:106
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
const CachingDms * obliquity() const
Definition ksnumbers.h:56
long double getJD() const
Definition ksnumbers.h:128
long double julianDay() const
Definition ksnumbers.h:91
A subclass of TrailObject that provides additional information needed for most solar system objects.
virtual bool findGeocentricPosition(const KSNumbers *num, const KSPlanetBase *Earth=nullptr)=0
find the object's current geocentric equatorial coordinates (RA and Dec) This function is pure virtua...
void findPosition(const KSNumbers *num, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, const KSPlanetBase *Earth=nullptr)
Find position, including correction for Figure-of-the-Earth.
const dms & helEcLat() const
static const UID UID_SOL_COMET
Comets.
static const UID UID_SOL_BIGOBJ
Big object.
virtual void findMagnitude(const KSNumbers *num)=0
Computes the visual magnitude for the major planets.
static const UID UID_SOL_ASTEROID
Asteroids.
void setAngularSize(double size)
set the planet's angular size, in km.
void setRearth(double r)
Set the distance from Earth, in AU.
double physicalSize() const
KSPlanetBase(const QString &s=i18n("unnamed"), const QString &image_file=QString(), const QColor &c=Qt::white, double pSize=0)
Constructor.
void findPA(const KSNumbers *num)
Determine the position angle of the planet for a given date (used internally by findPosition() )
const dms & helEcLong() const
void updateCoords(const KSNumbers *num, bool includePlanets=true, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, bool forceRecompute=false) override
Update position of the planet (reimplemented from SkyPoint)
double angSize() const
double labelOffset() const override
const dms & ecLat() const
void EquatorialToEcliptic(const CachingDms *Obliquity)
Convert Right Ascension/Declination to Ecliptic longitude/latitude.
const dms & ecLong() const
double rearth() const
void EclipticToEquatorial(const CachingDms *Obliquity)
Convert Ecliptic longitude/latitude to Right Ascension/Declination.
double pa() const override
double rsun() const
virtual void findPhase()
Determine the phase of the planet.
void setPA(double p)
Set the Planet's position angle.
bool isMajorPlanet() const
KStarsData is the backbone of KStars.
Definition kstarsdata.h:74
SkyMapComposite * skyComposite()
Definition kstarsdata.h:174
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
void setLongName(const QString &longname=QString())
Set the object's long name.
Definition skyobject.cpp:76
qint64 UID
Type for Unique object IDenticator.
Definition skyobject.h:57
virtual QString name(void) const
Definition skyobject.h:154
void setName(const QString &name)
Set the object's primary name.
Definition skyobject.h:392
int type(void) const
Definition skyobject.h:212
const CachingDms & dec() const
Definition skypoint.h:269
SkyPoint(const dms &r, const dms &d)
Default constructor: Sets RA, Dec and RA0, Dec0 according to arguments.
Definition skypoint.h:54
void setDec(dms d)
Sets Dec, the current Declination.
Definition skypoint.h:169
void setRA(dms &r)
Sets RA, the current Right Ascension.
Definition skypoint.h:144
const CachingDms & ra() const
Definition skypoint.h:263
void findEcliptic(const CachingDms *Obliquity, dms &EcLong, dms &EcLat)
Determine the Ecliptic coordinates of the SkyPoint, given the Julian Date.
Definition skypoint.cpp:207
void setFromEcliptic(const CachingDms *Obliquity, const dms &EcLong, const dms &EcLat)
Set the current (RA, Dec) coordinates of the SkyPoint, given pointers to its Ecliptic (Long,...
Definition skypoint.cpp:221
static const QImage & getImage(const QString &name)
Return texture image.
TrailObject(int t=TYPE_UNKNOWN, dms r=dms(0.0), dms d=dms(0.0), float m=0.0, const QString &n=QString())
Constructor.
bool hasTrail() const
Definition trailobject.h:36
void addToTrail(const QString &label=QString())
adds a point to the planet's trail
static const int MaxTrail
Maximum trail size.
Definition trailobject.h:66
void clipTrail()
removes the oldest point from the trail
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
const dms reduce() const
return the equivalent angle between 0 and 360 degrees.
Definition dms.cpp:251
void SinCos(double &s, double &c) const
Compute Sine and Cosine of the angle simultaneously.
Definition dms.h:447
static constexpr double PI
PI is a const static member; it's public so that it can be used anywhere, as long as dms....
Definition dms.h:385
double radians() const
Express the angle in radians.
Definition dms.h:325
virtual void setRadians(const double &Rad)
Set angle according to the argument, in radians.
Definition dms.h:333
virtual void setD(const double &x)
Sets floating-point value of angle, in degrees.
Definition dms.h:179
const double & Degrees() const
Definition dms.h:141
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
QString toString(QStringView format, QCalendar cal) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:53:02 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.