Warning, file /education/kstars/kstars/skycomponents/skymesh.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2007 James B. Bowlin <bowlin@mindspring.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "ksnumbers.h" 0010 #include "typedef.h" 0011 #include "htmesh/HTMesh.h" 0012 0013 #include <QMap> 0014 0015 class QPainter; 0016 class QPointF; 0017 class QPolygonF; 0018 0019 class KSNumbers; 0020 class SkyPoint; 0021 class StarObject; 0022 0023 // These enums control the trixel storage. Separate buffers are available for 0024 // indexing and intersecting. Currently only one buffer is required. Multiple 0025 // buffers could be used for intermingling drawing and searching or to have a 0026 // non-precessed aperture for objects that don't precess. If a buffer number 0027 // is greater than or equal to NUM_BUF a brief error message will be printed 0028 // and then KStars will crash. This is a feature, not a bug. 0029 0030 enum MeshBufNum_t 0031 { 0032 DRAW_BUF = 0, 0033 NO_PRECESS_BUF = 1, 0034 OBJ_NEAREST_BUF = 2, 0035 IN_CONSTELL_BUF = 3, 0036 NUM_MESH_BUF 0037 }; 0038 0039 /** @class SkyMesh 0040 * Provides an interface to the Hierarchical Triangular Mesh (HTM) library 0041 * written by A. Szalay, John Doug Reynolds, Jim Gray, and Peter Z. Kunszt. 0042 * 0043 * HTM divides the celestial sphere up into little triangles (trixels) and 0044 * gives each triangle a unique integer id. We index objects by putting a 0045 * pointer to the object in a data structure accessible by the id number, for 0046 * example QList<QList<StarObject*> or QHash<int, QList<LineListComponent*>. 0047 * 0048 * Use aperture(centerPoint, radius) to get a list of trixels visible in the 0049 * circle. Then use a MeshIterator to iterate over the indices of the visible 0050 * trixels. Look up each index in the top level QHash or QList data structure 0051 * and the union of all the elements of the QList's returned will contain all 0052 * the objects visible in the circle in the sky specified in the aperture() 0053 * call. 0054 * 0055 * The drawID is used for extended objects that may be covered by more than 0056 * one trixel. Every time aperture() is called, drawID is incremented by one. 0057 * Extended objects should each contain their own drawID. If an object's 0058 * drawID is the same as the current drawID then it shouldn't be drawn again 0059 * because it was already drawn in this draw cycle. If the drawID is 0060 * different then it should be drawn and then the drawID should be set to the 0061 * current drawID() so it doesn't get drawn again this cycle. 0062 * 0063 * The list of visible trixels found from an aperture() call or one of the 0064 * primitive index() by creating a new MeshIterator instance: 0065 * 0066 * MeshIterator( HTMesh *mesh ) 0067 * 0068 * The MeshIterator has its own bool hasNext(), int next(), and int size() 0069 * methods for iterating through the integer indices of the found trixels or 0070 * for just getting the total number of found trixels. 0071 */ 0072 0073 class SkyMesh : public HTMesh 0074 { 0075 protected: 0076 SkyMesh(int level); 0077 // FIXME: check copy ctor 0078 SkyMesh(SkyMesh &skyMesh); 0079 0080 public: 0081 /** @short creates the single instance of SkyMesh. The level indicates 0082 * how fine a mesh we will use. The number of triangles (trixels) in the 0083 * mesh will be 8 * 4^level so a mesh of level 5 will have 8 * 4^5 = 8 * 0084 * 2^10 = 8192 trixels. The size of the triangles are roughly pi / * 0085 * 2^(level + 1) so a level 5 mesh will have triangles size roughly of 0086 * .05 radians or 2.8 degrees. 0087 */ 0088 static SkyMesh *Create(int level); 0089 0090 /** @short returns the default instance of SkyMesh or null if it has not 0091 * yet been created. 0092 */ 0093 static SkyMesh *Instance(); 0094 0095 /** 0096 *@short returns the instance of SkyMesh corresponding to the given level 0097 *@return the instance of SkyMesh at the given level, or nullptr if it has not 0098 *yet been created. 0099 */ 0100 static SkyMesh *Instance(int level); 0101 0102 /** 0103 *@short finds the set of trixels that cover the circular aperture 0104 * specified after first performing a reverse precession correction on 0105 * the center so we don't have to re-index objects simply due to 0106 * precession. The drawID also gets incremented which is useful for 0107 * drawing extended objects. Typically a safety factor of about one 0108 * degree is added to the radius to account for proper motion, 0109 * refraction and other imperfections. 0110 *@param center Center of the aperture 0111 *@param radius Radius of the aperture in degrees 0112 *@param bufNum Buffer to use 0113 *@note See HTMesh.h for more 0114 */ 0115 void aperture(SkyPoint *center, double radius, MeshBufNum_t bufNum = DRAW_BUF); 0116 0117 /** @short returns the index of the trixel containing p. 0118 */ 0119 Trixel index(const SkyPoint *p); 0120 0121 /** 0122 * @short returns the sky region needed to cover the rectangle defined by two 0123 * SkyPoints p1 and p2 0124 * @param p1 top-left SkyPoint of the rectangle 0125 * @param p2 bottom-right SkyPoint of the rectangle 0126 */ 0127 const SkyRegion &skyRegion(const SkyPoint &p1, const SkyPoint &p2); 0128 0129 /** @name Stars and CLines 0130 Routines used for indexing stars and CLines. 0131 The following four routines are used for indexing stars and CLines. 0132 They differ from the normal routines because they take proper motion 0133 into account while the normal routines always index the J2000 0134 position. 0135 0136 Since the proper motion depends on time, it is essential to call 0137 setKSNumbers to set the time before doing the indexing. The default 0138 value is J2000. 0139 */ 0140 0141 /** @{*/ 0142 0143 /** @short sets the time for indexing StarObjects and CLines. 0144 */ 0145 void setKSNumbers(KSNumbers *num) { m_KSNumbers = KSNumbers(*num); } 0146 0147 /** @short returns the trixel that contains the star at the set 0148 * time with proper motion taken into account but not precession. 0149 * This is a feature not a bug. 0150 */ 0151 Trixel indexStar(StarObject *star); 0152 0153 /** @short fills the default buffer with all the trixels needed to cover 0154 * the line connecting the two stars. 0155 */ 0156 void indexStar(StarObject *star1, StarObject *star2); 0157 0158 /** @short Fills a hash with all the trixels needed to cover all the line 0159 * segments in the SkyList where each SkyPoint is assumed to be a star 0160 * and proper motion is taken into account. Used only by 0161 * ConstellationsLines. 0162 */ 0163 const IndexHash &indexStarLine(SkyList *points); 0164 0165 /** @}*/ 0166 0167 //----- Here come index routines for various shapes ----- 0168 0169 /** @name Multi Shape Index Routines 0170 * The first two routines use QPoint and the rest use SkyPoint 0171 */ 0172 0173 /** @{*/ 0174 0175 /** @short finds the indices of the trixels that cover the triangle 0176 * specified by the three QPointF's. 0177 */ 0178 void index(const QPointF &p1, const QPointF &p2, const QPointF &p3); 0179 0180 /** @short Finds the trixels needed to cover the quadrilateral specified 0181 * by the four QPointF's. 0182 */ 0183 void index(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4); 0184 0185 /** @short finds the indices of the trixels covering the circle specified 0186 * by center and radius. 0187 */ 0188 void index(const SkyPoint *center, double radius, MeshBufNum_t bufNum = DRAW_BUF); 0189 0190 /** @short finds the indices of the trixels covering the line segment 0191 * connecting p1 and p2. 0192 */ 0193 void index(const SkyPoint *p1, const SkyPoint *p2); 0194 0195 /** @short finds the indices of the trixels covering the triangle 0196 * specified by vertices: p1, p2, and p3. 0197 */ 0198 void index(const SkyPoint *p1, const SkyPoint *p2, const SkyPoint *p3); 0199 0200 /** @short finds the indices of the trixels covering the quadralateral 0201 * specified by the vertices: p1, p2, p3, and p4. 0202 */ 0203 void index(const SkyPoint *p1, const SkyPoint *p2, const SkyPoint *p3, const SkyPoint *p4); 0204 0205 /** @}*/ 0206 0207 /** @name IndexHash Routines 0208 0209 The follow routines are used to index SkyList data structures. They 0210 fill a QHash with the indices of the trixels that cover the data 0211 structure. These are all used as callbacks in the LineListIndex 0212 subclasses so they can use the same indexing code to index different 0213 data structures. See also indexStarLine() above. 0214 */ 0215 0216 /** @{*/ 0217 0218 /** @short fills a QHash with the trixel indices needed to cover all the 0219 * line segments specified in the QVector<SkyPoints*> points. 0220 * 0221 * @param points the points of the line segment. The debug mode causes extra 0222 * info to be printed. 0223 */ 0224 const IndexHash &indexLine(SkyList *points); 0225 0226 /** @short as above but allows for skipping the indexing of some of 0227 * the points. 0228 * 0229 * @param points the line segment to be indexed. 0230 * @param skip a hash indicating which points to skip 0231 * debugging info. 0232 */ 0233 const IndexHash &indexLine(SkyList *points, IndexHash *skip); 0234 0235 /** @short fills a QHash with the trixel indices needed to cover the 0236 * polygon specified in the QList<SkyPoints*> points. There is no 0237 * version with a skip parameter because it does not make sense to 0238 * skip some of the edges of a filled polygon. 0239 * 0240 * @param points the points of the line segment. 0241 * The debug mode causes extra info to be printed. 0242 */ 0243 const IndexHash &indexPoly(SkyList *points); 0244 0245 /** @short does the same as above but with a QPolygonF as the 0246 * container for the points. 0247 */ 0248 const IndexHash &indexPoly(const QPolygonF *points); 0249 0250 /** @}*/ 0251 0252 /** @short Returns the debug level. This is used as a global debug level 0253 * for LineListIndex and its subclasses. 0254 */ 0255 int debug() const { return m_debug; } 0256 0257 /** @short Sets the debug level. 0258 */ 0259 void debug(int debug) { m_debug = debug; } 0260 0261 /** @return the current drawID which gets incremented each time aperture() 0262 * is called. 0263 */ 0264 DrawID drawID() const { return m_drawID; } 0265 0266 /** @short increments the drawID and returns the new value. This is 0267 * useful when you want to use the drawID to ensure you are not 0268 * repeating yourself when iterating over the elements of an IndexHash. 0269 * It is currently used in LineListIndex::reindex(). 0270 */ 0271 int incDrawID() { return ++m_drawID; } 0272 0273 /** @short Draws the outline of all the trixels in the specified buffer. 0274 * This was very useful during debugging. I don't precess the points 0275 * because I mainly use it with the IN_CONSTELL_BUF which is not 0276 * precessed. We will probably have buffers serve double and triple 0277 * duty in the production code to save space in which case this function 0278 * may become less useful. 0279 */ 0280 void draw(QPainter &psky, MeshBufNum_t bufNum = DRAW_BUF); 0281 0282 bool inDraw() const { return m_inDraw; } 0283 void inDraw(bool inDraw) { m_inDraw = inDraw; } 0284 0285 private: 0286 DrawID m_drawID; 0287 int errLimit { 0 }; 0288 int m_debug { 0 }; 0289 0290 IndexHash indexHash; 0291 KSNumbers m_KSNumbers; 0292 0293 bool m_inDraw { false }; 0294 static int defaultLevel; 0295 static QMap<int, SkyMesh *> pinstances; 0296 };