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
Provides necessary information about the Moon.
Definition ksmoon.h:26
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
A subclass of KSPlanetBase for seven of the major planets in the solar system (Earth and Pluto have t...
Definition ksplanet.h:33
Child class of KSPlanetBase; encapsulates information about the Sun.
Definition kssun.h:24
KStarsData is the backbone of KStars.
Definition kstarsdata.h:74
SkyMapComposite * skyComposite()
Definition kstarsdata.h:168
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
virtual QString name(void) const
Definition skyobject.h:146
void setName(const QString &name)
Set the object's primary name.
Definition skyobject.h:342
qint64 UID
Type for Unique object IDenticator.
Definition skyobject.h:49
int type(void) const
Definition skyobject.h:189
The sky coordinates of a point in the sky.
Definition skypoint.h:45
const CachingDms & dec() const
Definition skypoint.h:269
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:187
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:201
static const QImage & getImage(const QString &name)
Return texture image.
provides a SkyObject with an attachable Trail
Definition trailobject.h:22
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
qsizetype size() const const
value_type takeLast()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:04:47 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.