• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 17068063291

19 Aug 2025 11:22AM UTC coverage: 11.766%. Remained the same
17068063291

push

github

alex-w
Reformatting

14706 of 124990 relevant lines covered (11.77%)

18303.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

21.91
/src/core/modules/ZoneArray.cpp
1
/*
2
 * The big star catalogue extension to Stellarium:
3
 * Author and Copyright: Johannes Gajdosik, 2006, 2007
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18
 */
19

20
#include "ZoneArray.hpp"
21
#include "StelGeodesicGrid.hpp"
22
#include "StelObject.hpp"
23
#include "StelPainter.hpp"
24
#include "StarMgr.hpp"
25

26
#include <QDebug>
27
#include <QFile>
28
#include <QDir>
29
#ifdef Q_OS_WIN
30
#include <io.h>
31
#include <Windows.h>
32
#endif
33

34

35
static unsigned int stel_bswap_32(unsigned int val)
×
36
{
37
        return (((val) & 0xff000000) >> 24) | (((val) & 0x00ff0000) >>  8) |
×
38
               (((val) & 0x0000ff00) <<  8) | (((val) & 0x000000ff) << 24);
×
39
}
40

41
static float stel_bswap_32f(int val)
×
42
{
43
    // Create a union to access the float as an unsigned int
44
    union {
45
        float f;
46
        unsigned int i;
47
    } u;
48

49
    // Assign the float value to the union
50
    u.i = val;
×
51

52
    // Perform the byte swap on the integer representation
53
    u.i = (((u.i) & 0xff000000) >> 24) | (((u.i) & 0x00ff0000) >>  8) |
×
54
          (((u.i) & 0x0000ff00) <<  8) | (((u.i) & 0x000000ff) << 24);
×
55

56
    // Return the float value from the union
57
    return u.f;
×
58
}
59

60
static const Vec3f north(0,0,1);
61

62
void ZoneArray::initTriangle(int index, const Vec3f &c0, const Vec3f &c1, const Vec3f &c2)
×
63
{
64
        // shut compiler up about unused variables
65
        (void)index;
66
        (void)c0;
67
        (void)c1;
68
        (void)c2;
69

70
        // we don't need them anymore for the new star catalogs
71
        // initialize zone:
72
        // ZoneData &z(zones[index]);
73
        // z.center = c0+c1+c2;
74
        // z.center.normalize();
75
        // z.axis0 = north ^ z.center;
76
        // z.axis0.normalize();
77
        // z.axis1 = z.center ^ z.axis0;
78
}
×
79

80
static inline int ReadInt(QFile& file, unsigned int &x)
24✔
81
{
82
        const int rval = (4 == file.read(reinterpret_cast<char*>(&x), 4)) ? 0 : -1;
24✔
83
        return rval;
24✔
84
}
85

86
static inline int ReadFloat(QFile& file, float &x)
4✔
87
{
88
        char data[sizeof x];
89
        if (file.read(data, sizeof data) != sizeof data)
4✔
90
                return -1;
×
91
        std::memcpy(&x, data, sizeof data);
4✔
92
        return 0;
4✔
93
}
94

95
#if (!defined(__GNUC__))
96
#ifndef _MSC_BUILD
97
#warning Star catalogue loading has only been tested with gcc
98
#endif
99
#endif
100

101
ZoneArray* ZoneArray::create(const QString& catalogFilePath, bool use_mmap)
4✔
102
{
103
        QString dbStr; // for debugging output.
4✔
104
        QFile* file = new QFile(catalogFilePath);
4✔
105
        if (!file->open(QIODevice::ReadOnly))
4✔
106
        {
107
                qWarning().noquote() << "Error while loading" << QDir::toNativeSeparators(catalogFilePath) << ": failed to open file.";
×
108
                return Q_NULLPTR;
×
109
        }
110
        dbStr = "Loading star catalog: " + QDir::toNativeSeparators(catalogFilePath) + " - ";
4✔
111
        unsigned int magic,major,minor,type,level,mag_min;
112
        float epochJD;
113
        if (ReadInt(*file,magic) < 0 ||
4✔
114
            ReadInt(*file,type) < 0 ||
4✔
115
            ReadInt(*file,major) < 0 ||
4✔
116
            ReadInt(*file,minor) < 0 ||
4✔
117
            ReadInt(*file,level) < 0 ||
4✔
118
            ReadInt(*file,mag_min) < 0 ||
12✔
119
            ReadFloat(*file,epochJD) < 0)
4✔
120
        {
121
                dbStr += "error - file format is bad.";
×
122
                qDebug().noquote() << dbStr;
×
123
                return Q_NULLPTR;
×
124
        }
125
        const bool byte_swap = (magic == FILE_MAGIC_OTHER_ENDIAN);
4✔
126
        if (byte_swap)
4✔
127
        {
128
                // ok, FILE_MAGIC_OTHER_ENDIAN, must swap
129
                if (use_mmap)
×
130
                {
131
                        dbStr += "warning - must convert catalogue";
×
132
#if (!defined(__GNUC__))
133
                        dbStr += "to native format";
134
#endif
135
                        dbStr += "before mmap loading";
×
136
                        qWarning().noquote() << dbStr;
×
137
                        use_mmap = false;
×
138
                        qWarning().noquote() << "Revert to not using mmmap";
×
139
                        //return 0;
140
                }
141
                dbStr += "byteswap";
×
142
                type = stel_bswap_32(type);
×
143
                major = stel_bswap_32(major);
×
144
                minor = stel_bswap_32(minor);
×
145
                level = stel_bswap_32(level);
×
146
                mag_min = stel_bswap_32(mag_min);
×
147
                epochJD = stel_bswap_32f(epochJD);
×
148
        }
149
        else if (magic == FILE_MAGIC)
4✔
150
        {
151
                // ok, FILE_MAGIC
152
#if (!defined(__GNUC__) && !defined(_MSC_BUILD))
153
                if (use_mmap)
154
                {
155
                        // mmap only with gcc:
156
                        dbStr += "warning - you must convert catalogue to native format before mmap loading";
157
                        qDebug(qPrintable(dbStr));
158

159
                        return 0;
160
                }
161
#endif
162
        }
163
        else if (magic == FILE_MAGIC_NATIVE)
×
164
        {
165
                // ok, will work for any architecture and any compiler
166
        }
167
        else
168
        {
169
                dbStr += "error - not a catalogue file.";
×
170
                qDebug().noquote() << dbStr;
×
171
                return Q_NULLPTR;
×
172
        }
173
        if (epochJD != STAR_CATALOG_JDEPOCH)
4✔
174
        {
175
                qDebug().noquote() << epochJD << "!=" << STAR_CATALOG_JDEPOCH;
×
176
                dbStr += "warning - Star catalog epoch is not what is expected in Stellarium";
×
177
                qDebug().noquote() << dbStr;
×
178
                return Q_NULLPTR;
×
179
        }
180
        ZoneArray *rval = Q_NULLPTR;
4✔
181
        dbStr += QString("%1_%2v%3_%4; ").arg(level).arg(type).arg(major).arg(minor);
4✔
182

183
        switch (type)
4✔
184
        {
185
                case 0:
4✔
186
                        if (major > MAX_MAJOR_FILE_VERSION)
4✔
187
                        {
188
                                dbStr += "warning - unsupported version";
×
189
                        }
190
                        else
191
                        {
192
                                rval = new HipZoneArray(file, byte_swap, use_mmap, static_cast<int>(level), static_cast<int>(mag_min));
4✔
193
                        }
194
                        break;
4✔
195
                case 1:
×
196
                        if (major > MAX_MAJOR_FILE_VERSION)
×
197
                        {
198
                                dbStr += "warning - unsupported version";
×
199
                        }
200
                        else
201
                        {
202
                                rval = new SpecialZoneArray<Star2>(file, byte_swap, use_mmap, static_cast<int>(level), static_cast<int>(mag_min));
×
203
                        }
204
                        break;
×
205
                case 2:
×
206
                        if (major > MAX_MAJOR_FILE_VERSION)
×
207
                        {
208
                                dbStr += "warning - unsupported version";
×
209
                        }
210
                        else
211
                        {
212
                                rval = new SpecialZoneArray<Star3>(file, byte_swap, use_mmap, static_cast<int>(level), static_cast<int>(mag_min));
×
213
                        }
214
                        break;
×
215
                default:
×
216
                        dbStr += "error - bad file type";
×
217
                        break;
×
218
        }
219
        if (rval && rval->isInitialized())
4✔
220
        {
221
                dbStr += QString("%1 entries").arg(rval->getNrOfStars());
4✔
222
                qInfo().noquote() << dbStr;
4✔
223
        }
224
        else
225
        {
226
                dbStr += "- initialization failed";
×
227
                qDebug().noquote() << dbStr;
×
228
                if (rval)
×
229
                {
230
                        delete rval;
×
231
                        rval = Q_NULLPTR;
×
232
                }
233
        }
234
        return rval;
4✔
235
}
4✔
236

237
ZoneArray::ZoneArray(const QString& fname, QFile* file, int level, int mag_min)
4✔
238
                        : fname(fname), level(level), mag_min(mag_min), nr_of_stars(0), zones(Q_NULLPTR), file(file)
4✔
239
{
240
        nr_of_zones = static_cast<unsigned int>(StelGeodesicGrid::nrOfZones(level));
4✔
241
}
4✔
242

243
bool ZoneArray::readFile(QFile& file, void *data, qint64 size)
×
244
{
245
        int parts = 256;
×
246
        int part_size = static_cast<int>((size + (parts>>1)) / parts);
×
247
        if (part_size < 64*1024)
×
248
        {
249
                part_size = 64*1024;
×
250
        }
251
        while (size > 0)
×
252
        {
253
                const int to_read = (part_size < size) ? part_size : static_cast<int>(size);
×
254
                const int read_rc = static_cast<int>(file.read(static_cast<char*>(data), to_read));
×
255
                if (read_rc != to_read) return false;
×
256
                size -= read_rc;
×
257
                data = (static_cast<char*>(data)) + read_rc;
×
258
        }
259
        return true;
×
260
}
261

262
void HipZoneArray::updateHipIndex(HipIndexStruct hipIndex[]) const
×
263
{
264
        for (const SpecialZoneData<Star1> *z=getZones()+(nr_of_zones-1);z>=getZones();z--)
×
265
        {
266
                for (const Star1 *s = z->getStars()+z->size-1;s>=z->getStars();s--)
×
267
                {
268
                        const int hip = s->getHip();
×
269
                        if (hip < 0 || NR_OF_HIP < hip)
×
270
                        {
271
                                qDebug() << "ERROR: HipZoneArray::updateHipIndex: invalid HIP number:" << hip;
×
272
                                exit(1);
×
273
                        }
274
                        if (hip != 0)
×
275
                        {        
276
                                // check if a star is there already
277
                                if (hipIndex[hip].a)
×
278
                                {
279
                                        // check if componentid is smaller or higher, we want smaller one (the main one)
280
                                        // otherwise there can be case where Sirius B is stored as main star but not Sirius A
281
                                        if (hipIndex[hip].s->getComponentIds() > s->getComponentIds())
×
282
                                        {
283
                                                hipIndex[hip].a = this;
×
284
                                                hipIndex[hip].z = z;
×
285
                                                hipIndex[hip].s = s;
×
286
                                        }
287
                                }
288
                                else
289
                                {
290
                                        hipIndex[hip].a = this;
×
291
                                        hipIndex[hip].z = z;
×
292
                                        hipIndex[hip].s = s;
×
293
                                }
294
                        }
295
                }
296
        }
297
}
×
298

299
template<class Star>
300
SpecialZoneArray<Star>::SpecialZoneArray(QFile* file, bool byte_swap,bool use_mmap,
4✔
301
                                         int level, int mag_min)
302
                : ZoneArray(file->fileName(), file, level, mag_min),
4✔
303
                  stars(Q_NULLPTR), mmap_start(Q_NULLPTR)
4✔
304
{
305
        if (nr_of_zones > 0)
4✔
306
        {
307
                zones = new SpecialZoneData<Star>[nr_of_zones];
1,708✔
308

309
                unsigned int *zone_size = new unsigned int[nr_of_zones];
4✔
310
                if (static_cast<qint64>(sizeof(unsigned int)*nr_of_zones) != file->read(reinterpret_cast<char*>(zone_size), sizeof(unsigned int)*nr_of_zones))
4✔
311
                {
312
                        qDebug() << "Error reading zones from catalog:"
×
313
                                 << file->fileName();
×
314
                        delete[] getZones();
×
315
                        zones = Q_NULLPTR;
×
316
                        nr_of_zones = 0;
×
317
                }
318
                else
319
                {
320
                        const unsigned int *tmp = zone_size;
4✔
321
                        for (unsigned int z=0;z<nr_of_zones;z++,tmp++)
1,708✔
322
                        {
323
                                const unsigned int tmp_spu_int32 = byte_swap?stel_bswap_32(*tmp):*tmp;
1,704✔
324
                                nr_of_stars += tmp_spu_int32;
1,704✔
325
                                getZones()[z].size = static_cast<int>(tmp_spu_int32);
1,704✔
326
                        }
327
                        // last one is always the global zone
328
                        getZones()[nr_of_zones-1].isGlobal = true;
4✔
329
                }
330
                // delete zone_size before allocating stars
331
                // in order to avoid memory fragmentation:
332
                delete[] zone_size;
4✔
333

334
                if (nr_of_stars == 0)
4✔
335
                {
336
                        // no stars ?
337
                        if (zones) delete[] getZones();
×
338
                        zones = Q_NULLPTR;
×
339
                        nr_of_zones = 0;
×
340
                }
341
                else
342
                {
343
                        if (use_mmap)
4✔
344
                        {
345
                                mmap_start = file->map(file->pos(), sizeof(Star)*nr_of_stars);
4✔
346
                                if (mmap_start == Q_NULLPTR)
4✔
347
                                {
348
                                        qDebug() << "ERROR: SpecialZoneArray(" << level
×
349
                                                 << ")::SpecialZoneArray: QFile(" << file->fileName()
×
350
                                                 << ".map(" << file->pos()
×
351
                                                 << ',' << sizeof(Star)*nr_of_stars
×
352
                                                 << ") failed: " << file->errorString();
×
353
                                        stars = Q_NULLPTR;
×
354
                                        nr_of_stars = 0;
×
355
                                        delete[] getZones();
×
356
                                        zones = Q_NULLPTR;
×
357
                                        nr_of_zones = 0;
×
358
                                }
359
                                else
360
                                {
361
                                        stars = reinterpret_cast<Star*>(mmap_start);
4✔
362
                                        Star *s = stars;
4✔
363
                                        for (unsigned int z=0;z<nr_of_zones;z++)
1,708✔
364
                                        {
365
                                                getZones()[z].stars = s;
1,704✔
366
                                                s += getZones()[z].size;
1,704✔
367
                                        }
368
                                }
369
                                file->close();
4✔
370
                        }
371
                        else
372
                        {
373
                                stars = new Star[nr_of_stars];
×
374
                                if (!readFile(*file,stars,sizeof(Star)*nr_of_stars))
×
375
                                {
376
                                        delete[] stars;
×
377
                                        stars = Q_NULLPTR;
×
378
                                        nr_of_stars = 0;
×
379
                                        delete[] getZones();
×
380
                                        zones = Q_NULLPTR;
×
381
                                        nr_of_zones = 0;
×
382
                                }
383
                                else
384
                                {
385
                                        Star *s = stars;
×
386
                                        for (unsigned int z=0;z<nr_of_zones;z++)
×
387
                                        {
388
                                                getZones()[z].stars = s;
×
389
                                                s += getZones()[z].size;
×
390
                                        }
391
                                }
392
                                file->close();
×
393
                        }
394
                }
395
        }
396
}
4✔
397

398
template<class Star>
399
SpecialZoneArray<Star>::~SpecialZoneArray(void)
×
400
{
401
        if (stars)
×
402
        {
403
                if (mmap_start != Q_NULLPTR)
×
404
                {
405
                        file->unmap(mmap_start);
×
406
                }
407
                else
408
                {
409
                        delete[] stars;
×
410
                }
411
                delete file;
×
412
                stars = Q_NULLPTR;
×
413
        }
414
        if (zones)
×
415
        {
416
                delete[] getZones();
×
417
                zones = Q_NULLPTR;
×
418
        }
419
        nr_of_zones = 0;
×
420
        nr_of_stars = 0;
×
421
}
×
422

423
template<class Star>
424
void SpecialZoneArray<Star>::draw(StelPainter* sPainter, int index, bool isInsideViewport, const RCMag* rcmag_table,
×
425
                                  int limitMagIndex, StelCore* core, int maxMagStarName, float names_brightness,
426
                                  const QVector<SphericalCap> &boundingCaps,
427
                                  const bool withAberration, const Vec3d vel, const double withParallax, const Vec3d diffPos,
428
                                  const bool withCommonNameI18n) const
429
{
430
        StelSkyDrawer* drawer = core->getSkyDrawer();
×
431
        Vec3d v;
×
432
        const float dyrs = static_cast<float>(core->getJDE()-STAR_CATALOG_JDEPOCH)/365.25;
×
433

434
        const Extinction& extinction=core->getSkyDrawer()->getExtinction();
×
435
        const bool withExtinction=drawer->getFlagHasAtmosphere() && extinction.getExtinctionCoefficient()>=0.01f;
×
436
        
437
        // Allow artificial cutoff:
438
        // find the (integer) mag at which is just bright enough to be drawn.
439
        int cutoffMagStep=limitMagIndex;  // for steps
×
440
        float cutoffMag = 999999.;  // for precise magnitude cutoff
×
441
        if (drawer->getFlagStarMagnitudeLimit())
×
442
        {
443
                cutoffMag = drawer->getCustomStarMagnitudeLimit() * 1000.0f;  // in milli-mag
×
444
                cutoffMagStep = static_cast<int>((cutoffMag - (mag_min - 7000.))*0.02);  // 1/(50 milli-mag)
×
445
                if (cutoffMagStep>limitMagIndex)
×
446
                        cutoffMagStep = limitMagIndex;
×
447
        }
448
        Q_ASSERT_X(cutoffMagStep<=RCMAG_TABLE_SIZE, "ZoneArray.cpp",
×
449
                   QString("RCMAG_TABLE_SIZE: %1, cutoffmagStep: %2").arg(QString::number(RCMAG_TABLE_SIZE), QString::number(cutoffMagStep)).toLatin1());
450
    
451
        // Go through all stars, which are sorted by magnitude (bright stars first)
452
        const SpecialZoneData<Star>* zoneToDraw = getZones() + index;
×
453
        const Star* lastStar = zoneToDraw->getStars() + zoneToDraw->size;
×
454
        bool globalzone;
455
        for (const Star* s=zoneToDraw->getStars();s<lastStar;++s)
×
456
        {
457
                // check if this is a global zone
458
                globalzone = zoneToDraw->isGlobal;
×
459
                float starMag = s->getMag();
×
460
                int magIndex = static_cast<int>((starMag - (mag_min - 7000.)) * 0.02);  // 1 / (50 milli-mag)
×
461

462
                // first part is check for Star1 and is global zone, so to keep looping for long-range prediction
463
                // second part is old behavior, to skip stars below you that are too faint to display for Star2 and Star3
464
                if ((magIndex > cutoffMagStep) || (starMag > cutoffMag)) { // should always use catalog magnitude, otherwise will mess up the order
×
465
                        if (fabs(dyrs) <= 5000. || !s->isVIP() || !globalzone)  // if any of these true, we should always break
×
466
                                break;
×
467
                }
468
                // Because of the test above, the star should always be visible from this point.
469
                
470
                // only recompute if has time dependence
471
                bool recomputeMag = (s->getPreciseAstrometricFlag());
×
472
                double Plx = s->getPlx();
×
473
                if (recomputeMag) { 
×
474
                        // don't do full solution, can be very slow, just estimate here        
475
                        // estimate parallax from radial velocity and total proper motion
476
                        double vr = s->getRV();
×
477
                        Vec3d pmvec0(s->getDx0(), s->getDx1(), s->getDx2());
×
478
                        pmvec0 = pmvec0 * MAS2RAD;
×
479
                        double pmr0 = vr * Plx / (AU / JYEAR_SECONDS) * MAS2RAD;
×
480
                        double pmtotsqr =  (pmvec0[0] * pmvec0[0] + pmvec0[1] * pmvec0[1] + pmvec0[2] * pmvec0[2]);
×
481
                        double f = 1. / sqrt(1. + 2. * pmr0 * dyrs + (pmtotsqr + pmr0*pmr0)*dyrs*dyrs);
×
482
                        Plx *= f;
×
483
                        float magOffset = 5.f * log10(1/f);
×
484
                        starMag += magOffset * 1000.;
×
485
                        // if we reach here we might as well compute the position too
486
                        Vec3d r(s->getX0(), s->getX1(), s->getX2());
×
487
                        Vec3d u = (r * (1. + pmr0 * dyrs) + pmvec0 * dyrs) * f;
×
488
                        v.set(u[0], u[1], u[2]);
×
489
                }
490
                // recompute magIndex with the new magnitude
491
                magIndex = static_cast<int>((starMag - (mag_min - 7000.)) * 0.02);  // 1 / (50 milli-mag)
×
492

493
                if ((magIndex > cutoffMagStep) || (starMag > cutoffMag)) {  // check again with the new magIndex
×
494
                                continue;  // allow continue for other star that might became bright enough in the future
×
495
                }
496
                // Array of 2 numbers containing radius and magnitude
497
                const RCMag* tmpRcmag = &rcmag_table[magIndex];
×
498
                
499
                // Get the star position from the array, only do it if not already computed
500
                // put it here because potentially cutoffMagStep bigger than magIndex and no computation needed
501
                if (!recomputeMag) {
×
502
                        s->getJ2000Pos(dyrs, v);
×
503
                }
504

505
                // in case it is in a binary system
506
                s->getBinaryOrbit(core->getJDE(), v);
×
507

508
                if (withParallax) {
×
509
                        s->getPlxEffect(withParallax * Plx, v, diffPos);
×
510
                        v.normalize();
×
511
                }
512

513
                // Aberration: vf contains Equatorial J2000 position.
514
                if (withAberration)
×
515
                {
516
                        //Q_ASSERT_X(fabs(vf.lengthSquared()-1.0f)<0.0001f, "ZoneArray aberration", "vertex length not unity");
517
                        v += vel;
×
518
                        v.normalize();
×
519
                }
520
                
521
                // If the star zone is not strictly contained inside the viewport, eliminate from the 
522
                // beginning the stars actually outside viewport.
523
                if (!isInsideViewport)
×
524
                {
525
                        bool isVisible = true;
×
526
                        for (const auto& cap : boundingCaps)
×
527
                        {
528
                                if (!cap.contains(v))
×
529
                                {
530
                                        isVisible = false;
×
531
                                        continue;
×
532
                                }
533
                        }
534
                        if (!isVisible)
×
535
                                continue;
×
536
                }
537

538
                int extinctedMagIndex = magIndex;
×
539
                float twinkleFactor=1.0f; // allow height-dependent twinkle.
×
540
                if (withExtinction)
×
541
                {
542
                        Vec3d altAz(v);
×
543
                        altAz.normalize();
×
544
                        core->j2000ToAltAzInPlaceNoRefraction(&altAz);
×
545
                        float extMagShift=0.0f;
×
546
                        extinction.forward(altAz, &extMagShift);
×
547
                        extinctedMagIndex += static_cast<int>(extMagShift/0.05f); // 0.05 mag MagStepIncrement
×
548
                        if (extinctedMagIndex >= cutoffMagStep || extinctedMagIndex<0) // i.e., if extincted it is dimmer than cutoff or extinctedMagIndex is negative (missing star catalog), so remove
×
549
                                continue;
×
550
                        tmpRcmag = &rcmag_table[extinctedMagIndex];
×
551
                        twinkleFactor=qMin(1.0, 1.0-0.9*altAz[2]); // suppress twinkling in higher altitudes. Keep 0.1 twinkle amount in zenith.
×
552
                }
553

554
                if (drawer->drawPointSource(sPainter, v, *tmpRcmag, s->getBVIndex(), !isInsideViewport, twinkleFactor) && s->hasName() && extinctedMagIndex < maxMagStarName && s->hasComponentID()<=1)
×
555
                {
556
                        const float offset = tmpRcmag->radius*0.7f;
×
557
                        const Vec3f color = StelSkyDrawer::indexToColor(s->getBVIndex())*0.75f;
×
558
                        sPainter->setColor(color, names_brightness);
×
559
                        sPainter->drawText(v, s->getScreenNameI18n(withCommonNameI18n), 0, offset, offset, false);
×
560
                }
561
        }
562
}
×
563

564
template<class Star>
565
void SpecialZoneArray<Star>::searchAround(const StelCore* core, int index, const Vec3d &v, const double withParallax, const Vec3d diffPos, 
×
566
                                                                                  double cosLimFov, QList<StelObjectP > &result)
567
{
568
        const float dyrs = static_cast<float>(core->getJDE()-STAR_CATALOG_JDEPOCH)/365.25;
×
569
        const SpecialZoneData<Star> *const z = getZones()+index;
×
570
        Vec3d tmp;
×
571
        double RA, DEC, pmra, pmdec, Plx, RadialVel;
572
        for (const Star* s=z->getStars();s<z->getStars()+z->size;++s)
×
573
        {
574
                s->getFull6DSolution(RA, DEC, Plx, pmra, pmdec, RadialVel, dyrs);
×
575
                StelUtils::spheToRect(RA, DEC, tmp);
×
576
                // s->getJ2000Pos(dyrs, tmp);
577
                // in case it is in a binary system
578
                s->getBinaryOrbit(core->getJDE(), tmp);
×
579
                s->getPlxEffect(withParallax * Plx, tmp, diffPos);
×
580
                tmp.normalize();
×
581
                if (core->getUseAberration())
×
582
                {
583
                        const Vec3d vel = core->getAberrationVec(core->getJDE());
×
584
                        tmp+=vel;
×
585
                        tmp.normalize();
×
586
                }
587
                if (tmp * v >= cosLimFov)
×
588
                {
589
                        // TODO: do not select stars that are too faint to display
590
                        result.push_back(s->createStelObject(this,z));
×
591
                }
592
        }
593
}
×
594

595
template<class Star>
596
void SpecialZoneArray<Star>::searchWithin(const StelCore* core, int index, const SphericalRegionP region, const double withParallax, const Vec3d diffPos, const bool hipOnly, const float maxMag,
×
597
                                                  QList<StelObjectP > &result) const
598
{
599
        if (hipOnly && level>3)
×
600
                        return;
×
601
#ifndef NDEBUG
602
        qDebug() << "SpecialZoneArray<Star>::searchWithin(): Level" << level << "MagMin" << mag_min << "fname" << fname << "nr_of_zones" << nr_of_zones << "nr_of_stars" << nr_of_stars;
×
603
#endif
604
        const float dyrs = static_cast<float>(core->getJDE()-STAR_CATALOG_JDEPOCH)/365.25;
×
605
        const SpecialZoneData<Star> *const z = getZones()+index;
×
606
        const float maxMilliMag = 1000.f*maxMag;
×
607
        Vec3d tmp;
×
608
        double RA, DEC, pmra, pmdec, Plx, RadialVel;
609
        for (const Star* s=z->getStars();s<z->getStars()+z->size;++s)
×
610
        {
611
                if (hipOnly && s->getHip()==0)
×
612
                {
613
                        continue;
×
614
                }
615

616
                s->getFull6DSolution(RA, DEC, Plx, pmra, pmdec, RadialVel, dyrs);
×
617
                StelUtils::spheToRect(RA, DEC, tmp);
×
618
                // s->getJ2000Pos(dyrs, tmp);
619
                // in case it is in a binary system
620
                s->getBinaryOrbit(core->getJDE(), tmp);
×
621
                s->getPlxEffect(withParallax * Plx, tmp, diffPos);
×
622
                tmp.normalize();
×
623
                // TODO: Move vel into arg.list
624
                if (core->getUseAberration())
×
625
                {
626
                        const Vec3d vel = core->getAberrationVec(core->getJDE());
×
627
                        tmp+=vel;
×
628
                        tmp.normalize();
×
629
                }
630
                // By trying, region is a SphericalPolygon. We are calling SphericalPolygon::contains(Vec3d)
631
                if (region->contains(tmp) && (s->getMag() < maxMilliMag) )
×
632
                {
633
#ifndef NDEBUG
634
                        //qDebug() << "Region match: " <<  s->getHip() << s->getGaia()  << "(Index (Zone):" << index << ", Level="<< level << ")";
635
#endif
636
                        result.push_back(s->createStelObject(this,z));
×
637
                }
638
        }
639
}
640

641

642
template<class Star>
643
StelObjectP SpecialZoneArray<Star>::searchGaiaID(int index, const StarId source_id, int &matched) const
×
644
{
645
        const SpecialZoneData<Star> *const z = getZones()+index;
×
646
        for (const Star* s=z->getStars();s<z->getStars()+z->size;++s)
×
647
        {
648
                if (s->getGaia() == source_id)
×
649
                {
650
                        matched++;
×
651
                        return s->createStelObject(this,z);
×
652
                }
653
        }
654
        return StelObjectP();
×
655
}
656

657
template<class Star>
658
// this class is written for the unit test
659
void SpecialZoneArray<Star>::searchGaiaIDepochPos(const StarId source_id,
27✔
660
                                                  float         dyrs,
661
                                                  double &      RA,
662
                                                  double &      DEC,
663
                                                  double &      Plx,
664
                                                  double &      pmra,
665
                                                  double &      pmdec,
666
                                                  double &      RV) const
667
{
668
   // loop through each zone in the level which is 20 * 4 ** level + 1 as index
669
   for (int i = 0; i < 20 * pow(4, (level)) + 1; i++) {
2,436✔
670
      // get the zone data
671
      const SpecialZoneData<Star> * const z = getZones() + i;
2,421✔
672
      // loop through the stars in the zone
673
      for (const Star * s = z->getStars(); s < z->getStars() + z->size; ++s) {
909,893✔
674
         // check if the star has the same Gaia ID
675
         if (s->getGaia() == source_id) {
907,484✔
676
            // get the J2000 position of the star
677
            s->getFull6DSolution(RA, DEC, Plx, pmra, pmdec, RV, dyrs);
12✔
678
            return;
12✔
679
         }
680
      }
681
   }
682
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc