Kstars

projector.cpp
1 /*
2  SPDX-FileCopyrightText: 2010 Henry de Valence <[email protected]>
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 
15 namespace
16 {
17 void 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();
41  setViewParams(p);
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 
88 double Projector::fov() const
89 {
90  return m_fov;
91 }
92 
93 QPointF Projector::toScreen(const SkyPoint *o, bool oRefract, bool *onVisibleHemisphere) const
94 {
95  return KSUtils::vecToPoint(toScreenVec(o, oRefract, onVisibleHemisphere));
96 }
97 
98 bool 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 
103 bool 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 
113 Eigen::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)
237 double 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 
267 double 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)
273 double 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 
305 QVector<Eigen::Vector2f> Projector::groundPoly(SkyPoint *labelpoint, bool *drawLabel) const
306 {
308 
309  static const QString horizonLabel = i18n("Horizon");
310  float marginLeft, marginRight, marginTop, marginBot;
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;
359  return QVector<Eigen::Vector2f>();
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  //In Gnomonic projection, or if sufficiently zoomed in, we can complete
375  //the ground polygon by simply adding offscreen points
376  //FIXME: not just gnomonic
377  if (daz < 25.0 || type() == Projector::Gnomonic)
378  {
379  const float completion_height = (inverted ?
380  -10.f : m_vp.height + 10.f);
381  ground.append(Eigen::Vector2f(m_vp.width + 10.f, ground.last().y()));
382  ground.append(Eigen::Vector2f(m_vp.width + 10.f, completion_height));
383  ground.append(Eigen::Vector2f(-10.f, completion_height));
384  ground.append(Eigen::Vector2f(-10.f, ground.first().y()));
385  }
386  else
387  {
388  double r = m_vp.zoomFactor * radius();
389  double t1 =
390  atan2(-1. * (ground.last().y() - 0.5 * m_vp.height), ground.last().x() - 0.5 * m_vp.width) / dms::DegToRad;
391  double t2 = t1 - 180.;
392  for (double t = t1; t >= t2; t -= inc) //step along circumference
393  {
394  dms a(t);
395  double sa(0.), ca(0.);
396  a.SinCos(sa, ca);
397  ground.append(Eigen::Vector2f(0.5 * m_vp.width + r * ca, 0.5 * m_vp.height - r * sa));
398  }
399  }
400 
401  if (drawLabel)
402  *drawLabel = true;
403  return ground;
404 }
405 
407 {
408  m_clipPolygon.clear();
409 
410  double r = m_vp.zoomFactor * radius();
411  double t1 = 0;
412  double t2 = 360;
413  double inc = 1.0;
414  for (double t = t1; t <= t2; t += inc)
415  {
416  //step along circumference
417  dms a(t);
418  double sa(0.), ca(0.);
419  a.SinCos(sa, ca);
420  m_clipPolygon << QPointF(0.5 * m_vp.width + r * ca, 0.5 * m_vp.height - r * sa);
421  }
422 }
423 
425 {
426  return m_clipPolygon;
427 }
428 
429 bool Projector::unusablePoint(const QPointF &p) const
430 {
431  //r0 is the angular size of the sky horizon, in radians
432  double r0 = radius();
433  //If the zoom is high enough, all points are usable
434  //The center-to-corner distance, in radians
435  double r = 0.5 * 1.41421356 * m_vp.width / m_vp.zoomFactor;
436  if (r < r0)
437  return false;
438  //At low zoom, we have to determine whether the point is beyond the sky horizon
439  //Convert pixel position to x and y offsets in radians
440 
441  // N.B. Technically, rotation does not affect the dx² + dy²
442  // metric, but we use the derst method for uniformity; this
443  // function is not perf critical
444  auto p_ = derst(p.x(), p.y());
445  double dx = p_[0], dy = p_[1];
446  return (dx * dx + dy * dy) > r0 * r0;
447 }
448 
449 SkyPoint Projector::fromScreen(const QPointF &p, dms *LST, const dms *lat, bool onlyAltAz) const
450 {
451  dms c;
452  double sinc, cosc;
453  /** N.B. We don't cache these sin/cos values in the inverse
454  * projection because it causes 'shaking' when moving the sky.
455  */
456  double sinY0, cosY0;
457  //Convert pixel position to x and y offsets in radians
458  auto p_ = derst(p.x(), p.y());
459  double dx = p_[0], dy = p_[1];
460 
461  double r = sqrt(dx * dx + dy * dy);
462  c.setRadians(projectionL(r));
463  c.SinCos(sinc, cosc);
464 
465  if (m_vp.useAltAz)
466  {
467  dx = -1.0 * dx; //Azimuth goes in opposite direction compared to RA
468  SkyPoint::refract(m_vp.focus->alt(), m_vp.useRefraction).SinCos(sinY0, cosY0);
469  }
470  else
471  {
472  m_vp.focus->dec().SinCos(sinY0, cosY0);
473  }
474 
475  double Y = asin(cosc * sinY0 + (r == 0 ? 0 : (dy * sinc * cosY0) / r));
476  double atop = dx * sinc;
477  double abot = r * cosY0 * cosc - dy * sinY0 * sinc;
478  double A = atan2(atop, abot);
479 
480  SkyPoint result;
481  if (m_vp.useAltAz)
482  {
483  dms alt, az;
484  alt.setRadians(Y);
485  az.setRadians(A + m_vp.focus->az().radians());
486  if (m_vp.useRefraction)
487  alt = SkyPoint::unrefract(alt);
488  result.setAlt(alt);
489  result.setAz(az);
490  if (onlyAltAz)
491  return result;
492  result.HorizontalToEquatorial(LST, lat);
493  }
494  else
495  {
496  dms ra, dec;
497  dec.setRadians(Y);
498  ra.setRadians(A + m_vp.focus->ra().radians());
499  result.set(ra.reduce(), dec);
500  result.EquatorialToHorizontal(LST, lat);
501  }
502 
503  return result;
504 }
505 
506 Eigen::Vector2f Projector::toScreenVec(const SkyPoint *o, bool oRefract, bool *onVisibleHemisphere) const
507 {
508  double Y, dX;
509  double sindX, cosdX, sinY, cosY;
510 
511  oRefract &= m_vp.useRefraction;
512  if (m_vp.useAltAz)
513  {
514  if (oRefract)
515  Y = SkyPoint::refract(o->alt()).radians(); //account for atmospheric refraction
516  else
517  Y = o->alt().radians();
518  dX = m_vp.focus->az().radians() - o->az().radians();
519  }
520  else
521  {
522  dX = o->ra().radians() - m_vp.focus->ra().radians();
523  Y = o->dec().radians();
524  }
525 
526  if (!(std::isfinite(Y) && std::isfinite(dX)))
527  {
528  return Eigen::Vector2f(0, 0);
529 
530  // JM: Enable this again later when trying to find a solution for it
531  // As it is now creating too much noise in the log file.
532  /*
533  qDebug() << Q_FUNC_INFO << "Assert in Projector::toScreenVec failed!";
534  qDebug() << Q_FUNC_INFO << "using AltAz?" << m_vp.useAltAz << " Refract? " << oRefract;
535  const SkyObject *obj;
536  qDebug() << Q_FUNC_INFO << "Point supplied has RA0 = " << o->ra0().toHMSString() << " Dec0 = " << o->dec0().toDMSString() << "; alt = " << o->alt().toDMSString() << "; az = " << o->az().toDMSString();
537  if ( (obj = dynamic_cast<const SkyObject *>(o) ) ) {
538  qDebug() << Q_FUNC_INFO << "Point is object with name = " << obj->name() << " longname = " << obj->longname();
539  }
540  qDebug() << Q_FUNC_INFO << "dX = " << dX << " and isfinite(dX) is" << std::isfinite(dX);
541  qDebug() << Q_FUNC_INFO << "Y = " << Y << " and isfinite(Y) is" << std::isfinite(Y);
542 
543  //Q_ASSERT( false );
544  */
545  }
546 
547  dX = KSUtils::reduceAngle(dX, -dms::PI, dms::PI);
548 
549  //Convert dX, Y coords to screen pixel coords, using GNU extension if available
550 #ifdef HAVE_SINCOS
551  sincos(dX, &sindX, &cosdX);
552  sincos(Y, &sinY, &cosY);
553 #else
554  sindX = sin(dX);
555  cosdX = cos(dX);
556  sinY = sin(Y);
557  cosY = cos(Y);
558 #endif
559 
560  //c is the cosine of the angular distance from the center
561  double c = m_sinY0 * sinY + m_cosY0 * cosY * cosdX;
562 
563  //If c is less than 0.0, then the "field angle" (angular distance from the focus)
564  //is more than 90 degrees. This is on the "back side" of the celestial sphere
565  //and should not be drawn.
566  if (onVisibleHemisphere)
567  *onVisibleHemisphere =
568  (c >
569  cosMaxFieldAngle()); // TODO: Isn't it more efficient to bypass the final calculation below if the object is not visible?
570 
571  double k = projectionK(c);
572 
573  auto p = rst(k * cosY * sindX, k * (m_cosY0 * sinY - m_sinY0 * cosY * cosdX));
574 
575 #ifdef KSTARS_LITE
576  double skyRotation = SkyMapLite::Instance()->getSkyRotation();
577  // FIXME: Port above to change the m_vp.rotationAngle, or
578  // deprecate it
579  Q_ASSERT(false);
580 #endif
581  return p;
582 }
static double unrefract(const double alt, bool conditional=true)
Remove refraction correction, depending on conditional.
Definition: skypoint.cpp:1091
const dms & alt() const
Definition: skypoint.h:281
void setAlt(dms alt)
Sets Alt, the Altitude.
Definition: skypoint.h:194
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
T & last()
virtual void updateClipPoly()
updateClipPoly calculate the clipping polygen given the current FOV.
Definition: projector.cpp:406
double findPA(const SkyObject *o, float x, float y) const
Determine the on-screen position angle of a SkyObject.
Definition: projector.cpp:267
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
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
virtual double projectionK(double x) const
This function handles some of the projection-specific code.
Definition: projector.h:276
Projector(const ViewParams &p)
Constructor.
Definition: projector.cpp:38
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.
Definition: projector.cpp:506
void SinCos(double &s, double &c) const
Get the sine and cosine together.
Definition: cachingdms.h:175
void append(const T &value)
void SinCos(double &s, double &c) const
Compute Sine and Cosine of the angle simultaneously.
Definition: dms.h:444
CachingDms * lst()
Definition: kstarsdata.h:224
virtual double cosMaxFieldAngle() const
This function returns the cosine of the maximum field angle, i.e., the maximum angular distance from ...
Definition: projector.h:295
QPointF clipLine(SkyPoint *p1, SkyPoint *p2) const
ASSUMES *p1 did not clip but *p2 did.
Definition: projector.cpp:108
static double refract(const double alt, bool conditional=true)
Apply refraction correction to altitude, depending on conditional.
Definition: skypoint.cpp:1070
T & first()
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
Eigen::Vector2f clipLineVec(SkyPoint *p1, SkyPoint *p2) const
ASSUMES *p1 did not clip but *p2 did.
Definition: projector.cpp:113
virtual double pa() const
Definition: skyobject.h:212
virtual Q_INVOKABLE Projection type() const =0
Return the type of this projection.
bool onScreen(const QPointF &p) const
Check whether the projected point is on-screen.
Definition: projector.cpp:98
void clear()
QString i18n(const char *text, const TYPE &arg...)
const CachingDms & dec() const
Definition: skypoint.h:269
const CachingDms * lat() const
Definition: geolocation.h:70
Eigen::Vector2f derst(double x, double y) const
Transform screen (x, y) to projector (x, y) accounting for scale, rotation.
Definition: projector.h:331
virtual bool unusablePoint(const QPointF &p) const
Check if the current point on screen is a valid point on the sky.
Definition: projector.cpp:429
Eigen::Vector2f rst(double x, double y) const
Transform proj (x, y) to screen (x, y) accounting for scale and rotation.
Definition: projector.h:310
GeoLocation * geo()
Definition: kstarsdata.h:230
This is just a container that holds information needed to do projections.
Definition: projector.h:36
double findNorthPA(const SkyPoint *o, float x, float y) const
Determine the on-screen position angle of a SkyPont with recept with NCP.
Definition: projector.cpp:237
void getMargins(const QString &text, float *left, float *right, float *top, float *bot)
sets four margins for help in keeping labels entirely on the screen.
Definition: skylabeler.cpp:227
static const double altCrit
Critical height for atmospheric refraction corrections.
Definition: skypoint.h:718
void set(const dms &r, const dms &d)
Sets RA, Dec and RA0, Dec0 according to arguments.
Definition: skypoint.cpp:63
bool fillGround
If the ground is filled, then points below horizon are invisible.
Definition: projector.h:44
void setViewParams(const ViewParams &p)
Update cached values for projector.
Definition: projector.cpp:46
An angle, stored as degrees, but expressible in many ways.
Definition: dms.h:37
virtual void setRadians(const double &Rad)
Set angle according to the argument, in radians.
Definition: dms.h:333
void setAz(dms az)
Sets Az, the Azimuth.
Definition: skypoint.h:230
virtual QVector< Eigen::Vector2f > groundPoly(SkyPoint *labelpoint=nullptr, bool *drawLabel=nullptr) const
Get the ground polygon.
Definition: projector.cpp:305
double findZenithPA(const SkyPoint *o, float x, float y) const
Determine the on-screen angle of a SkyPoint with respect to Zenith.
Definition: projector.cpp:273
qreal x() const const
qreal y() const const
const CachingDms & ra() const
Definition: skypoint.h:263
double radians() const
Express the angle in radians.
Definition: dms.h:325
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...
Definition: projector.cpp:449
double fov() const
Return the FOV of this projection.
Definition: projector.cpp:88
const double & Degrees() const
Definition: dms.h:141
virtual QPolygonF clipPoly() const
Definition: projector.cpp:424
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
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
const dms reduce() const
return the equivalent angle between 0 and 360 degrees.
Definition: dms.cpp:251
virtual double projectionL(double x) const
This function handles some of the projection-specific code.
Definition: projector.h:285
static SkyPoint pointAt(double az)
Helper function for drawing ground.
Definition: projector.cpp:29
Information about an object in the sky.
Definition: skyobject.h:41
double Hours() const
Definition: dms.h:168
bool checkVisibility(const SkyPoint *p) const
Determine if the skypoint p is likely to be visible in the display window.
Definition: projector.cpp:183
const dms & az() const
Definition: skypoint.h:275
virtual double radius() const
Get the radius of this projection's sky circle.
Definition: projector.h:267
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Sep 26 2023 03:55:49 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.