Kstars

skypoint.cpp
1/*
2 SPDX-FileCopyrightText: 2001-2005 Jason Harris <jharris@30doradus.org>
3 SPDX-FileCopyrightText: 2004-2005 Pablo de Vicente <p.devicente@wanadoo.es>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#include "skypoint.h"
9
10#include "dms.h"
11#include "ksnumbers.h"
12#include "kstarsdatetime.h"
13#include "kssun.h"
14#include "kstarsdata.h"
15#include "Options.h"
16#include "skyobject.h"
17#include "skycomponents/skymapcomposite.h"
18
19#include "config-kstars.h"
20
21#include <KLocalizedString>
22
23#include <QDebug>
24
25#include <cmath>
26
27
28
29// N.B. To use libnova depending on the availability of the package,
30// uncomment the following:
31/*
32#ifdef HAVE_LIBNOVA
33#define SKYPOINT_USE_LIBNOVA 1
34#endif
35*/
36
37#ifdef SKYPOINT_USE_LIBNOVA
38#include <libnova/libnova.h>
39bool SkyPoint::implementationIsLibnova = true;
40#else
41bool SkyPoint::implementationIsLibnova = false;
42#endif
43
44#ifdef PROFILE_COORDINATE_CONVERSION
45#include <ctime> // For profiling, remove if not profiling.
46long unsigned SkyPoint::eqToHzCalls = 0;
47double SkyPoint::cpuTime_EqToHz = 0.;
48#endif
49
50KSSun *SkyPoint::m_Sun = nullptr;
51const double SkyPoint::altCrit = -1.0;
52
54{
55 // Default constructor. Set nonsense values
56 RA0.setD(-1); // RA >= 0 always :-)
57 Dec0.setD(180); // Dec is between -90 and 90 Degrees :-)
58 RA = RA0;
59 Dec = Dec0;
60 lastPrecessJD = J2000; // By convention, we use J2000 coordinates
61}
62
63void SkyPoint::set(const dms &r, const dms &d)
64{
65 RA0 = RA = r;
66 Dec0 = Dec = d;
67 lastPrecessJD = J2000; // By convention, we use J2000 coordinates
68}
69
70void SkyPoint::EquatorialToHorizontal(const dms *LST, const dms *lat)
71{
72 // qDebug() << Q_FUNC_INFO << "NOTE: This EquatorialToHorizontal overload (using dms pointers instead of CachingDms pointers) is deprecated and should be replaced with CachingDms prototype wherever speed is desirable!";
73 CachingDms _LST(*LST), _lat(*lat);
74 EquatorialToHorizontal(&_LST, &_lat);
75}
76
78{
79#ifdef PROFILE_COORDINATE_CONVERSION
80 std::clock_t start = std::clock();
81#endif
82 //Uncomment for spherical trig version
83 double AltRad, AzRad;
84 double sindec, cosdec, sinlat, coslat, sinHA, cosHA;
85 double sinAlt, cosAlt;
86
87 CachingDms HourAngle =
88 (*LST) - ra(); // Using CachingDms subtraction operator to find cos/sin of HourAngle without calling sincos()
89
90 lat->SinCos(sinlat, coslat);
91 dec().SinCos(sindec, cosdec);
92 HourAngle.SinCos(sinHA, cosHA);
93
94 sinAlt = sindec * sinlat + cosdec * coslat * cosHA;
95 AltRad = asin(sinAlt);
96
97 cosAlt = sqrt(
98 1 -
99 sinAlt *
100 sinAlt); // Avoid trigonometric function. Return value of asin is always in [-pi/2, pi/2] and in this domain cosine is always non-negative, so we can use this.
101 if (cosAlt == 0.)
102 cosAlt = cos(AltRad);
103
104 double arg = (sindec - sinlat * sinAlt) / (coslat * cosAlt);
105 if (arg <= -1.0)
106 AzRad = dms::PI;
107 else if (arg >= 1.0)
108 AzRad = 0.0;
109 else
110 AzRad = acos(arg);
111
112 if (sinHA > 0.0 && AzRad != 0.0)
113 AzRad = 2.0 * dms::PI - AzRad; // resolve acos() ambiguity
114
115 Alt.setRadians(AltRad);
116 Az.setRadians(AzRad);
117#ifdef PROFILE_COORDINATE_CONVERSION
118 std::clock_t stop = std::clock();
119 cpuTime_EqToHz += double(stop - start) / double(CLOCKS_PER_SEC); // Accumulate time in seconds
120 ++eqToHzCalls;
121#endif
122
123 // //Uncomment for XYZ version
124 // double xr, yr, zr, xr1, zr1, sa, ca;
125 // //Z-axis rotation by -LST
126 // dms a = dms( -1.0*LST->Degrees() );
127 // a.SinCos( sa, ca );
128 // xr1 = m_X*ca + m_Y*sa;
129 // yr = -1.0*m_X*sa + m_Y*ca;
130 // zr1 = m_Z;
131 //
132 // //Y-axis rotation by lat - 90.
133 // a = dms( lat->Degrees() - 90.0 );
134 // a.SinCos( sa, ca );
135 // xr = xr1*ca - zr1*sa;
136 // zr = xr1*sa + zr1*ca;
137 //
138 // //FIXME: eventually, we will work with XYZ directly
139 // Alt.setRadians( asin( zr ) );
140 // Az.setRadians( atan2( yr, xr ) );
141}
142
143void SkyPoint::HorizontalToEquatorial(const dms *LST, const dms *lat)
144{
145 double HARad, DecRad;
146 double sinlat, coslat, sinAlt, cosAlt, sinAz, cosAz;
147 double sinDec, cosDec;
148
149 lat->SinCos(sinlat, coslat);
150 alt().SinCos(sinAlt, cosAlt);
151 Az.SinCos(sinAz, cosAz);
152
153 sinDec = sinAlt * sinlat + cosAlt * coslat * cosAz;
154 DecRad = asin(sinDec);
155 cosDec = cos(DecRad);
156 Dec.setRadians(DecRad);
157
158 double x = (sinAlt - sinlat * sinDec) / (coslat * cosDec);
159
160 //Under certain circumstances, x can be very slightly less than -1.0000, or slightly
161 //greater than 1.0000, leading to a crash on acos(x). However, the value isn't
162 //*really* out of range; it's a kind of roundoff error.
163 if (x < -1.0 && x > -1.000001)
164 HARad = dms::PI;
165 else if (x > 1.0 && x < 1.000001)
166 HARad = 0.0;
167 else if (x < -1.0)
168 {
169 //qWarning() << "Coordinate out of range.";
170 HARad = dms::PI;
171 }
172 else if (x > 1.0)
173 {
174 //qWarning() << "Coordinate out of range.";
175 HARad = 0.0;
176 }
177 else
178 HARad = acos(x);
179
180 if (sinAz > 0.0)
181 HARad = 2.0 * dms::PI - HARad; // resolve acos() ambiguity
182
183 RA.setRadians(LST->radians() - HARad);
184 RA.reduceToRange(dms::ZERO_TO_2PI);
185}
186
187void SkyPoint::HorizontalToEquatorialICRS(const dms *LST, const dms *lat, const long double jdf)
188{
189 HorizontalToEquatorial(LST, lat);
190 const auto ra_ = ra(), dec_ = dec();
191 catalogueCoord(jdf);
192
193 // The above alters (RA, Dec), so we restore
194 RA = ra_;
195 Dec = dec_;
196 lastPrecessJD = jdf;
197}
198
200{
201 auto *data = KStarsData::Instance();
202 Q_ASSERT(!!data);
203 HorizontalToEquatorialICRS(data->lst(), data->geo()->lat(), data->djd());
204}
205
206
207void SkyPoint::findEcliptic(const CachingDms *Obliquity, dms &EcLong, dms &EcLat)
208{
209 double sinRA, cosRA, sinOb, cosOb, sinDec, cosDec;
210 ra().SinCos(sinRA, cosRA);
211 dec().SinCos(sinDec, cosDec);
212 Obliquity->SinCos(sinOb, cosOb);
213
214 double ycosDec = sinRA * cosOb * cosDec + sinDec * sinOb;
215 double ELongRad = atan2(ycosDec, cosDec * cosRA);
216 EcLong.setRadians(ELongRad);
217 EcLong.reduceToRange(dms::ZERO_TO_2PI);
218 EcLat.setRadians(asin(sinDec * cosOb - cosDec * sinOb * sinRA)); // FIXME: Haversine
219}
220
221void SkyPoint::setFromEcliptic(const CachingDms *Obliquity, const dms &EcLong, const dms &EcLat)
222{
223 double sinLong, cosLong, sinLat, cosLat, sinObliq, cosObliq;
224 EcLong.SinCos(sinLong, cosLong);
225 EcLat.SinCos(sinLat, cosLat);
226 Obliquity->SinCos(sinObliq, cosObliq);
227
228 // double sinDec = sinLat * cosObliq + cosLat * sinObliq * sinLong;
229
230 double ycosLat = sinLong * cosObliq * cosLat - sinLat * sinObliq;
231 // double RARad = atan2( y, cosLong );
232 RA.setUsing_atan2(ycosLat, cosLong * cosLat);
233 RA.reduceToRange(dms::ZERO_TO_2PI);
234 // Dec.setUsing_asin(sinDec);
235
236 // Use Haversine to set declination
237 Dec.setRadians(dms::PI / 2.0 - 2.0 * asin(sqrt(0.5 * (
238 1.0 - sinLat * cosObliq
239 - cosLat * sinObliq * sinLong
240 ))));
241}
242
244{
245 double cosRA0, sinRA0, cosDec0, sinDec0;
246 const Eigen::Matrix3d &precessionMatrix = num->p2();
247 Eigen::Vector3d v, s;
248
249 RA0.SinCos(sinRA0, cosRA0);
250 Dec0.SinCos(sinDec0, cosDec0);
251
252 s[0] = cosRA0 * cosDec0;
253 s[1] = sinRA0 * cosDec0;
254 s[2] = sinDec0;
255
256 // NOTE: Rotation matrices are the fastest way to do rotations on
257 // a vector. Quaternions need more multiplications. The rotation
258 // matrix compensates in some sense by having more 'precomputed'
259 // multiplications. The matrix elements seem to cache nicely, so
260 // there isn't much overhead in accessing them.
261
262 //Multiply P2 and s to get v, the vector representing the new coords.
263 // for ( unsigned int i=0; i<3; ++i ) {
264 // v[i] = 0.0;
265 // for (uint j=0; j< 3; ++j) {
266 // v[i] += num->p2( j, i )*s[j];
267 // }
268 // }
269 v.noalias() = precessionMatrix * s;
270
271 //Extract RA, Dec from the vector:
272 RA.setUsing_atan2(v[1], v[0]);
273 RA.reduceToRange(dms::ZERO_TO_2PI);
274 Dec.setUsing_asin(v[2]);
275}
276
277SkyPoint SkyPoint::deprecess(const KSNumbers *num, long double epoch)
278{
279 SkyPoint p1(RA, Dec);
280 long double now = num->julianDay();
281 p1.precessFromAnyEpoch(now, epoch);
282 if ((std::isnan(RA0.Degrees()) || std::isnan(Dec0.Degrees())) ||
283 (!std::isnan(Dec0.Degrees()) && fabs(Dec0.Degrees()) > 90.0))
284 {
285 // We have invalid RA0 and Dec0, so set them if epoch = J2000. Otherwise, do not touch.
286 if (epoch == J2000L)
287 {
288 RA0 = p1.ra();
289 Dec0 = p1.dec();
290 }
291 }
292 return p1;
293}
294
295void SkyPoint::nutate(const KSNumbers *num, const bool reverse)
296{
297 //Step 2: Nutation
298 if (fabs(Dec.Degrees()) < 80.0) //approximate method
299 {
300 double cosRA, sinRA, cosDec, sinDec, tanDec;
301 double cosOb, sinOb;
302 double dRA, dDec;
303
304 RA.SinCos(sinRA, cosRA);
305 Dec.SinCos(sinDec, cosDec);
306
307 tanDec = sinDec / cosDec;
308
309 // Equ 23.1 in Jean Meeus' book
310 // nut_ecliptic / num->obliquity() is called epsilon in Meeus
311 // nut.longitude / num->dEcLong() is called delta psi in Meeus
312 // nut.obliquity / num->dObliq() is called delta epsilon in Meeus
313 // Meeus notes that these expressions are invalid if the star is
314 // close to one of the celestial poles
315
316 // N.B. These expressions are valid for FK5 coordinates
317 // (presumably also valid for ICRS by extension), but not for
318 // FK4. See the "Important Remark" on Page 152 of Jean Meeus'
319 // book.
320
321#ifdef SKYPOINT_USE_LIBNOVA
322 // code lifted from libnova ln_get_equ_nut, tailored to our needs
323 // with the option to add or remove nutation
324 struct ln_nutation nut;
325 ln_get_nutation (num->julianDay(), &nut); // FIXME: Is this cached, or is it a slow call? If it is slow, we should move it to KSNumbers
326
327 double nut_ecliptic = ln_deg_to_rad(nut.ecliptic + nut.obliquity);
328 sinOb = sin(nut_ecliptic);
329 cosOb = cos(nut_ecliptic);
330
331 dRA = nut.longitude * (cosOb + sinOb * sinRA * tanDec) - nut.obliquity * cosRA * tanDec;
332 dDec = nut.longitude * (sinOb * cosRA) + nut.obliquity * sinRA;
333#else
334 num->obliquity()->SinCos(sinOb, cosOb);
335
336 // N.B. num->dEcLong() and num->dObliq() methods return in
337 // degrees, whereby the corrections dRA and dDec are also in
338 // degrees.
339 dRA = num->dEcLong() * (cosOb + sinOb * sinRA * tanDec) - num->dObliq() * cosRA * tanDec;
340 dDec = num->dEcLong() * (sinOb * cosRA) + num->dObliq() * sinRA;
341#endif
342 // the sign changed to remove nutation
343 if (reverse)
344 {
345 dRA = -dRA;
346 dDec = -dDec;
347 }
348 RA.setD(RA.Degrees() + dRA);
349 Dec.setD(Dec.Degrees() + dDec);
350 }
351 else //exact method
352 {
353 // NOTE: Meeus declares that you must add Δψ to the ecliptic
354 // longitude of the body to get a more accurate precession
355 // result, but fails to emphasize that the NCP of the two
356 // coordinates systems is different. The (RA, Dec) without
357 // nutation computed, i.e. the mean place of the sky point is
358 // referenced to the un-nutated geocentric frame (without the
359 // obliquity correction), whereas the (RA, Dec) after nutation
360 // is applied is referenced to the nutated geocentric
361 // frame. This is more clearly explained in the "Explanatory
362 // Supplement to the Astronomical Almanac" by
363 // K. P. Seidelmann, which can be borrowed on the internet
364 // archive as of this writing, see page 114:
365 // https://archive.org/details/explanatorysuppl00pken
366 //
367 // The rotation matrix formulation in (3.222-3) and the figure
368 // 3.222.1 make this clear
369
370 // TODO apply reverse test above 80 degrees
371 dms EcLong, EcLat;
372 CachingDms obliquityWithoutNutation(*num->obliquity() - dms(num->dObliq()));
373
374 if (reverse)
375 {
376 //Subtract dEcLong from the Ecliptic Longitude
377 findEcliptic(num->obliquity(), EcLong, EcLat);
378 dms newLong(EcLong.Degrees() - num->dEcLong());
379 setFromEcliptic(&obliquityWithoutNutation, newLong, EcLat); // FIXME: Check
380 }
381 else
382 {
383 //Add dEcLong to the Ecliptic Longitude
384 findEcliptic(&obliquityWithoutNutation, EcLong, EcLat);
385 dms newLong(EcLong.Degrees() + num->dEcLong());
386 setFromEcliptic(num->obliquity(), newLong, EcLat);
387 }
388 }
389}
390
391SkyPoint SkyPoint::moveAway(const SkyPoint &from, double dist) const
392{
393 CachingDms lat1, dtheta;
394
395 if (dist == 0.0)
396 {
397 qDebug() << Q_FUNC_INFO << "moveAway called with zero distance!";
398 return *this;
399 }
400
401 double dst = fabs(dist * dms::DegToRad / 3600.0); // In radian
402
403 // Compute the bearing angle w.r.t. the RA axis ("latitude")
404 CachingDms dRA(ra() - from.ra());
405 CachingDms dDec(dec() - from.dec());
406 double bearing = atan2(dRA.sin() / dRA.cos(), dDec.sin()); // Do not use dRA = PI / 2!!
407 //double bearing = atan2( dDec.radians() , dRA.radians() );
408
409 // double dir0 = (dist >= 0 ) ? bearing : bearing + dms::PI; // in radian
410 double dir0 = bearing + std::signbit(dist) * dms::PI; // might be faster?
411 double sinDst = sin(dst), cosDst = cos(dst);
412
413 lat1.setUsing_asin(dec().sin() * cosDst + dec().cos() * sinDst * cos(dir0));
414 dtheta.setUsing_atan2(sin(dir0) * sinDst * dec().cos(), cosDst - dec().sin() * lat1.sin());
415
416 return SkyPoint(ra() + dtheta, lat1);
417}
418
420{
421 // First see if we are close enough to the sun to bother about the
422 // gravitational lensing effect. We correct for the effect at
423 // least till b = 10 solar radii, where the effect is only about
424 // 0.06". Assuming min. sun-earth distance is 200 solar radii.
425 static const dms maxAngle(1.75 * (30.0 / 200.0) / dms::DegToRad);
426
427 if (!m_Sun)
428 {
429 SkyComposite *skycomopsite = KStarsData::Instance()->skyComposite();
430
431 if (skycomopsite == nullptr)
432 return false;
433
434 m_Sun = dynamic_cast<KSSun *>(skycomopsite->findByName(i18n("Sun")));
435
436 if (m_Sun == nullptr)
437 return false;
438 }
439
440 // TODO: This can be optimized further. We only need a ballpark estimate of the distance to the sun to start with.
441 return (fabs(angularDistanceTo(static_cast<const SkyPoint *>(m_Sun)).Degrees()) <=
442 maxAngle.Degrees()); // NOTE: dynamic_cast is slow and not important here.
443}
444
446{
447 // NOTE: This should be applied before aberration
448 // NOTE: One must call checkBendLight() before unnecessarily calling this.
449 // We correct for GR effects
450
451 // NOTE: This code is buggy. The sun needs to be initialized to
452 // the current epoch -- but we are not certain that this is the
453 // case. We have, as of now, no way of telling if the sun is
454 // initialized or not. If we initialize the sun here, we will be
455 // slowing down the program rather substantially and potentially
456 // introducing bugs. Therefore, we just ignore this problem, and
457 // hope that whenever the user is interested in seeing the effects
458 // of GR, we have the sun initialized correctly. This is usually
459 // the case. When the sun is not correctly initialized, rearth()
460 // is not computed, so we just assume it is nominally equal to 1
461 // AU to get a reasonable estimate.
462 Q_ASSERT(m_Sun);
463 double corr_sec = 1.75 * m_Sun->physicalSize() /
464 ((std::isfinite(m_Sun->rearth()) ? m_Sun->rearth() : 1) * AU_KM *
465 angularDistanceTo(static_cast<const SkyPoint *>(m_Sun)).sin());
466 Q_ASSERT(corr_sec > 0);
467
468 SkyPoint sp = moveAway(*m_Sun, corr_sec);
469 setRA(sp.ra());
470 setDec(sp.dec());
471 return true;
472}
473
474void SkyPoint::aberrate(const KSNumbers *num, bool reverse)
475{
476#ifdef SKYPOINT_USE_LIBNOVA
477 ln_equ_posn pos { RA.Degrees(), Dec.Degrees() };
478 ln_equ_posn abPos { 0, 0 };
479 ln_get_equ_aber(&pos, num->julianDay(), &abPos);
480 if (reverse)
481 {
482 RA.setD(RA.Degrees() * 2 - abPos.ra);
483 Dec.setD(Dec.Degrees() * 2 - abPos.dec);
484 }
485 else
486 {
487 RA.setD(abPos.ra);
488 Dec.setD(abPos.dec);
489 }
490
491#else
492 // N.B. These expressions are valid for FK5 coordinates
493 // (presumably also valid for ICRS by extension), but not for
494 // FK4. See the "Important Remark" on Page 152 of Jean Meeus'
495 // book.
496
497 // N.B. Even though Meeus does not say this explicitly, these
498 // equations must not apply near the pole. Therefore, we fall-back
499 // to the expressions provided by Meeus in ecliptic coordinates
500 // (Equ 23.2) when we are near the pole.
501
502 double K = num->constAberr().Degrees(); //constant of aberration
503 double e = num->earthEccentricity(); // eccentricity of Earth's orbit
504
505 if (fabs(Dec.Degrees()) < 80.0)
506 {
507
508 double cosRA, sinRA, cosDec, sinDec;
509 double cosL, sinL, cosP, sinP;
510 double cosOb, sinOb;
511
512
513 RA.SinCos(sinRA, cosRA);
514 Dec.SinCos(sinDec, cosDec);
515
516 num->obliquity()->SinCos(sinOb, cosOb);
517 // double tanOb = sinOb/cosOb;
518
519 num->sunTrueLongitude().SinCos(sinL, cosL);
520 num->earthPerihelionLongitude().SinCos(sinP, cosP);
521
522 //Step 3: Aberration
523 // These are the expressions given in Jean Meeus, Equation (23.3)
524
525 // double dRA = -1.0 * K * ( cosRA * cosL * cosOb + sinRA * sinL )/cosDec
526 // + e * K * ( cosRA * cosP * cosOb + sinRA * sinP )/cosDec;
527
528 // double dDec = -1.0 * K * ( cosL * cosOb * ( tanOb * cosDec - sinRA * sinDec ) + cosRA * sinDec * sinL )
529 // + e * K * ( cosP * cosOb * ( tanOb * cosDec - sinRA * sinDec ) + cosRA * sinDec * sinP );
530
531 // However, we have factorized the expressions below by pulling
532 // out common factors to make it more optimized, in case the
533 // compiler fails to spot these optimizations.
534
535 // N.B. I had failed to factor out the expressions correctly,
536 // making mistakes, in c5e709bd91, which should now be
537 // fixed. --asimha
538
539 // FIXME: Check if the unit tests have sufficient coverage to
540 // check this expression
541
542 double dRA = (K / cosDec) * (
543 cosRA * cosOb * (e * cosP - cosL)
544 + sinRA * (e * sinP - sinL)
545 );
546 double dDec = K * (
547 (sinOb * cosDec - cosOb * sinDec * sinRA) * (e * cosP - cosL)
548 + cosRA * sinDec * (e * sinP - sinL)
549 );
550
551 // N.B. Meeus points out that the result has the same units as
552 // K, so the corrections are in degrees.
553
554 if (reverse)
555 {
556 dRA = -dRA;
557 dDec = -dDec;
558 }
559 RA.setD(RA.Degrees() + dRA);
560 Dec.setD(Dec.Degrees() + dDec);
561 }
562 else
563 {
564 dms EcLong, EcLat;
565 double sinEcLat, cosEcLat;
566 const auto &L = num->sunTrueLongitude();
567 const auto &P = num->earthPerihelionLongitude();
568
569 findEcliptic(num->obliquity(), EcLong, EcLat);
570 EcLat.SinCos(sinEcLat, cosEcLat);
571
572 double sin_L_minus_EcLong, cos_L_minus_EcLong;
573 double sin_P_minus_EcLong, cos_P_minus_EcLong;
574 (L - EcLong).SinCos(sin_L_minus_EcLong, cos_L_minus_EcLong);
575 (P - EcLong).SinCos(sin_P_minus_EcLong, cos_P_minus_EcLong);
576
577 // Equation (23.2) in Meeus
578 // N.B. dEcLong, dEcLat are in degrees, because K is expressed in degrees.
579 double dEcLong = (K / cosEcLat) * (e * cos_P_minus_EcLong - cos_L_minus_EcLong);
580 double dEcLat = K * sinEcLat * (e * sin_P_minus_EcLong - sin_L_minus_EcLong);
581
582 // Note: These are approximate corrections, so it is
583 // appropriate to change their sign to reverse them to first
584 // order in the corrections. As a result, the forward and
585 // reverse calculations will not be exact inverses, but only
586 // approximate inverses.
587 if (reverse)
588 {
589 dEcLong = -dEcLong;
590 dEcLat = -dEcLat;
591 }
592
593 // Update the ecliptic coordinates to their new values
594 EcLong.setD(EcLong.Degrees() + dEcLong);
595 EcLat.setD(EcLat.Degrees() + dEcLat);
596 setFromEcliptic(num->obliquity(), EcLong, EcLat);
597 }
598#endif
599}
600
601// Note: This method is one of the major rate determining factors in how fast the map pans / zooms in or out
602void SkyPoint::updateCoords(const KSNumbers *num, bool /*includePlanets*/, const CachingDms *lat, const CachingDms *LST,
603 bool forceRecompute)
604{
605 //Correct the catalog coordinates for the time-dependent effects
606 //of precession, nutation and aberration
607 bool recompute, lens;
608
609 // NOTE: The same short-circuiting checks are also implemented in
610 // StarObject::JITUpdate(), even before calling
611 // updateCoords(). While this is code-duplication, these bits of
612 // code need to be really optimized, at least for stars. For
613 // optimization purposes, the code is left duplicated in two
614 // places. Please be wary of changing one without changing the
615 // other.
616
617 Q_ASSERT(std::isfinite(lastPrecessJD));
618
619 if (Options::useRelativistic() && checkBendLight())
620 {
621 recompute = true;
622 lens = true;
623 }
624 else
625 {
626 recompute = (Options::alwaysRecomputeCoordinates() || forceRecompute ||
627 std::abs(lastPrecessJD - num->getJD()) >= 0.00069444); // Update once per solar minute
628 lens = false;
629 }
630 if (recompute)
631 {
632 precess(num);
633 nutate(num);
634 if (lens)
635 bendlight(); // FIXME: Shouldn't we apply this on the horizontal coordinates?
636 aberrate(num);
637 lastPrecessJD = num->getJD();
638 Q_ASSERT(std::isfinite(RA.Degrees()) && std::isfinite(Dec.Degrees()));
639 }
640
641 if (lat || LST)
642 qWarning() << i18n("lat and LST parameters should only be used in KSPlanetBase objects.");
643}
644
645void SkyPoint::precessFromAnyEpoch(long double jd0, long double jdf)
646{
647 double cosRA, sinRA, cosDec, sinDec;
648 double v[3], s[3];
649
650 RA = RA0;
651 Dec = Dec0; // Is this necessary?
652
653 if (jd0 == jdf)
654 return;
655
656 RA.SinCos(sinRA, cosRA);
657 Dec.SinCos(sinDec, cosDec);
658
659 if (jd0 == B1950L)
660 {
661 B1950ToJ2000();
662 jd0 = J2000L;
663 RA.SinCos(sinRA, cosRA);
664 Dec.SinCos(sinDec, cosDec);
665 }
666
667 if (jd0 != jdf)
668 {
669 // The original coordinate is referred to the FK5 system and
670 // is NOT J2000.
671 if (jd0 != J2000L)
672 {
673 //v is a column vector representing input coordinates.
674 v[0] = cosRA * cosDec;
675 v[1] = sinRA * cosDec;
676 v[2] = sinDec;
677
678 //Need to first precess to J2000.0 coords
679 //s is the product of P1 and v; s represents the
680 //coordinates precessed to J2000
681 KSNumbers num(jd0);
682 for (unsigned int i = 0; i < 3; ++i)
683 {
684 s[i] = num.p1(0, i) * v[0] + num.p1(1, i) * v[1] + num.p1(2, i) * v[2];
685 }
686
687 //Input coords already in J2000, set s accordingly.
688 }
689 else
690 {
691 s[0] = cosRA * cosDec;
692 s[1] = sinRA * cosDec;
693 s[2] = sinDec;
694 }
695
696 if (jdf == B1950L)
697 {
698 RA.setRadians(atan2(s[1], s[0]));
699 Dec.setRadians(asin(s[2]));
700 J2000ToB1950();
701
702 return;
703 }
704
705 KSNumbers num(jdf);
706 for (unsigned int i = 0; i < 3; ++i)
707 {
708 v[i] = num.p2(0, i) * s[0] + num.p2(1, i) * s[1] + num.p2(2, i) * s[2];
709 }
710
711 RA.setUsing_atan2(v[1], v[0]);
712 Dec.setUsing_asin(v[2]);
713
714 RA.reduceToRange(dms::ZERO_TO_2PI);
715
716 return;
717 }
718}
719
720void SkyPoint::apparentCoord(long double jd0, long double jdf)
721{
722 precessFromAnyEpoch(jd0, jdf);
723 KSNumbers num(jdf);
724 nutate(&num);
725 if (Options::useRelativistic() && checkBendLight())
726 bendlight();
727 aberrate(&num);
728}
729
731{
732 KSNumbers num(jdf);
733
734 // remove abberation
735 aberrate(&num, true);
736
737 // remove nutation
738 nutate(&num, true);
739
740 // remove precession
741 // the start position needs to be in RA0,Dec0
742 RA0 = RA;
743 Dec0 = Dec;
744 // from now to J2000
745 precessFromAnyEpoch(jdf, static_cast<long double>(J2000));
746 // the J2000 position is in RA,Dec, move to RA0, Dec0
747 RA0 = RA;
748 Dec0 = Dec;
749 lastPrecessJD = J2000;
750
751 SkyPoint sp(RA0, Dec0);
752 return sp;
753}
754
756{
757 double a = 192.25;
758 double sinb, cosb, sina_RA, cosa_RA, sinDEC, cosDEC, tanDEC;
759
760 dms c(303.0);
761 dms b(27.4);
762 tanDEC = tan(Dec.radians());
763
764 b.SinCos(sinb, cosb);
765 dms(a - RA.Degrees()).SinCos(sina_RA, cosa_RA);
766 Dec.SinCos(sinDEC, cosDEC);
767
768 galLong.setRadians(c.radians() - atan2(sina_RA, cosa_RA * sinb - tanDEC * cosb));
769 galLong.reduceToRange(dms::ZERO_TO_2PI);
770
771 galLat.setRadians(asin(sinDEC * sinb + cosDEC * cosb * cosa_RA));
772}
773
774void SkyPoint::GalacticToEquatorial1950(const dms *galLong, const dms *galLat)
775{
776 double a = 123.0;
777 double sinb, cosb, singLat, cosgLat, tangLat, singLong_a, cosgLong_a;
778
779 dms c(12.25);
780 dms b(27.4);
781 tangLat = tan(galLat->radians());
782 galLat->SinCos(singLat, cosgLat);
783
784 dms(galLong->Degrees() - a).SinCos(singLong_a, cosgLong_a);
785 b.SinCos(sinb, cosb);
786
787 RA.setRadians(c.radians() + atan2(singLong_a, cosgLong_a * sinb - tangLat * cosb));
788 RA.reduceToRange(dms::ZERO_TO_2PI);
789
790 Dec.setRadians(asin(singLat * sinb + cosgLat * cosb * cosgLong_a));
791}
792
794{
795 double cosRA, sinRA, cosDec, sinDec;
796 // double cosRA0, sinRA0, cosDec0, sinDec0;
797 double v[3], s[3];
798
799 // 1984 January 1 0h
800 KSNumbers num(2445700.5L);
801
802 // Eterms due to aberration
803 addEterms();
804 RA.SinCos(sinRA, cosRA);
805 Dec.SinCos(sinDec, cosDec);
806
807 // Precession from B1950 to J1984
808 s[0] = cosRA * cosDec;
809 s[1] = sinRA * cosDec;
810 s[2] = sinDec;
811 for (unsigned int i = 0; i < 3; ++i)
812 {
813 v[i] = num.p2b(0, i) * s[0] + num.p2b(1, i) * s[1] + num.p2b(2, i) * s[2];
814 }
815
816 // RA zero-point correction at 1984 day 1, 0h.
817 RA.setRadians(atan2(v[1], v[0]));
818 Dec.setRadians(asin(v[2]));
819
820 RA.setH(RA.Hours() + 0.06390 / 3600.);
821 RA.SinCos(sinRA, cosRA);
822 Dec.SinCos(sinDec, cosDec);
823
824 s[0] = cosRA * cosDec;
825 s[1] = sinRA * cosDec;
826 s[2] = sinDec;
827
828 // Precession from 1984 to J2000.
829
830 for (unsigned int i = 0; i < 3; ++i)
831 {
832 v[i] = num.p1(0, i) * s[0] + num.p1(1, i) * s[1] + num.p1(2, i) * s[2];
833 }
834
835 RA.setRadians(atan2(v[1], v[0]));
836 Dec.setRadians(asin(v[2]));
837}
838
840{
841 double cosRA, sinRA, cosDec, sinDec;
842 // double cosRA0, sinRA0, cosDec0, sinDec0;
843 double v[3], s[3];
844
845 // 1984 January 1 0h
846 KSNumbers num(2445700.5L);
847
848 RA.SinCos(sinRA, cosRA);
849 Dec.SinCos(sinDec, cosDec);
850
851 s[0] = cosRA * cosDec;
852 s[1] = sinRA * cosDec;
853 s[2] = sinDec;
854
855 // Precession from J2000 to 1984 day, 0h.
856
857 for (unsigned int i = 0; i < 3; ++i)
858 {
859 v[i] = num.p2(0, i) * s[0] + num.p2(1, i) * s[1] + num.p2(2, i) * s[2];
860 }
861
862 RA.setRadians(atan2(v[1], v[0]));
863 Dec.setRadians(asin(v[2]));
864
865 // RA zero-point correction at 1984 day 1, 0h.
866
867 RA.setH(RA.Hours() - 0.06390 / 3600.);
868 RA.SinCos(sinRA, cosRA);
869 Dec.SinCos(sinDec, cosDec);
870
871 // Precession from B1950 to J1984
872
873 s[0] = cosRA * cosDec;
874 s[1] = sinRA * cosDec;
875 s[2] = sinDec;
876 for (unsigned int i = 0; i < 3; ++i)
877 {
878 v[i] = num.p1b(0, i) * s[0] + num.p1b(1, i) * s[1] + num.p1b(2, i) * s[2];
879 }
880
881 RA.setRadians(atan2(v[1], v[0]));
882 Dec.setRadians(asin(v[2]));
883
884 // Eterms due to aberration
886}
887
889{
890 double sd, cd, sinEterm, cosEterm;
891 dms raTemp, raDelta, decDelta;
892
893 Dec.SinCos(sd, cd);
894 raTemp.setH(RA.Hours() + 11.25);
895 raTemp.SinCos(sinEterm, cosEterm);
896
897 raDelta.setH(0.0227 * sinEterm / (3600. * cd));
898 decDelta.setD(0.341 * cosEterm * sd / 3600. + 0.029 * cd / 3600.);
899
900 return SkyPoint(raDelta, decDelta);
901}
902
904{
905 SkyPoint spd = Eterms();
906
907 RA = RA + spd.ra();
908 Dec = Dec + spd.dec();
909}
910
912{
913 SkyPoint spd = Eterms();
914
915 RA = RA - spd.ra();
916 Dec = Dec - spd.dec();
917}
918
919dms SkyPoint::angularDistanceTo(const SkyPoint *sp, double *const positionAngle) const
920{
921 // double dalpha = sp->ra().radians() - ra().radians() ;
922 // double ddelta = sp->dec().radians() - dec().radians();
923 CachingDms dalpha = sp->ra() - ra();
924 CachingDms ddelta = sp->dec() - dec();
925
926 // double sa = sin(dalpha/2.);
927 // double sd = sin(ddelta/2.);
928
929 // double hava = sa*sa;
930 // double havd = sd*sd;
931
932 // Compute the haversin directly:
933 double hava = (1 - dalpha.cos()) / 2.;
934 double havd = (1 - ddelta.cos()) / 2.;
935
936 // Haversine law
937 double aux = havd + (sp->dec().cos()) * dec().cos() * hava;
938
939 dms angDist;
940 angDist.setRadians(2. * fabs(asin(sqrt(aux))));
941
942 if (positionAngle)
943 {
944 // Also compute the position angle of the line from this SkyPoint to sp
945 //*positionAngle = acos( tan(-ddelta)/tan( angDist.radians() ) ); // FIXME: Might fail for large ddelta / zero angDist
946 //if( -dalpha < 0 )
947 // *positionAngle = 2*M_PI - *positionAngle;
948 *positionAngle =
949 atan2f(dalpha.sin(), (dec().cos()) * tan(sp->dec().radians()) - (dec().sin()) * dalpha.cos()) * 180 / M_PI;
950 }
951 return angDist;
952}
953
954double SkyPoint::vRSun(long double jd0)
955{
956 double ca, sa, cd, sd, vsun;
957 double cosRA, sinRA, cosDec, sinDec;
958
959 /* Sun apex (where the sun goes) coordinates */
960
961 dms asun(270.9592); // Right ascention: 18h 3m 50.2s [J2000]
962 dms dsun(30.00467); // Declination: 30^o 0' 16.8'' [J2000]
963 vsun = 20.; // [km/s]
964
965 asun.SinCos(sa, ca);
966 dsun.SinCos(sd, cd);
967
968 /* We need an auxiliary SkyPoint since we need the
969 * source referred to the J2000 equinox and we do not want to overwrite
970 * the current values
971 */
972
973 SkyPoint aux;
974 aux.set(RA0, Dec0);
975
976 aux.precessFromAnyEpoch(jd0, J2000L);
977
978 aux.ra().SinCos(sinRA, cosRA);
979 aux.dec().SinCos(sinDec, cosDec);
980
981 /* Computation is done performing the scalar product of a unitary vector
982 in the direction of the source with the vector velocity of Sun, both being in the
983 LSR reference system:
984 Vlsr = Vhel + Vsun.u_radial =>
985 Vlsr = Vhel + vsun(cos D cos A,cos D sen A,sen D).(cos d cos a,cos d sen a,sen d)
986 Vhel = Vlsr - Vsun.u_radial
987 */
988
989 return vsun * (cd * cosDec * (cosRA * ca + sa * sinRA) + sd * sinDec);
990}
991
992double SkyPoint::vHeliocentric(double vlsr, long double jd0)
993{
994 return vlsr - vRSun(jd0);
995}
996
997double SkyPoint::vHelioToVlsr(double vhelio, long double jd0)
998{
999 return vhelio + vRSun(jd0);
1000}
1001
1002double SkyPoint::vREarth(long double jd0)
1003{
1004 double sinRA, sinDec, cosRA, cosDec;
1005
1006 /* u_radial = unitary vector in the direction of the source
1007 Vlsr = Vhel + Vsun.u_radial
1008 = Vgeo + VEarth.u_radial + Vsun.u_radial =>
1009
1010 Vgeo = (Vlsr -Vsun.u_radial) - VEarth.u_radial
1011 = Vhel - VEarth.u_radial
1012 = Vhel - (vx, vy, vz).(cos d cos a,cos d sen a,sen d)
1013 */
1014
1015 /* We need an auxiliary SkyPoint since we need the
1016 * source referred to the J2000 equinox and we do not want to overwrite
1017 * the current values
1018 */
1019
1020 SkyPoint aux(RA0, Dec0);
1021
1022 aux.precessFromAnyEpoch(jd0, J2000L);
1023
1024 aux.ra().SinCos(sinRA, cosRA);
1025 aux.dec().SinCos(sinDec, cosDec);
1026
1027 /* vEarth is referred to the J2000 equinox, hence we need that
1028 the source coordinates are also in the same reference system.
1029 */
1030
1031 KSNumbers num(jd0);
1032 return num.vEarth(0) * cosDec * cosRA + num.vEarth(1) * cosDec * sinRA + num.vEarth(2) * sinDec;
1033}
1034
1035double SkyPoint::vGeocentric(double vhelio, long double jd0)
1036{
1037 return vhelio - vREarth(jd0);
1038}
1039
1040double SkyPoint::vGeoToVHelio(double vgeo, long double jd0)
1041{
1042 return vgeo + vREarth(jd0);
1043}
1044
1045double SkyPoint::vRSite(double vsite[3])
1046{
1047 double sinRA, sinDec, cosRA, cosDec;
1048
1049 RA.SinCos(sinRA, cosRA);
1050 Dec.SinCos(sinDec, cosDec);
1051
1052 return vsite[0] * cosDec * cosRA + vsite[1] * cosDec * sinRA + vsite[2] * sinDec;
1053}
1054
1055double SkyPoint::vTopoToVGeo(double vtopo, double vsite[3])
1056{
1057 return vtopo + vRSite(vsite);
1058}
1059
1060double SkyPoint::vTopocentric(double vgeo, double vsite[3])
1061{
1062 return vgeo - vRSite(vsite);
1063}
1064
1065bool SkyPoint::checkCircumpolar(const dms *gLat) const
1066{
1067 return fabs(dec().Degrees()) > (90 - fabs(gLat->Degrees()));
1068}
1069
1071{
1072 return refract(Alt, Options::useRefraction());
1073}
1074
1076{
1077 setAlt(unrefract(alt_apparent, Options::useRefraction()));
1078}
1079
1080void SkyPoint::setAltRefracted(double alt_apparent)
1081{
1082 setAlt(unrefract(alt_apparent, Options::useRefraction()));
1083}
1084
1086{
1087 return 1.02 / tan(dms::DegToRad * (alt + 10.3 / (alt + 5.11))) / 60;
1088}
1089
1090double SkyPoint::refract(const double alt, bool conditional)
1091{
1092 if (!conditional)
1093 {
1094 return alt;
1095 }
1096 static double corrCrit = SkyPoint::refractionCorr(SkyPoint::altCrit);
1097
1098 if (alt > SkyPoint::altCrit)
1099 return (alt + SkyPoint::refractionCorr(alt));
1100 else
1101 return (alt +
1102 corrCrit * (alt + 90) /
1103 (SkyPoint::altCrit + 90)); // Linear extrapolation from corrCrit at altCrit to 0 at -90 degrees
1104}
1105
1106// Found uncorrected value by solving equation. This is OK since
1107// unrefract is never called in loops with the potential exception of
1108// slewing.
1109//
1110// Convergence is quite fast just a few iterations.
1111double SkyPoint::unrefract(const double alt, bool conditional)
1112{
1113 if (!conditional)
1114 {
1115 return alt;
1116 }
1117 double h0 = alt;
1118 double h1 =
1119 alt -
1120 (refract(h0) -
1121 h0); // It's probably okay to add h0 in refract() and subtract it here, since refract() is called way more frequently.
1122
1123 while (fabs(h1 - h0) > 1e-4)
1124 {
1125 h0 = h1;
1126 h1 = alt - (refract(h0) - h0);
1127 }
1128 return h1;
1129}
1130
1131dms SkyPoint::findAltitude(const SkyPoint *p, const KStarsDateTime &dt, const GeoLocation *geo, const double hour)
1132{
1133 Q_ASSERT(p);
1134 if (!p)
1135 return dms(NaN::d);
1136
1137 // Jasem 2015-08-24 Using correct procedure to find altitude
1138 return SkyPoint::timeTransformed(p, dt, geo, hour).alt();
1139}
1140
1142 const double hour)
1143{
1144 Q_ASSERT(p);
1145 if (!p)
1146 return SkyPoint(NaN::d, NaN::d);
1147
1148 // Jasem 2015-08-24 Using correct procedure to find altitude
1149 SkyPoint sp = *p; // make a copy
1150 KStarsDateTime targetDateTime = dt.addSecs(hour * 3600.0);
1151 dms LST = geo->GSTtoLST(targetDateTime.gst());
1152 sp.EquatorialToHorizontal(&LST, geo->lat());
1153 return sp;
1154}
1155
1156double SkyPoint::maxAlt(const dms &lat) const
1157{
1158 double retval = (lat.Degrees() + 90. - dec().Degrees());
1159 if (retval > 90.)
1160 retval = 180. - retval;
1161 return retval;
1162}
1163
1164double SkyPoint::minAlt(const dms &lat) const
1165{
1166 double retval = (lat.Degrees() - 90. + dec().Degrees());
1167 if (retval < -90.)
1168 retval = 180. + retval;
1169 return retval;
1170}
1171
1173{
1174 // N.B. Technically, we could use the form
1175 // cos(angle) = (sin(φ) - sin(h) sin(δ))/(cos(h) cos(δ))
1176 // where h = altitude, δ = declination, φ = latitude,
1177 // and then disambiguate the sign as
1178 // if (az().reduce() < 180°) angle = -angle;
1179 // However, acos(...) is inaccurate when cosine is nearly flat, i.e. near 0° and 180°.
1180 // It is therefore better to go through some extra pain to use atan2()
1181
1182 // Therefore we use the form shown in Jean Meeus' book (14.1)
1183 dms HA = LST - ra();
1184 double tan_lat = lat.sin() / lat.cos();
1185 double angle = atan2( // Measured CW on sky map (See Meeus' Fig on Pg 99)
1186 HA.sin(),
1187 tan_lat * dec().cos() - HA.cos() * dec().sin()
1188 );
1189 return dms(angle / dms::DegToRad);
1190}
1191
1192
1193#ifndef KSTARS_LITE
1194QDBusArgument &operator<<(QDBusArgument &argument, const SkyPoint &source)
1195{
1196 argument.beginStructure();
1197 argument << source.ra().Hours() << source.dec().Degrees();
1198 argument.endStructure();
1199 return argument;
1200}
1201
1202const QDBusArgument &operator>>(const QDBusArgument &argument, SkyPoint &dest)
1203{
1204 double ra, dec;
1205 argument.beginStructure();
1206 argument >> ra >> dec;
1207 argument.endStructure();
1208 dest = SkyPoint(ra, dec);
1209 return argument;
1210}
1211#endif
1212
a dms subclass that caches its sine and cosine values every time the angle is changed.
Definition cachingdms.h:19
double cos() const
Get the cosine of this angle.
Definition cachingdms.h:204
void setUsing_atan2(const double &y, const double &x)
Sets the angle using atan2()
double sin() const
Get the sine of this angle.
Definition cachingdms.h:190
void SinCos(double &s, double &c) const
Get the sine and cosine together.
Definition cachingdms.h:175
void setUsing_asin(const double &sine)
Sets the angle using asin()
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
double p1(int i1, int i2) const
Definition ksnumbers.h:97
dms constAberr() const
Definition ksnumbers.h:59
double p1b(int i1, int i2) const
Definition ksnumbers.h:103
CachingDms earthPerihelionLongitude() const
Definition ksnumbers.h:74
CachingDms sunTrueLongitude() const
Definition ksnumbers.h:71
const CachingDms * obliquity() const
Definition ksnumbers.h:56
long double getJD() const
Definition ksnumbers.h:128
double dEcLong() const
Definition ksnumbers.h:85
double dObliq() const
Definition ksnumbers.h:81
double p2(int i1, int i2) const
Definition ksnumbers.h:100
double earthEccentricity() const
Definition ksnumbers.h:77
long double julianDay() const
Definition ksnumbers.h:91
double p2b(int i1, int i2) const
Definition ksnumbers.h:106
Child class of KSPlanetBase; encapsulates information about the Sun.
Definition kssun.h:24
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
KStarsDateTime addSecs(double s) const
SkyComposite is a kind of container class for SkyComponent objects.
SkyObject * findByName(const QString &name, bool exact=true) override
Search the children of this SkyComposite for a SkyObject whose name matches the argument.
The sky coordinates of a point in the sky.
Definition skypoint.h:45
double maxAlt(const dms &lat) const
Return the object's altitude at the upper culmination for the given latitude.
void apparentCoord(long double jd0, long double jdf)
Computes the apparent coordinates for this SkyPoint for any epoch, accounting for the effects of prec...
Definition skypoint.cpp:720
static double refract(const double alt, bool conditional=true)
Apply refraction correction to altitude, depending on conditional.
static const double altCrit
Critical height for atmospheric refraction corrections.
Definition skypoint.h:746
void aberrate(const KSNumbers *num, bool reverse=false)
Determine the effects of aberration for this SkyPoint.
Definition skypoint.cpp:474
void precessFromAnyEpoch(long double jd0, long double jdf)
General case of precession.
Definition skypoint.cpp:645
static double refractionCorr(double alt)
Calculate refraction correction.
const CachingDms & dec() const
Definition skypoint.h:269
void setAltRefracted(dms alt_apparent)
Sets the apparent altitude, checking whether refraction corrections are enabled.
SkyPoint(const dms &r, const dms &d)
Default constructor: Sets RA, Dec and RA0, Dec0 according to arguments.
Definition skypoint.h:54
double minAlt(const dms &lat) const
Return the object's altitude at the lower culmination for the given latitude.
double vREarth(long double jd0)
Computes the velocity of any object projected on the direction of the source.
void setDec(dms d)
Sets Dec, the current Declination.
Definition skypoint.h:169
bool checkCircumpolar(const dms *gLat) const
Check if this point is circumpolar at the given geographic latitude.
void setRA(dms &r)
Sets RA, the current Right Ascension.
Definition skypoint.h:144
const CachingDms & ra() const
Definition skypoint.h:263
static dms findAltitude(const SkyPoint *p, const KStarsDateTime &dt, const GeoLocation *geo, const double hour=0)
Compute the altitude of a given skypoint hour hours from the given date/time.
dms altRefracted() const
void precess(const KSNumbers *num)
Precess this SkyPoint's catalog coordinates to the epoch described by the given KSNumbers object.
Definition skypoint.cpp:243
static SkyPoint timeTransformed(const SkyPoint *p, const KStarsDateTime &dt, const GeoLocation *geo, const double hour=0)
returns a time-transformed SkyPoint.
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 HorizontalToEquatorialNow()
Convenience method for Horizontal -> Equatorial at simulation time.
Definition skypoint.cpp:199
void addEterms(void)
Coordinates in the FK4 catalog include the effect of aberration due to the ellipticity of the orbit o...
Definition skypoint.cpp:903
double vGeoToVHelio(double vgeo, long double jd)
Computes the radial velocity of a source referred to the solar system barycenter from the velocity re...
void nutate(const KSNumbers *num, const bool reverse=false)
Apply the effects of nutation to this SkyPoint.
Definition skypoint.cpp:295
dms angularDistanceTo(const SkyPoint *sp, double *const positionAngle=nullptr) const
Computes the angular distance between two SkyObjects.
Definition skypoint.cpp:919
double vTopoToVGeo(double vtopo, double vsite[3])
Computes the radial velocity of a source referred to the center of the Earth from the radial velocity...
void B1950ToJ2000(void)
Exact precession from Besselian epoch 1950 to epoch J2000.
Definition skypoint.cpp:793
bool bendlight()
Correct for the effect of "bending" of light around the sun for positions near the sun.
Definition skypoint.cpp:445
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
SkyPoint moveAway(const SkyPoint &from, double dist) const
Find the SkyPoint obtained by moving distance dist (arcseconds) away from the givenSkyPoint.
Definition skypoint.cpp:391
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition skypoint.cpp:77
double vRSite(double vsite[3])
Computes the velocity of any object (observer's site) projected on the direction of the source.
static double unrefract(const double alt, bool conditional=true)
Remove refraction correction, depending on conditional.
double vRSun(long double jd)
Computes the velocity of the Sun projected on the direction of the source.
Definition skypoint.cpp:954
void HorizontalToEquatorialICRS(const dms *LST, const dms *lat, const long double jdf)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates,...
Definition skypoint.cpp:187
virtual void updateCoords(const KSNumbers *num, bool includePlanets=true, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, bool forceRecompute=false)
Determine the current coordinates (RA, Dec) from the catalog coordinates (RA0, Dec0),...
Definition skypoint.cpp:602
void set(const dms &r, const dms &d)
Sets RA, Dec and RA0, Dec0 according to arguments.
Definition skypoint.cpp:63
double vTopocentric(double vgeo, double vsite[3])
Computes the radial velocity of a source referred to the observer site on the surface of the earth fr...
void setAlt(dms alt)
Sets Alt, the Altitude.
Definition skypoint.h:194
double vHeliocentric(double vlsr, long double jd)
Computes the radial velocity of a source referred to the solar system barycenter from the radial velo...
Definition skypoint.cpp:992
const dms & alt() const
Definition skypoint.h:281
void HorizontalToEquatorial(const dms *LST, const dms *lat)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates,...
Definition skypoint.cpp:143
bool checkBendLight()
Check if this sky point is close enough to the sun for gravitational lensing to be significant.
Definition skypoint.cpp:419
SkyPoint Eterms(void)
Determine the E-terms of aberration In the past, the mean places of stars published in catalogs inclu...
Definition skypoint.cpp:888
void GalacticToEquatorial1950(const dms *galLong, const dms *galLat)
Computes equatorial coordinates referred to 1950 from galactic ones referred to epoch B1950.
Definition skypoint.cpp:774
double vGeocentric(double vhelio, long double jd)
Computes the radial velocity of a source referred to the center of the earth from the radial velocity...
void J2000ToB1950(void)
Exact precession from epoch J2000 Besselian epoch 1950.
Definition skypoint.cpp:839
double vHelioToVlsr(double vhelio, long double jd)
Computes the radial velocity of a source referred to the Local Standard of Rest, also known as VLSR f...
Definition skypoint.cpp:997
SkyPoint()
Default constructor.
Definition skypoint.cpp:53
void subtractEterms(void)
Coordinates in the FK4 catalog include the effect of aberration due to the ellipticity of the orbit o...
Definition skypoint.cpp:911
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
Definition skypoint.cpp:730
void Equatorial1950ToGalactic(dms &galLong, dms &galLat)
Computes galactic coordinates from equatorial coordinates referred to epoch 1950.
Definition skypoint.cpp:755
dms parallacticAngle(const CachingDms &LST, const CachingDms &lat)
Return the Parallactic Angle.
SkyPoint deprecess(const KSNumbers *num, long double epoch=J2000)
Obtain a Skypoint with RA0 and Dec0 set from the RA, Dec of this skypoint.
Definition skypoint.cpp:277
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
double cos() const
Compute the Angle's Cosine.
Definition dms.h:290
double Hours() const
Definition dms.h:168
void reduceToRange(enum dms::AngleRanges range)
Reduce this angle to the given range.
Definition dms.cpp:446
virtual void setH(const double &x)
Sets floating-point value of angle, in hours.
Definition dms.h:210
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
double sin() const
Compute the Angle's Sine.
Definition dms.h:258
static constexpr double DegToRad
DegToRad is a const static member equal to the number of radians in one degree (dms::PI/180....
Definition dms.h:390
QString i18n(const char *text, const TYPE &arg...)
void beginStructure()
void endStructure()
QTextStream & dec(QTextStream &stream)
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.