Kstars

projector.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Henry de Valence <hdevalence@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "projector.h"
8
9#include "ksutils.h"
10#ifdef KSTARS_LITE
11#include "skymaplite.h"
12#endif
13#include "skycomponents/skylabeler.h"
14
15namespace
16{
17void toXYZ(const SkyPoint *p, double *x, double *y, double *z)
18{
19 double sinRa, sinDec, cosRa, cosDec;
20
21 p->ra().SinCos(sinRa, cosRa);
22 p->dec().SinCos(sinDec, cosDec);
23 *x = cosDec * cosRa;
24 *y = cosDec * sinRa;
25 *z = sinDec;
26}
27}
28
30{
31 SkyPoint p;
32 p.setAz(az);
33 p.setAlt(0.0);
34 p.HorizontalToEquatorial(KStarsData::Instance()->lst(), KStarsData::Instance()->geo()->lat());
35 return p;
36}
37
39{
40 m_data = KStarsData::Instance();
42 // Force clip polygon update
44}
45
47{
48 m_vp = p;
49
50 /** Precompute cached values */
51 //Find Sin/Cos for focus point
52 m_sinY0 = 0;
53 m_cosY0 = 0;
54 if (m_vp.useAltAz)
55 {
56 // N.B. We explicitly check useRefraction and not use
57 // SkyPoint::altRefracted() here because it could be different
58 // from Options::useRefraction() in some future use-case
59 // --asimha
60 SkyPoint::refract(m_vp.focus->alt(), m_vp.useRefraction).SinCos(m_sinY0, m_cosY0);
61 }
62 else
63 {
64 m_vp.focus->dec().SinCos(m_sinY0, m_cosY0);
65 }
66
67 double currentFOV = m_fov;
68 //Find FOV in radians
69 m_fov = sqrt(m_vp.width * m_vp.width + m_vp.height * m_vp.height) / (2 * m_vp.zoomFactor * dms::DegToRad);
70 //Set checkVisibility variables
71 double Ymax;
72 m_xrange = 1.2 * m_fov / m_cosY0;
73 if (m_vp.useAltAz)
74 {
75 Ymax = fabs(SkyPoint::refract(m_vp.focus->alt().Degrees(), m_vp.useRefraction)) + m_fov;
76 }
77 else
78 {
79 Ymax = fabs(m_vp.focus->dec().Degrees()) + m_fov;
80 }
81 m_isPoleVisible = (Ymax >= 90.0);
82
83 // Only update clipping polygon if there is an FOV change
84 if (currentFOV != m_fov)
86}
87
88double Projector::fov() const
89{
90 return m_fov;
91}
92
94{
95 return KSUtils::vecToPoint(toScreenVec(o, oRefract, onVisibleHemisphere));
96}
97
98bool Projector::onScreen(const QPointF &p) const
99{
100 return (0 <= p.x() && p.x() <= m_vp.width && 0 <= p.y() && p.y() <= m_vp.height);
101}
102
103bool Projector::onScreen(const Eigen::Vector2f &p) const
104{
105 return onScreen(QPointF(p.x(), p.y()));
106}
107
109{
110 return KSUtils::vecToPoint(clipLineVec(p1, p2));
111}
112
113Eigen::Vector2f Projector::clipLineVec(SkyPoint *p1, SkyPoint *p2) const
114{
115 /* ASSUMES p1 was not clipped but p2 was.
116 * Return the QPoint that barely clips in the line twixt p1 and p2.
117 */
118 //TODO: iteration = ceil( 0.5*log2( w^2 + h^2) )??
119 // also possibly rewrite this
120 // --hdevalence
121 int iteration = 15; // For "perfect" clipping:
122 // 2^iterations should be >= max pixels/line
123 bool isVisible = true; // so we start at midpoint
124 SkyPoint mid;
125 Eigen::Vector2f oMid;
126 double x, y, z, dx, dy, dz, ra, dec;
127 int newx, newy, oldx, oldy;
128 oldx = oldy = -10000; // any old value that is not the first omid
129
130 toXYZ(p1, &x, &y, &z);
131 // -jbb printf("\np1: %6.4f %6.4f %6.4f\n", x, y, z);
132
133 toXYZ(p2, &dx, &dy, &dz);
134
135 // -jbb printf("p2: %6.4f %6.4f %6.4f\n", dx, dy, dz);
136 dx -= x;
137 dy -= y;
138 dz -= z;
139 // Successive approximation to point on line that just clips.
140 while (iteration-- > 0)
141 {
142 dx *= .5;
143 dy *= .5;
144 dz *= .5;
145 if (!isVisible) // move back toward visible p1
146 {
147 x -= dx;
148 y -= dy;
149 z -= dz;
150 }
151 else // move out toward clipped p2
152 {
153 x += dx;
154 y += dy;
155 z += dz;
156 }
157
158 // -jbb printf(" : %6.4f %6.4f %6.4f\n", x, y, z);
159 // [x, y, z] => [ra, dec]
160 ra = atan2(y, x);
161 dec = asin(z / sqrt(x * x + y * y + z * z));
162
163 mid = SkyPoint(ra * 12. / dms::PI, dec * 180. / dms::PI);
164 mid.EquatorialToHorizontal(m_data->lst(), m_data->geo()->lat());
165
166 oMid = toScreenVec(&mid, false, &isVisible);
167 //AND the result with checkVisibility to clip things going below horizon
168 isVisible &= checkVisibility(&mid);
169 newx = (int)oMid.x();
170 newy = (int)oMid.y();
171
172 // -jbb printf("new x/y: %4d %4d", newx, newy);
173 if ((oldx == newx) && (oldy == newy))
174 {
175 break;
176 }
177 oldx = newx;
178 oldy = newy;
179 }
180 return oMid;
181}
182
184{
185 //TODO deal with alternate projections
186 //not clear how this depends on projection
187 //FIXME do these heuristics actually work?
188
189 double dX, dY;
190
191 //Skip objects below the horizon if the ground is drawn
192 /* Is the cost of this conversion actually less than drawing it anyways?
193 * EquatorialToHorizontal takes 3 SinCos calls -- so 6 trig calls if not using GNU exts.
194 */
195 /*
196 if( m_vp.fillGround ) {
197 if( !m_vp.useAltAz )
198 p->EquatorialToHorizontal( m_data->lst(), m_data->geo()->lat() );
199 if( p->alt().Degrees() < -1.0 ) return false;
200 }
201 */ //Here we hope that the point has already been 'synchronized'
202 if (m_vp.fillGround /*&& m_vp.useAltAz*/ && p->alt().Degrees() <= SkyPoint::altCrit)
203 return false;
204
205 if (m_vp.useAltAz)
206 {
207 /** To avoid calculating refraction, we just use the unrefracted
208 altitude and add a 2-degree 'safety factor' */
209 dY = fabs(p->alt().Degrees() - m_vp.focus->alt().Degrees()) - 2.;
210 }
211 else
212 {
213 dY = fabs(p->dec().Degrees() - m_vp.focus->dec().Degrees());
214 }
215 if (m_isPoleVisible)
216 dY *= 0.75; //increase effective FOV when pole visible.
217 if (dY > m_fov)
218 return false;
219 if (m_isPoleVisible)
220 return true;
221
222 if (m_vp.useAltAz)
223 {
224 dX = fabs(p->az().Degrees() - m_vp.focus->az().Degrees());
225 }
226 else
227 {
228 dX = fabs(p->ra().Degrees() - m_vp.focus->ra().Degrees());
229 }
230 if (dX > 180.0)
231 dX = 360.0 - dX; // take shorter distance around sky
232
233 return dX < m_xrange;
234}
235
236// FIXME: There should be a MUCH more efficient way to do this (see EyepieceField for example)
237double Projector::findNorthPA(const SkyPoint *o, float x, float y) const
238{
239 //Find position angle of North using a test point displaced to the north
240 //displace by 100/zoomFactor radians (so distance is always 100 pixels)
241 //this is 5730/zoomFactor degrees
242 KStarsData *data = KStarsData::Instance();
243 double newDec = o->dec().Degrees() + 5730.0 / m_vp.zoomFactor;
244 if (newDec > 90.0)
245 newDec = 90.0;
246 SkyPoint test(o->ra().Hours(), newDec);
247 if (m_vp.useAltAz)
248 test.EquatorialToHorizontal(data->lst(), data->geo()->lat());
249 Eigen::Vector2f t = toScreenVec(&test);
250 float dx = t.x() - x;
251 float dy = y - t.y(); //backwards because QWidget Y-axis increases to the bottom (FIXME: Check)
252 // float dx = dx_ * m_vp.rotationAngle.cos() - dy_ * m_vp.rotationAngle.sin();
253 // float dy = dx_ * m_vp.rotationAngle.sin() + dy_ * m_vp.rotationAngle.cos();
254 float north;
255 if (dy)
256 {
257 north = atan2f(dx, dy) * 180.0 / dms::PI;
258 }
259 else
260 {
261 north = (dx > 0.0 ? -90.0 : 90.0);
262 }
263
264 return north;
265}
266
267double Projector::findPA(const SkyObject *o, float x, float y) const
268{
269 return (findNorthPA(o, x, y) + o->pa());
270}
271
272// FIXME: There should be a MUCH more efficient way to do this (see EyepieceField for example)
273double Projector::findZenithPA(const SkyPoint *o, float x, float y) const
274{
275 //Find position angle of North using a test point displaced to the north
276 //displace by 100/zoomFactor radians (so distance is always 100 pixels)
277 //this is 5730/zoomFactor degrees
278 KStarsData *data = KStarsData::Instance();
279 double newAlt = o->alt().Degrees() + 5730.0 / m_vp.zoomFactor;
280 if (newAlt > 90.0)
281 newAlt = 90.0;
282 SkyPoint test;
283 test.setAlt(newAlt);
284 test.setAz(o->az().Degrees());
285 if (!m_vp.useAltAz)
286 test.HorizontalToEquatorial(data->lst(), data->geo()->lat());
287 Eigen::Vector2f t = toScreenVec(&test);
288 float dx = t.x() - x;
289 float dy = y - t.y(); //backwards because QWidget Y-axis increases to the bottom (FIXME: Check)
290 // float dx = dx_ * m_vp.rotationAngle.cos() - dy_ * m_vp.rotationAngle.sin();
291 // float dy = dx_ * m_vp.rotationAngle.sin() + dy_ * m_vp.rotationAngle.cos();
292 float zenith;
293 if (dy)
294 {
295 zenith = atan2f(dx, dy) * 180.0 / dms::PI;
296 }
297 else
298 {
299 zenith = (dx > 0.0 ? -90.0 : 90.0);
300 }
301
302 return zenith;
303}
304
306{
308
309 static const QString horizonLabel = i18n("Horizon");
311 SkyLabeler::Instance()->getMargins(horizonLabel, &marginLeft, &marginRight, &marginTop, &marginBot);
312
313 //daz is 1/2 the width of the sky in degrees
314 double daz = 90.;
315 if (m_vp.useAltAz && m_vp.rotationAngle.reduce().Degrees() == 0.0)
316 {
317 daz = 0.5 * m_vp.width / (dms::DegToRad * m_vp.zoomFactor); //center to edge, in degrees
318 if (type() == Projector::Orthographic)
319 {
320 daz = daz * 1.4;
321 }
322 daz = qMin(qreal(90.0), daz);
323 }
324
325 double faz = m_vp.focus->az().Degrees();
326 double az1 = faz - daz;
327 double az2 = faz + daz;
328
329 bool allGround = true;
330 bool allSky = true;
331
332 bool inverted = ((m_vp.rotationAngle + 90.0_deg).reduce().Degrees() > 180.);
333
334 double inc = 1.0;
335 //Add points along horizon
336 for (double az = az1; az <= az2 + inc; az += inc)
337 {
338 SkyPoint p = pointAt(az);
339 bool visible = false;
340 Eigen::Vector2f o = toScreenVec(&p, false, &visible);
341 if (visible)
342 {
343 ground.append(o);
344 //Set the label point if this point is onscreen
345 if (labelpoint && o.x() < marginRight && o.y() > marginTop && o.y() < marginBot)
346 *labelpoint = p;
347
348 if (o.y() > 0.)
349 (inverted ? allSky : allGround) = false;
350 if (o.y() < m_vp.height)
351 (inverted ? allGround : allSky) = false;
352 }
353 }
354
355 if (allSky)
356 {
357 if (drawLabel)
358 *drawLabel = false;
360 }
361
362 if (allGround)
363 {
364 ground.clear();
365 ground.append(Eigen::Vector2f(-10., -10.));
366 ground.append(Eigen::Vector2f(m_vp.width + 10., -10.));
367 ground.append(Eigen::Vector2f(m_vp.width + 10., m_vp.height + 10.));
368 ground.append(Eigen::Vector2f(-10., m_vp.height + 10.));
369 if (drawLabel)
370 *drawLabel = false;
371 return ground;
372 }
373
374 if (m_vp.mirror)
375 std::reverse(ground.begin(), ground.end());
376
377 //In Gnomonic projection, or if sufficiently zoomed in, we can complete
378 //the ground polygon by simply adding offscreen points
379 //FIXME: not just gnomonic
380 if (daz < 25.0 || type() == Projector::Gnomonic)
381 {
382 const float completion_height = (inverted ?
383 -10.f : m_vp.height + 10.f);
384 ground.append(Eigen::Vector2f(m_vp.width + 10.f, ground.last().y()));
385 ground.append(Eigen::Vector2f(m_vp.width + 10.f, completion_height));
386 ground.append(Eigen::Vector2f(-10.f, completion_height));
387 ground.append(Eigen::Vector2f(-10.f, ground.first().y()));
388 }
389 else
390 {
391 double r = m_vp.zoomFactor * radius();
392 double t1 =
393 atan2(-1. * (ground.last().y() - 0.5 * m_vp.height), ground.last().x() - 0.5 * m_vp.width) / dms::DegToRad;
394 double t2 = t1 - 180.;
395 for (double t = t1; t >= t2; t -= inc) //step along circumference
396 {
397 dms a(t);
398 double sa(0.), ca(0.);
399 a.SinCos(sa, ca);
400 ground.append(Eigen::Vector2f(0.5 * m_vp.width + r * ca, 0.5 * m_vp.height - r * sa));
401 }
402 }
403
404 if (drawLabel)
405 *drawLabel = true;
406 return ground;
407}
408
410{
411 m_clipPolygon.clear();
412
413 double r = m_vp.zoomFactor * radius();
414 double t1 = 0;
415 double t2 = 360;
416 double inc = 1.0;
417 for (double t = t1; t <= t2; t += inc)
418 {
419 //step along circumference
420 dms a(t);
421 double sa(0.), ca(0.);
422 a.SinCos(sa, ca);
423 m_clipPolygon << QPointF(0.5 * m_vp.width + r * ca, 0.5 * m_vp.height - r * sa);
424 }
425}
426
428{
429 return m_clipPolygon;
430}
431
433{
434 //r0 is the angular size of the sky horizon, in radians
435 double r0 = radius();
436 //If the zoom is high enough, all points are usable
437 //The center-to-corner distance, in radians
438 double r = 0.5 * 1.41421356 * m_vp.width / m_vp.zoomFactor;
439 if (r < r0)
440 return false;
441 //At low zoom, we have to determine whether the point is beyond the sky horizon
442 //Convert pixel position to x and y offsets in radians
443
444 // N.B. Technically, rotation does not affect the dx² + dy²
445 // metric, but we use the derst method for uniformity; this
446 // function is not perf critical
447 auto p_ = derst(p.x(), p.y());
448 double dx = p_[0], dy = p_[1];
449 return (dx * dx + dy * dy) > r0 * r0;
450}
451
452SkyPoint Projector::fromScreen(const QPointF &p, dms *LST, const dms *lat, bool onlyAltAz) const
453{
454 dms c;
455 double sinc, cosc;
456 /** N.B. We don't cache these sin/cos values in the inverse
457 * projection because it causes 'shaking' when moving the sky.
458 */
459 double sinY0, cosY0;
460 //Convert pixel position to x and y offsets in radians
461 auto p_ = derst(p.x(), p.y());
462 double dx = p_[0], dy = p_[1];
463
464 double r = sqrt(dx * dx + dy * dy);
466 c.SinCos(sinc, cosc);
467
468 if (m_vp.useAltAz)
469 {
470 dx = -1.0 * dx; //Azimuth goes in opposite direction compared to RA
471 SkyPoint::refract(m_vp.focus->alt(), m_vp.useRefraction).SinCos(sinY0, cosY0);
472 }
473 else
474 {
475 m_vp.focus->dec().SinCos(sinY0, cosY0);
476 }
477
478 double Y = asin(cosc * sinY0 + (r == 0 ? 0 : (dy * sinc * cosY0) / r));
479 double atop = dx * sinc;
480 double abot = r * cosY0 * cosc - dy * sinY0 * sinc;
481 double A = atan2(atop, abot);
482
483 SkyPoint result;
484 if (m_vp.useAltAz)
485 {
486 dms alt, az;
487 alt.setRadians(Y);
488 az.setRadians(A + m_vp.focus->az().radians());
489 if (m_vp.useRefraction)
490 alt = SkyPoint::unrefract(alt);
491 result.setAlt(alt);
492 result.setAz(az);
493 if (onlyAltAz)
494 return result;
495 result.HorizontalToEquatorial(LST, lat);
496 }
497 else
498 {
499 dms ra, dec;
500 dec.setRadians(Y);
501 ra.setRadians(A + m_vp.focus->ra().radians());
502 result.set(ra.reduce(), dec);
503 result.EquatorialToHorizontal(LST, lat);
504 }
505
506 return result;
507}
508
509Eigen::Vector2f Projector::toScreenVec(const SkyPoint *o, bool oRefract, bool *onVisibleHemisphere) const
510{
511 double Y, dX;
512 double sindX, cosdX, sinY, cosY;
513
514 oRefract &= m_vp.useRefraction;
515 if (m_vp.useAltAz)
516 {
517 if (oRefract)
518 Y = SkyPoint::refract(o->alt()).radians(); //account for atmospheric refraction
519 else
520 Y = o->alt().radians();
521 dX = m_vp.focus->az().radians() - o->az().radians();
522 }
523 else
524 {
525 dX = o->ra().radians() - m_vp.focus->ra().radians();
526 Y = o->dec().radians();
527 }
528
529 if (!(std::isfinite(Y) && std::isfinite(dX)))
530 {
531 return Eigen::Vector2f(0, 0);
532
533 // JM: Enable this again later when trying to find a solution for it
534 // As it is now creating too much noise in the log file.
535 /*
536 qDebug() << Q_FUNC_INFO << "Assert in Projector::toScreenVec failed!";
537 qDebug() << Q_FUNC_INFO << "using AltAz?" << m_vp.useAltAz << " Refract? " << oRefract;
538 const SkyObject *obj;
539 qDebug() << Q_FUNC_INFO << "Point supplied has RA0 = " << o->ra0().toHMSString() << " Dec0 = " << o->dec0().toDMSString() << "; alt = " << o->alt().toDMSString() << "; az = " << o->az().toDMSString();
540 if ( (obj = dynamic_cast<const SkyObject *>(o) ) ) {
541 qDebug() << Q_FUNC_INFO << "Point is object with name = " << obj->name() << " longname = " << obj->longname();
542 }
543 qDebug() << Q_FUNC_INFO << "dX = " << dX << " and isfinite(dX) is" << std::isfinite(dX);
544 qDebug() << Q_FUNC_INFO << "Y = " << Y << " and isfinite(Y) is" << std::isfinite(Y);
545
546 //Q_ASSERT( false );
547 */
548 }
549
550 dX = KSUtils::reduceAngle(dX, -dms::PI, dms::PI);
551
552 //Convert dX, Y coords to screen pixel coords, using GNU extension if available
553#ifdef HAVE_SINCOS
554 sincos(dX, &sindX, &cosdX);
555 sincos(Y, &sinY, &cosY);
556#else
557 sindX = sin(dX);
558 cosdX = cos(dX);
559 sinY = sin(Y);
560 cosY = cos(Y);
561#endif
562
563 //c is the cosine of the angular distance from the center
564 double c = m_sinY0 * sinY + m_cosY0 * cosY * cosdX;
565
566 //If c is less than 0.0, then the "field angle" (angular distance from the focus)
567 //is more than 90 degrees. This is on the "back side" of the celestial sphere
568 //and should not be drawn.
571 (c >
572 cosMaxFieldAngle()); // TODO: Isn't it more efficient to bypass the final calculation below if the object is not visible?
573
574 double k = projectionK(c);
575
576 auto p = rst(k * cosY * sindX, k * (m_cosY0 * sinY - m_sinY0 * cosY * cosdX));
577
578#ifdef KSTARS_LITE
579 double skyRotation = SkyMapLite::Instance()->getSkyRotation();
580 // FIXME: Port above to change the m_vp.rotationAngle, or
581 // deprecate it
582 Q_ASSERT(false);
583#endif
584 return p;
585}
const CachingDms * lat() const
Definition geolocation.h:70
KStarsData is the backbone of KStars.
Definition kstarsdata.h:72
CachingDms * lst()
Definition kstarsdata.h:224
GeoLocation * geo()
Definition kstarsdata.h:230
Eigen::Vector2f derst(double x, double y) const
Transform screen (x, y) to projector (x, y) accounting for scale, rotation.
Definition projector.h:333
virtual double cosMaxFieldAngle() const
This function returns the cosine of the maximum field angle, i.e., the maximum angular distance from ...
Definition projector.h:296
virtual SkyPoint fromScreen(const QPointF &p, dms *LST, const dms *lat, bool onlyAltAz=false) const
Determine RA, Dec coordinates of the pixel at (dx, dy), which are the screen pixel coordinate offsets...
QPointF toScreen(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=nullptr) const
This is exactly the same as toScreenVec but it returns a QPointF.
Definition projector.cpp:93
Eigen::Vector2f rst(double x, double y) const
Transform proj (x, y) to screen (x, y) accounting for scale and rotation.
Definition projector.h:311
virtual double projectionK(double x) const
This function handles some of the projection-specific code.
Definition projector.h:277
double findZenithPA(const SkyPoint *o, float x, float y) const
Determine the on-screen angle of a SkyPoint with respect to Zenith.
double findPA(const SkyObject *o, float x, float y) const
Determine the on-screen position angle of a SkyObject.
virtual bool unusablePoint(const QPointF &p) const
Check if the current point on screen is a valid point on the sky.
bool onScreen(const QPointF &p) const
Check whether the projected point is on-screen.
Definition projector.cpp:98
virtual Eigen::Vector2f toScreenVec(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=nullptr) const
Given the coordinates of the SkyPoint argument, determine the pixel coordinates in the SkyMap.
Eigen::Vector2f clipLineVec(SkyPoint *p1, SkyPoint *p2) const
ASSUMES *p1 did not clip but *p2 did.
double findNorthPA(const SkyPoint *o, float x, float y) const
Determine the on-screen position angle of a SkyPont with recept with NCP.
virtual QPolygonF clipPoly() const
void setViewParams(const ViewParams &p)
Update cached values for projector.
Definition projector.cpp:46
static SkyPoint pointAt(double az)
Helper function for drawing ground.
Definition projector.cpp:29
double fov() const
Return the FOV of this projection.
Definition projector.cpp:88
bool checkVisibility(const SkyPoint *p) const
Determine if the skypoint p is likely to be visible in the display window.
virtual QVector< Eigen::Vector2f > groundPoly(SkyPoint *labelpoint=nullptr, bool *drawLabel=nullptr) const
Get the ground polygon.
virtual double projectionL(double x) const
This function handles some of the projection-specific code.
Definition projector.h:286
virtual double radius() const
Get the radius of this projection's sky circle.
Definition projector.h:268
QPointF clipLine(SkyPoint *p1, SkyPoint *p2) const
ASSUMES *p1 did not clip but *p2 did.
virtual Q_INVOKABLE Projection type() const =0
Return the type of this projection.
Projector(const ViewParams &p)
Constructor.
Definition projector.cpp:38
virtual void updateClipPoly()
updateClipPoly calculate the clipping polygen given the current FOV.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
virtual double pa() const
Definition skyobject.h:212
The sky coordinates of a point in the sky.
Definition skypoint.h:45
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:718
const CachingDms & dec() const
Definition skypoint.h:269
const CachingDms & ra() const
Definition skypoint.h:263
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
static double unrefract(const double alt, bool conditional=true)
Remove refraction correction, depending on conditional.
const dms & az() const
Definition skypoint.h:275
void set(const dms &r, const dms &d)
Sets RA, Dec and RA0, Dec0 according to arguments.
Definition skypoint.cpp:63
void setAlt(dms alt)
Sets Alt, the Altitude.
Definition skypoint.h:194
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
void setAz(dms az)
Sets Az, the Azimuth.
Definition skypoint.h:230
This is just a container that holds information needed to do projections.
Definition projector.h:37
bool fillGround
If the ground is filled, then points below horizon are invisible.
Definition projector.h:44
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:444
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
virtual void setRadians(const double &Rad)
Set angle according to the argument, in radians.
Definition dms.h:333
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...)
qreal x() const const
qreal y() const const
void clear()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:45:35 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.