Kstars

skymesh.cpp
1/*
2 SPDX-FileCopyrightText: 2007 James B. Bowlin <bowlin@mindspring.com>
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
22QMap<int, SkyMesh *> SkyMesh::pinstances;
23int 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
49SkyMesh::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
56void 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
74Trixel 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
94void 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
99void 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
104void 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
110void 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
116void 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
121void 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 {
183 index(pThis, pLast);
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
276void 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
312const 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}
const CachingDms * lat() const
Definition geolocation.h:70
HTMesh was originally intended to be a simple interface to the HTM library for the KStars project tha...
Definition HTMesh.h:57
int size() const
returns the total number of trixels in the HTM.
Definition HTMesh.h:118
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
Trixel index(double ra, double dec) const
returns the index of the trixel that contains the specified point.
Definition HTMesh.cpp:72
int level() const
returns the mesh level.
Definition HTMesh.h:122
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
long double julianDay() const
Definition ksnumbers.h:91
KStarsData is the backbone of KStars.
Definition kstarsdata.h:74
CachingDms * lst()
Definition kstarsdata.h:226
GeoLocation * geo()
Definition kstarsdata.h:232
MeshIterator is a very lightweight class used to iterate over the result set of an HTMesh intersectio...
Trixel next() const
returns the next trixel
bool hasNext() const
true if there are more trixel to iterate over.
int size() const
returns the number of trixels stored
This is the canvas on which the sky is painted.
Definition skymap.h:54
Provides an interface to the Hierarchical Triangular Mesh (HTM) library written by A.
Definition skymesh.h:74
void draw(QPainter &psky, MeshBufNum_t bufNum=DRAW_BUF)
Draws the outline of all the trixels in the specified buffer.
Definition skymesh.cpp:276
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
static SkyMesh * Instance()
returns the default instance of SkyMesh or null if it has not yet been created.
Definition skymesh.cpp:39
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
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
static SkyMesh * Create(int level)
creates the single instance of SkyMesh.
Definition skymesh.cpp:25
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
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
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
Trixel index(const SkyPoint *p)
returns the index of the trixel containing p.
Definition skymesh.cpp:74
This is a subclass of SkyObject.
Definition starobject.h:33
bool getIndexCoords(const double julianMillenia, CachingDms &ra, CachingDms &dec) const
Fills ra and dec with the coordinates of the star with the proper motion correction but without preci...
void clear()
bool contains(const Key &key) const const
const_reference at(qsizetype i) const const
T & first()
qsizetype size() const const
iterator insert(const Key &key, const T &value)
T value(const Key &key, const T &defaultValue) const const
void drawLine(const QLine &line)
void drawText(const QPoint &position, const QString &text)
qreal x() const const
qreal y() const const
QString & setNum(double n, char format, int precision)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:16:41 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.