Kstars

skymesh.cpp
1 /*
2  SPDX-FileCopyrightText: 2007 James B. Bowlin <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "skymesh.h"
8 
9 #include "kstarsdata.h"
10 #ifndef KSTARS_LITE
11 #include "skymap.h"
12 #endif
13 #include "htmesh/MeshIterator.h"
14 #include "htmesh/MeshBuffer.h"
15 #include "projections/projector.h"
16 #include "skyobjects/starobject.h"
17 
18 #include <QPainter>
19 #include <QPolygonF>
20 #include <QPointF>
21 
22 QMap<int, SkyMesh *> SkyMesh::pinstances;
23 int SkyMesh::defaultLevel = -1;
24 
26 {
27  SkyMesh *newInstance = pinstances.value(level, nullptr);
28  if (newInstance != nullptr)
29  return newInstance;
30 
31  newInstance = new SkyMesh(level);
32  pinstances.insert(level, newInstance);
33  if (defaultLevel < 0)
34  defaultLevel = newInstance->level();
35 
36  return newInstance;
37 }
38 
40 {
41  return pinstances.value(defaultLevel, nullptr);
42 }
43 
45 {
46  return pinstances.value(level, nullptr);
47 }
48 
49 SkyMesh::SkyMesh(int level)
50  : HTMesh(level, level, NUM_MESH_BUF), m_drawID(0), m_KSNumbers(0)
51 {
52  errLimit = HTMesh::size() / 4;
53  m_inDraw = false;
54 }
55 
56 void SkyMesh::aperture(SkyPoint *p0, double radius, MeshBufNum_t bufNum)
57 {
58  KStarsData *data = KStarsData::Instance();
59  // FIXME: simple copying leads to incorrect results because RA0 && dec0 are both zero sometimes
60  SkyPoint p1(p0->ra(), p0->dec());
61  long double now = data->updateNum()->julianDay();
62  p1.catalogueCoord(now);
63 
64  if (radius == 1.0)
65  {
66  SkyPoint p2 = p1;
67  p2.updateCoordsNow(data->updateNum());
68  }
69 
70  HTMesh::intersect(p1.ra().Degrees(), p1.dec().Degrees(), radius, (BufNum)bufNum);
71  m_drawID++;
72 }
73 
74 Trixel SkyMesh::index(const SkyPoint *p)
75 {
76  return HTMesh::index(p->ra0().Degrees(), p->dec0().Degrees());
77 }
78 
80 {
81  double ra, dec;
82  star->getIndexCoords(&m_KSNumbers, &ra, &dec);
83  return HTMesh::index(ra, dec);
84 }
85 
87 {
88  double ra1, ra2, dec1, dec2;
89  star1->getIndexCoords(&m_KSNumbers, &ra1, &dec1);
90  star2->getIndexCoords(&m_KSNumbers, &ra2, &dec2);
91  HTMesh::intersect(ra1, dec1, ra2, dec2);
92 }
93 
94 void SkyMesh::index(const SkyPoint *p, double radius, MeshBufNum_t bufNum)
95 {
96  HTMesh::intersect(p->ra().Degrees(), p->dec().Degrees(), radius, (BufNum)bufNum);
97 }
98 
99 void SkyMesh::index(const SkyPoint *p1, const SkyPoint *p2)
100 {
101  HTMesh::intersect(p1->ra0().Degrees(), p1->dec0().Degrees(), p2->ra0().Degrees(), p2->dec0().Degrees());
102 }
103 
104 void SkyMesh::index(const SkyPoint *p1, const SkyPoint *p2, const SkyPoint *p3)
105 {
106  HTMesh::intersect(p1->ra0().Degrees(), p1->dec0().Degrees(), p2->ra0().Degrees(), p2->dec0().Degrees(),
107  p3->ra0().Degrees(), p3->dec0().Degrees());
108 }
109 
110 void SkyMesh::index(const SkyPoint *p1, const SkyPoint *p2, const SkyPoint *p3, const SkyPoint *p4)
111 {
112  HTMesh::intersect(p1->ra0().Degrees(), p1->dec0().Degrees(), p2->ra0().Degrees(), p2->dec0().Degrees(),
113  p3->ra0().Degrees(), p3->dec0().Degrees(), p4->ra0().Degrees(), p4->dec0().Degrees());
114 }
115 
116 void SkyMesh::index(const QPointF &p1, const QPointF &p2, const QPointF &p3)
117 {
118  HTMesh::intersect(p1.x() * 15.0, p1.y(), p2.x() * 15.0, p2.y(), p3.x() * 15.0, p3.y());
119 }
120 
121 void SkyMesh::index(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
122 {
123  HTMesh::intersect(p1.x() * 15.0, p1.y(), p2.x() * 15.0, p2.y(), p3.x() * 15.0, p3.y(), p4.x() * 15.0, p4.y());
124 }
125 
127 {
128  return indexLine(points, nullptr);
129 }
130 
132 {
133  SkyPoint *pThis, *pLast;
134 
135  indexHash.clear();
136 
137  if (points->isEmpty())
138  return indexHash;
139 
140  pLast = points->at(0).get();
141  for (int i = 1; i < points->size(); i++)
142  {
143  pThis = points->at(i).get();
144 
145  indexStar((StarObject *)pThis, (StarObject *)pLast);
146  MeshIterator region(this);
147 
148  while (region.hasNext())
149  {
150  indexHash[region.next()] = true;
151  }
152  pLast = pThis;
153  }
154  return indexHash;
155 }
156 
158 {
159  SkyPoint *pThis, *pLast;
160 
161  indexHash.clear();
162 
163  if (points->isEmpty())
164  return indexHash;
165 
166  pLast = points->at(0).get();
167  for (int i = 1; i < points->size(); i++)
168  {
169  pThis = points->at(i).get();
170 
171  if (skip != nullptr && skip->contains(i))
172  {
173  pLast = pThis;
174  continue;
175  }
176 
177  index(pThis, pLast);
178  MeshIterator region(this);
179 
180  if (region.size() > errLimit)
181  {
182  HTMesh::setDebug(10);
183  index(pThis, pLast);
184  HTMesh::setDebug(0);
185  }
186 
187  // This was used to track down a bug in my HTMesh code. The bug was caught
188  // and fixed but I've left this debugging code in for now. -jbb
189 
190  else
191  {
192  while (region.hasNext())
193  {
194  indexHash[region.next()] = true;
195  }
196  }
197  pLast = pThis;
198  }
199  return indexHash;
200 }
201 
202 // ----- Create HTMesh Index for Polygons -----
203 // Create (mostly) 4-point polygons that cover the mw polygon and
204 // all share the same first vertex. Use indexHash to eliminate
205 // the many duplicate indices that are generated with this procedure.
206 // There are probably faster and better ways to do this.
207 
209 {
210  indexHash.clear();
211 
212  if (points->size() < 3)
213  return indexHash;
214 
215  SkyPoint *startP = points->first().get();
216 
217  int end = points->size() - 2; // 1) size - 1 -> last index,
218  // 2) minimum of 2 points
219 
220  for (int p = 1; p <= end; p += 2)
221  {
222  if (p == end)
223  {
224  index(startP, points->at(p).get(), points->at(p + 1).get());
225  }
226  else
227  {
228  index(startP, points->at(p).get(), points->at(p + 1).get(), points->at(p + 2).get());
229  }
230 
231  MeshIterator region(this);
232  while (region.hasNext())
233  {
234  indexHash[region.next()] = true;
235  }
236  }
237  return indexHash;
238 }
239 
241 {
242  indexHash.clear();
243 
244  if (points->size() < 3)
245  return indexHash;
246 
247  const QPointF startP = points->first();
248 
249  int end = points->size() - 2; // 1) size - 1 -> last index,
250  // 2) minimum of 2 points
251  for (int p = 1; p <= end; p += 2)
252  {
253  if (p == end)
254  {
255  index(startP, points->at(p), points->at(p + 1));
256  }
257  else
258  {
259  index(startP, points->at(p), points->at(p + 1), points->at(p + 2));
260  }
261 
262  MeshIterator region(this);
263  while (region.hasNext())
264  {
265  indexHash[region.next()] = true;
266  }
267  }
268  return indexHash;
269 }
270 
271 // NOTE: SkyMesh::draw() is primarily used for debugging purposes, to
272 // show the trixels to enable visualizing them. Thus, it is not
273 // necessary that this be compatible with GL unless we abandon the
274 // QPainter some day, or the need arises to use this for some other
275 // purpose. -- asimha
276 void SkyMesh::draw(QPainter &psky, MeshBufNum_t bufNum)
277 {
278 #ifndef KSTARS_LITE
279  SkyMap *map = SkyMap::Instance();
280  KStarsData *data = KStarsData::Instance();
281 
282  double r1, d1, r2, d2, r3, d3;
283 
284  MeshIterator region(this, bufNum);
285  while (region.hasNext())
286  {
287  Trixel trixel = region.next();
288  vertices(trixel, &r1, &d1, &r2, &d2, &r3, &d3);
289  SkyPoint s1(r1 / 15.0, d1);
290  SkyPoint s2(r2 / 15.0, d2);
291  SkyPoint s3(r3 / 15.0, d3);
292  s1.EquatorialToHorizontal(data->lst(), data->geo()->lat());
293  s2.EquatorialToHorizontal(data->lst(), data->geo()->lat());
294  s3.EquatorialToHorizontal(data->lst(), data->geo()->lat());
295  QPointF q1 = map->projector()->toScreen(&s1);
296  QPointF q2 = map->projector()->toScreen(&s2);
297  QPointF q3 = map->projector()->toScreen(&s3);
298  psky.drawLine(q1, q2);
299  psky.drawLine(q2, q3);
300  psky.drawLine(q3, q1);
301  // Draw the name of the trixel
302  QString TrixelNumberString;
303  TrixelNumberString.setNum(trixel);
304  psky.drawText((q1 + q2 + q3) / 3.0, TrixelNumberString);
305  }
306 #else
307  Q_UNUSED(psky);
308  Q_UNUSED(bufNum);
309 #endif
310 }
311 
312 const SkyRegion &SkyMesh::skyRegion(const SkyPoint &_p1, const SkyPoint &_p2)
313 {
314  std::shared_ptr<SkyPoint> p1(new SkyPoint(_p1));
315  std::shared_ptr<SkyPoint> p2(new SkyPoint(_p2));
316  std::shared_ptr<SkyPoint> p3(new SkyPoint(p1->ra(), p2->dec()));
317  std::shared_ptr<SkyPoint> p4(new SkyPoint(p2->ra(), p1->dec()));
318  SkyList skylist;
319 
320  skylist.push_back(p1);
321  skylist.push_back(p2);
322  skylist.push_back(p3);
323  skylist.push_back(p4);
324  return indexPoly(&skylist);
325 }
bool isEmpty() const const
const T value(const Key &key, const T &defaultValue) const const
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
bool getIndexCoords(const KSNumbers *num, CachingDms &ra, CachingDms &dec)
Fills ra and dec with the coordinates of the star with the proper motion correction but without preci...
Definition: starobject.cpp:290
void aperture(SkyPoint *center, double radius, MeshBufNum_t bufNum=DRAW_BUF)
finds the set of trixels that cover the circular aperture specified after first performing a reverse ...
Definition: skymesh.cpp:56
void draw(QPainter &psky, MeshBufNum_t bufNum=DRAW_BUF)
Draws the outline of all the trixels in the specified buffer.
Definition: skymesh.cpp:276
void push_back(const T &value)
void clear()
CachingDms * lst()
Definition: kstarsdata.h:224
void intersect(double ra, double dec, double radius, BufNum bufNum=0)
NOTE: The intersect() routines below are all used to find the trixels needed to cover a geometric obj...
Definition: HTMesh.cpp:104
const IndexHash & indexStarLine(SkyList *points)
Fills a hash with all the trixels needed to cover all the line segments in the SkyList where each Sky...
Definition: skymesh.cpp:131
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
void drawText(const QPointF &position, const QString &text)
Definition: HTMesh.h:56
int size() const
returns the number of trixels stored
Definition: MeshIterator.h:35
QMap::iterator insert(const Key &key, const T &value)
void setDebug(int debug)
sets the debug level which is used to print out intermediate results in the line intersection routine...
Definition: HTMesh.h:127
QString & setNum(short n, int base)
const CachingDms & dec() const
Definition: skypoint.h:269
const CachingDms * lat() const
Definition: geolocation.h:70
Trixel indexStar(StarObject *star)
returns the trixel that contains the star at the set time with proper motion taken into account but n...
Definition: skymesh.cpp:79
subclass of SkyObject specialized for stars.
Definition: starobject.h:32
const T & at(int i) const const
GeoLocation * geo()
Definition: kstarsdata.h:230
long double julianDay() const
Definition: ksnumbers.h:91
Trixel index(double ra, double dec) const
returns the index of the trixel that contains the specified point.
Definition: HTMesh.cpp:72
int size() const
returns the total number of trixels in the HTM.
Definition: HTMesh.h:118
virtual void updateCoordsNow(const KSNumbers *num)
updateCoordsNow Shortcut for updateCoords( const KSNumbers *num, false, nullptr, nullptr,...
Definition: skypoint.h:382
int level() const
returns the mesh level.
Definition: HTMesh.h:122
const IndexHash & indexPoly(SkyList *points)
fills a QHash with the trixel indices needed to cover the polygon specified in the QList<SkyPoints*> ...
Definition: skymesh.cpp:208
bool hasNext() const
true if there are more trixel to iterate over.
Definition: MeshIterator.h:27
static SkyMesh * Instance()
returns the default instance of SkyMesh or null if it has not yet been created.
Definition: skymesh.cpp:39
const SkyRegion & skyRegion(const SkyPoint &p1, const SkyPoint &p2)
returns the sky region needed to cover the rectangle defined by two SkyPoints p1 and p2
Definition: skymesh.cpp:312
qreal x() const const
qreal y() const const
const CachingDms & ra() const
Definition: skypoint.h:263
const CachingDms & dec0() const
Definition: skypoint.h:257
const double & Degrees() const
Definition: dms.h:141
Canvas widget for displaying the sky bitmap; also handles user interaction events.
Definition: skymap.h:53
void drawLine(const QLineF &line)
const CachingDms & ra0() const
Definition: skypoint.h:251
int size() const const
const IndexHash & indexLine(SkyList *points)
fills a QHash with the trixel indices needed to cover all the line segments specified in the QVector<...
Definition: skymesh.cpp:126
bool contains(const Key &key) const const
Trixel index(const SkyPoint *p)
returns the index of the trixel containing p.
Definition: skymesh.cpp:74
static SkyMesh * Create(int level)
creates the single instance of SkyMesh.
Definition: skymesh.cpp:25
SkyPoint catalogueCoord(long double jdf)
Computes the J2000.0 catalogue coordinates for this SkyPoint using the epoch removing aberration,...
Definition: skypoint.cpp:710
Trixel next() const
returns the next trixel
Definition: MeshIterator.h:31
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Sep 27 2023 04:02:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.