Kstars

ksplanetbase.cpp
1 /*
2  SPDX-FileCopyrightText: 2001 Jason Harris <[email protected]>
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 
22 QVector<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 
37 KSPlanetBase::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 
43 void 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 
53 KSPlanetBase *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 
86 void 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 
109 void 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 
152 void 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 }
void setPA(double p)
Set the Planet's position angle.
Definition: ksplanetbase.h:181
KSPlanetBase(const QString &s=i18n("unnamed"), const QString &image_file=QString(), const QColor &c=Qt::white, double pSize=0)
Constructor.
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
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
const dms & helEcLong() const
Definition: ksplanetbase.h:109
double labelOffset() const override
void clipTrail()
removes the oldest point from the trail
Definition: trailobject.cpp:67
void setComaAngSize(double comaAngSize)
Sets the comet's apparent tail length in degrees.
Definition: kscomet.h:106
virtual void setD(const double &x)
Sets floating-point value of angle, in degrees.
Definition: dms.h:179
void findEcliptic(const CachingDms *Obliquity, dms &EcLong, dms &EcLat)
Determine the Ecliptic coordinates of the SkyPoint, given the Julian Date.
Definition: skypoint.cpp:187
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
virtual void findPhase()
Determine the phase of the planet.
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition: cachingdms.h:18
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.
void SinCos(double &s, double &c) const
Get the sine and cosine together.
Definition: cachingdms.h:175
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 SinCos(double &s, double &c) const
Compute Sine and Cosine of the angle simultaneously.
Definition: dms.h:444
A subclass of KSPlanetBase that implements comets.
Definition: kscomet.h:43
virtual QString name(void) const
Definition: skyobject.h:145
double rsun() const
Definition: ksplanetbase.h:130
double rearth() const
Definition: ksplanetbase.h:139
const dms & helEcLat() const
Definition: ksplanetbase.h:112
void addToTrail(const QString &label=QString())
adds a point to the planet's trail
Definition: trailobject.cpp:60
Provides necessary information about the Moon. A subclass of SkyObject that provides information need...
Definition: ksmoon.h:25
qint64 UID
Type for Unique object IDenticator.
Definition: skyobject.h:49
long double getJD() const
Definition: ksnumbers.h:128
int type(void) const
Definition: skyobject.h:188
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)
int size() const const
Provides necessary information about the Sun.
Definition: kssun.h:23
QString i18n(const char *text, const TYPE &arg...)
Store several time-dependent astronomical quantities.
Definition: ksnumbers.h:42
const CachingDms & dec() const
Definition: skypoint.h:269
static const UID UID_SOL_ASTEROID
Asteroids.
Definition: ksplanetbase.h:218
void setRearth(double r)
Set the distance from Earth, in AU.
Definition: ksplanetbase.h:145
provides a SkyObject with an attachable Trail
Definition: trailobject.h:21
virtual void findMagnitude(const KSNumbers *num)=0
Computes the visual magnitude for the major planets.
const dms & ecLong() const
Definition: ksplanetbase.h:91
long double julianDay() const
Definition: ksnumbers.h:91
void setName(const QString &name)
Set the object's primary name.
Definition: skyobject.h:417
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
Provides necessary information about objects in the solar system.
Definition: ksplanet.h:32
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:166
double physicalSize() const
Definition: ksplanetbase.h:192
double pa() const override
Definition: ksplanetbase.h:175
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
double angSize() const
Definition: ksplanetbase.h:184
virtual void setRadians(const double &Rad)
Set angle according to the argument, in radians.
Definition: dms.h:333
const CachingDms & ra() const
Definition: skypoint.h:263
const CachingDms * obliquity() const
Definition: ksnumbers.h:56
double radians() const
Express the angle in radians.
Definition: dms.h:325
const double & Degrees() const
Definition: dms.h:141
bool hasTrail() const
Definition: trailobject.h:36
void EquatorialToEcliptic(const CachingDms *Obliquity)
Convert Right Ascension/Declination to Ecliptic longitude/latitude.
void setAngularSize(double size)
set the planet's angular size, in km.
Definition: ksplanetbase.h:189
static const QImage & getImage(const QString &name)
Return texture image.
void setDec(dms d)
Sets Dec, the current Declination.
Definition: skypoint.h:169
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void setRA(dms &r)
Sets RA, the current Right Ascension.
Definition: skypoint.h:144
const dms reduce() const
return the equivalent angle between 0 and 360 degrees.
Definition: dms.cpp:251
QString toString(Qt::DateFormat format) const const
void EclipticToEquatorial(const CachingDms *Obliquity)
Convert Ecliptic longitude/latitude to Right Ascension/Declination.
static const UID UID_SOL_COMET
Comets.
Definition: ksplanetbase.h:220
T takeLast()
const dms & ecLat() const
Definition: ksplanetbase.h:94
static const UID UID_SOL_BIGOBJ
Big object.
Definition: ksplanetbase.h:216
void setLongName(const QString &longname=QString())
Set the object's long name.
Definition: skyobject.cpp:76
static const int MaxTrail
Maximum trail size.
Definition: trailobject.h:66
void findPA(const KSNumbers *num)
Determine the position angle of the planet for a given date (used internally by findPosition() )
bool isMajorPlanet() const
Provides necessary information about objects in the solar system.
Definition: ksplanetbase.h:49
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 04:02:10 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.