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

Stellarium / stellarium / 15291801018

28 May 2025 04:52AM UTC coverage: 11.931% (-0.02%) from 11.951%
15291801018

push

github

alex-w
Added new set of navigational stars (XIX century)

0 of 6 new or added lines in 2 files covered. (0.0%)

14124 existing lines in 74 files now uncovered.

14635 of 122664 relevant lines covered (11.93%)

18291.42 hits per line

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

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

19
#include "StelProjector.hpp"
20
#include "StelApp.hpp"
21
#include "StelCore.hpp"
22
#include "StelFileMgr.hpp"
23
#include "StelGui.hpp"
24
#include "StelGuiItems.hpp"
25
#include "StelLocaleMgr.hpp"
26
#include "StelModuleMgr.hpp"
27
#include "StelMovementMgr.hpp"
28
#include "StelObject.hpp"
29
#include "StelObjectMgr.hpp"
30
#include "MosaicCamera.hpp"
31
#include "MosaicCameraDialog.hpp"
32
#include "StelUtils.hpp"
33
#include "StelPainter.hpp"
34
#include "CustomObject.hpp"
35

36
#include <QDebug>
37
#include <QDir>
38
#include <QJsonDocument>
39
#include <QJsonArray>
40
#include <QJsonObject>
41
#include <QResource>
42
#include <QByteArray>
43

44
/*************************************************************************
45
 This method is the one called automatically by the StelModuleMgr just
46
 after loading the dynamic library
47
*************************************************************************/
48
StelModule* MosaicCameraStelPluginInterface::getStelModule() const
×
49
{
50
        return new MosaicCamera();
×
51
}
52

53
StelPluginInfo MosaicCameraStelPluginInterface::getPluginInfo() const
×
54
{
55
        StelPluginInfo info;
×
56
        info.id = "MosaicCamera";
×
57
        info.displayedName = N_("Mosaic Camera");
×
58
        info.authors = "Josh Meyers";
×
59
        info.contact = "jmeyers314@gmail.com";
×
60
        info.description = N_("Mosaic Camera Overlay");
×
61
        info.version = MOSAICCAMERA_PLUGIN_VERSION;
×
62
        info.license = MOSAICCAMERA_PLUGIN_LICENSE;
×
63
        return info;
×
64
}
×
65

66
/*************************************************************************
67
 Constructor
68
*************************************************************************/
69
MosaicCamera::MosaicCamera()
×
70
        : toolbarButton(Q_NULLPTR)
×
71
{
72
        setObjectName("MosaicCamera");
×
73
        configDialog = new MosaicCameraDialog();
×
74
        StelApp &app = StelApp::getInstance();
×
75
        conf = app.getSettings();
×
76
        core = app.getCore();
×
77
        gui = dynamic_cast<StelGui*>(app.getGui());
×
78
}
×
79

80
/*************************************************************************
81
 Destructor
82
*************************************************************************/
83
MosaicCamera::~MosaicCamera()
×
84
{
85
        delete configDialog;
×
86
}
×
87

88
void MosaicCamera::loadSettings()
×
89
{
90
        conf->beginGroup("MosaicCamera");
×
91
        currentCamera = conf->value("currentCamera").toString();
×
92
        setFlagShowButton(conf->value("showButton", true).toBool());
×
93
        enableMosaicCamera(conf->value("enabled").toBool());
×
94
        int size = conf->beginReadArray("cameraVisibility");
×
95
        for (int i = 0; i < size; ++i)
×
96
        {
97
                conf->setArrayIndex(i);
×
98
                QString name = conf->value("name").toString();
×
99
                bool visible = conf->value("visible").toBool();
×
100
                if (cameras.contains(name))
×
101
                {
102
                        cameras[name].visible = visible;
×
103
                        cameras[name].ra = conf->value("ra").toDouble();
×
104
                        cameras[name].dec = conf->value("dec").toDouble();
×
105
                        cameras[name].rotation = conf->value("rotation").toDouble();
×
106
                }
107
        }
×
108
        conf->endArray();
×
109
        conf->endGroup();
×
110
}
×
111

112
void MosaicCamera::saveSettings() const
×
113
{
114
        conf->beginGroup("MosaicCamera");
×
115
        conf->setValue("currentCamera", currentCamera);
×
116
        conf->setValue("showButton", getFlagShowButton());
×
117
        conf->setValue("enabled", flagShowMosaicCamera);
×
118
        conf->beginWriteArray("cameraVisibility");
×
119
        int i = 0;
×
120
        for (auto it = cameras.constBegin(); it != cameras.constEnd(); ++it)
×
121
        {
122
                conf->setArrayIndex(i++);
×
123
                conf->setValue("name", it.key());
×
124
                conf->setValue("visible", it.value().visible);
×
125
                conf->setValue("ra", it.value().ra);
×
126
                conf->setValue("dec", it.value().dec);
×
127
                conf->setValue("rotation", it.value().rotation);
×
128
        }
129
        conf->endArray();
×
130
        conf->endGroup();
×
131
}
×
132

UNCOV
133
void MosaicCamera::restoreDefaults()
×
134
{
UNCOV
135
        conf->beginGroup("MosaicCamera");
×
136
        conf->remove("currentCamera");
×
UNCOV
137
        conf->remove("showButton");
×
138
        conf->remove("enabled");
×
139
        conf->remove("cameraVisibility");
×
140
        for (auto it = cameras.constBegin(); it != cameras.constEnd(); ++it)
×
141
        {
UNCOV
142
                conf->remove(it.key());
×
143
        }
UNCOV
144
        conf->endGroup();
×
145

UNCOV
146
        StelFileMgr::makeSureDirExistsAndIsWritable(userDirectory);
×
147
        copyResourcesToUserDirectory();
×
148

149
        // Reload the cameras
UNCOV
150
        loadBuiltInCameras();
×
151
        setCurrentCamera(cameraOrder[0]);
×
152
}
×
153

154
/*************************************************************************
155
 Reimplementation of the getCallOrder method
156
*************************************************************************/
157
double MosaicCamera::getCallOrder(StelModuleActionName actionName) const
×
158
{
159
        if (actionName==StelModule::ActionDraw)
×
160
                return StelApp::getInstance().getModuleMgr().getModule("NebulaMgr")->getCallOrder(actionName)+10.;
×
161
        return 0;
×
162
}
163

164

165
/*************************************************************************
166
 Init our module
167
*************************************************************************/
168
void MosaicCamera::init()
×
169
{
170
        Q_INIT_RESOURCE(MosaicCamera);
×
171

172
        initializeUserData();
×
UNCOV
173
        loadBuiltInCameras();
×
174

175
        addAction("actionShow_MosaicCamera", N_("Mosaic Camera"), N_("Show Mosaic Camera"), "enabled", "");
×
UNCOV
176
        addAction("actionShow_MosaicCamera_dialog", N_("Mosaic Camera"), N_("Show settings dialog"), configDialog, "visible");
×
177
        addAction("actionSetRADecToView", N_("Mosaic Camera"), N_("Set RA/Dec to current view"), "setRADecToView()", "");
×
UNCOV
178
        addAction("actionSetRADecToObject", N_("Mosaic Camera"), N_("Set RA/Dec to current object"), "setRADecToObject()", "");
×
179
        addAction("actionSetViewToCamera", N_("Mosaic Camera"), N_("Set view to current camera"), "setViewToCamera()", "");
×
UNCOV
180
        addAction("actionIncrementRotation", N_("Mosaic Camera"), N_("Increment rotation"), "incrementRotation()", "");
×
181
        addAction("actionDecrementRotation", N_("Mosaic Camera"), N_("Decrement rotation"), "decrementRotation()", "");
×
182
        addAction("actionNextCamera", N_("Mosaic Camera"), N_("Next camera"), "nextCamera()", "");
×
183
        addAction("actionPreviousCamera", N_("Mosaic Camera"), N_("Previous camera"), "previousCamera()", "");
×
184

185
        loadSettings();
×
186

UNCOV
187
        if (currentCamera == "")
×
188
                setCurrentCamera(cameraOrder[0]);
×
UNCOV
189
}
×
190

UNCOV
191
void MosaicCamera::enableMosaicCamera(bool b)
×
192
{
UNCOV
193
        if (b!=flagShowMosaicCamera)
×
194
        {
UNCOV
195
                flagShowMosaicCamera = b;
×
196
                emit flagMosaicCameraVisibilityChanged(b);
×
197
        }
UNCOV
198
}
×
199

200
void MosaicCamera::initializeUserData()
×
201
{
202
        userDirectory = StelFileMgr::getUserDir()+"/modules/MosaicCamera/";
×
UNCOV
203
        QDir dir(userDirectory);
×
UNCOV
204
        if (!dir.exists() || dir.isEmpty())
×
205
        {
UNCOV
206
                StelFileMgr::makeSureDirExistsAndIsWritable(userDirectory);
×
207
                copyResourcesToUserDirectory();
×
208
        }
UNCOV
209
}
×
210

UNCOV
211
void MosaicCamera::setFlagShowButton(bool b)
×
212
{
213
        if (gui != Q_NULLPTR)
×
214
        {
UNCOV
215
                if (b == true)
×
216
                {
UNCOV
217
                        if (toolbarButton == Q_NULLPTR)
×
218
                        {
219
                                // Create the button
220
                                toolbarButton = new StelButton(Q_NULLPTR,
×
221
                                                               QPixmap(":/MosaicCamera/bt_MosaicCamera_On.png"),
×
UNCOV
222
                                                               QPixmap(":/MosaicCamera/bt_MosaicCamera_Off.png"),
×
223
                                                               QPixmap(":/graphicGui/miscGlow32x32.png"),
×
224
                                                               "actionShow_MosaicCamera",
225
                                                               false,
226
                                                               "actionShow_MosaicCamera_dialog");
×
227
                        }
228
                        gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGroup");
×
229
                }
230
                else {
UNCOV
231
                        gui->getButtonBar()->hideButton("actionShow_MosaicCamera");
×
232
                }
233
        }
234
        flagShowButton = b;
×
235
}
×
236

UNCOV
237
void MosaicCamera::copyResourcesToUserDirectory()
×
238
{
239
        // Get list of files in the resource directory
240
        QDir resourceDir(":/MosaicCamera");
×
241
        QStringList fileNameFilters("*.json"); // copy data only
×
UNCOV
242
        QStringList resourceFiles = resourceDir.entryList(fileNameFilters);
×
243

UNCOV
244
        for (const QString& fileName : resourceFiles)
×
245
        {
246
                QString resourcePath = ":/MosaicCamera/" + fileName;
×
247
                QString destPath = userDirectory + fileName;
×
UNCOV
248
                QFile destFile(destPath);
×
249
                QFile resourceFile(resourcePath);
×
250

251
                if (destFile.exists()) {
×
252
                        if (!destFile.remove()) {
×
253
                                qWarning() << "[MosaicCamera] Failed to remove existing file:" << destPath;
×
254
                        }
255
                }
256

257
                if (resourceFile.copy(destPath))
×
258
                {
259
                        // Copy the file to the user directory
260
                        qDebug() << "[MosaicCamera] Copied" << resourcePath << "to" << destPath;
×
261
                        // Ensure the copied file is writable
262
                        destFile.setPermissions(destFile.permissions() | QFile::WriteOwner);
×
263
                }
264
                else
265
                {
266
                        qWarning() << "[MosaicCamera] Failed to copy" << resourcePath << "to" << destPath;
×
267
                }
268
        }
×
269
}
×
270

271
void MosaicCamera::loadCameraOrder()
×
272
{
273
        cameraOrder.clear();
×
274
        QFile file(userDirectory + "camera_order.json");
×
275
        if (file.open(QIODevice::ReadOnly))
×
276
        {
277
                QByteArray data = file.readAll();
×
278
                QJsonDocument doc(QJsonDocument::fromJson(data));
×
UNCOV
279
                QJsonObject json = doc.object();
×
280
                QJsonArray orderArray = json["order"].toArray();
×
UNCOV
281
                for (const auto& value : orderArray)
×
282
                {
UNCOV
283
                        cameraOrder << value.toString();
×
284
                }
285
        }
×
286
}
×
287

UNCOV
288
void MosaicCamera::loadBuiltInCameras()
×
289
{
290
        loadCameraOrder();
×
291
        cameras.clear();
×
UNCOV
292
        for (int i = 0; i < cameraOrder.size(); ++i)
×
293
        {
UNCOV
294
                Camera camera;
×
295
                camera.name = cameraOrder[i];
×
296
                camera.ra = 0.0;
×
UNCOV
297
                camera.dec = 0.0;
×
UNCOV
298
                camera.rotation = 0.0;
×
299
                camera.visible = false;
×
UNCOV
300
                camera.fieldDiameter = 0.0; // let's initialize field
×
UNCOV
301
                cameras.insert(camera.name, camera);
×
302
                readPolygonSetsFromJson(camera.name, userDirectory + camera.name + ".json");
×
303
                setCameraFieldDiameter(cameras[camera.name]);
×
UNCOV
304
        }
×
305
        qInfo() << "[MosaicCamera] Loaded" << cameras.size() << "cameras:" << cameras.keys().join(", ");
×
306
}
×
307

UNCOV
308
void MosaicCamera::readPolygonSetsFromJson(const QString& cameraName, const QString& filename)
×
309
{
310
        QVector<PolygonSet> polygonSets;
×
311

312
        QFile file(filename);
×
313
        if (!file.open(QIODevice::ReadOnly)) {
×
UNCOV
314
                qWarning() << "Couldn't open file:" << file.errorString();
×
315
        }
316

317
        QByteArray saveData = file.readAll();
×
UNCOV
318
        QJsonDocument loadDoc(QJsonDocument::fromJson(saveData));
×
UNCOV
319
        QJsonArray jsonArray = loadDoc.array();
×
320

321
        for (int i = 1; i < jsonArray.size(); ++i)
×
322
        {
UNCOV
323
                QJsonObject setObject = jsonArray[i].toObject();
×
324
                PolygonSet set;
×
325

326
                // Read name
327
                set.name = setObject["name"].toString();
×
328

329
                // Read corners
330
                QJsonArray cornersArray = setObject["corners"].toArray();
×
UNCOV
331
                for (int j = 0; j < cornersArray.size(); ++j)
×
332
                {
UNCOV
333
                        QVector<QPointF> polygon;
×
334
                        QJsonArray polygonArray = cornersArray[j].toArray();
×
UNCOV
335
                        for (int k = 0; k < polygonArray.size(); ++k)
×
336
                        {
UNCOV
337
                                QJsonArray pointArray = polygonArray[k].toArray();
×
UNCOV
338
                                if (pointArray.size() == 2)
×
339
                                {
340
                                        QPointF point(pointArray[0].toDouble(), pointArray[1].toDouble());
×
UNCOV
341
                                        polygon.append(point);
×
342
                                }
UNCOV
343
                        }
×
344
                        set.corners.append(polygon);
×
UNCOV
345
                }
×
346

347
                // Read color
UNCOV
348
                QJsonObject colorObject = setObject["color"].toObject();
×
349
                QJsonArray colorArray = colorObject["value"].toArray();
×
350
                if (colorArray.size() == 4)
×
351
                {
352
                        set.color = QColor::fromRgbF(colorArray[0].toDouble(), colorArray[1].toDouble(), colorArray[2].toDouble(), colorArray[3].toDouble());
×
353
                }
354

355
                polygonSets.append(set);
×
UNCOV
356
        }
×
357

UNCOV
358
        if (cameras.contains(cameraName))
×
359
        {
360
                // read the first one which is metadata
361
                QJsonObject setObject = jsonArray[0].toObject();
×
362
                cameras[cameraName].cameraName = setObject["camera_name"].toString();
×
UNCOV
363
                cameras[cameraName].cameraDescription = setObject["camera_description"].toString();
×
364
                cameras[cameraName].cameraURLDetails = setObject["camera_url"].toString();
×
UNCOV
365
                cameras[cameraName].polygon_sets = polygonSets;
×
UNCOV
366
        }
×
367
}
×
368

369
void MosaicCamera::setCameraFieldDiameter(Camera& camera)
×
370
{
371
        // First get all corners of all polygons
UNCOV
372
        QVector<QPointF> allCorners;
×
373
        for (const auto& polygonSet : camera.polygon_sets)
×
374
        {
UNCOV
375
                for (const auto& polygon : polygonSet.corners)
×
376
                {
UNCOV
377
                        allCorners.append(polygon);
×
378
                }
379
        }
380

381
        // Now calculate the maximum distance between any two corners
UNCOV
382
        double maxChordSq = 0.0;
×
383
        for (int i = 0; i < allCorners.size(); ++i)
×
384
        {
UNCOV
385
                for (int j = i + 1; j < allCorners.size(); ++j)
×
386
                {
387
                        double chordSq = gnomonicChordSeparationSquared(allCorners[i], allCorners[j]);
×
UNCOV
388
                        if (chordSq > maxChordSq)
×
389
                        {
UNCOV
390
                                maxChordSq = chordSq;
×
391
                        }
392
                }
393
        }
394
        camera.fieldDiameter = 2.0 * asin(0.5 * sqrt(maxChordSq)) * M_180_PI;
×
UNCOV
395
}
×
396

397
double MosaicCamera::gnomonicChordSeparationSquared(const QPointF& p1, const QPointF& p2)
×
398
{
399
        // Compute unit circle coordinates
400
        Vec3d v1(p1.x(), p1.y(), 1.0);
×
UNCOV
401
        Vec3d v2(p2.x(), p2.y(), 1.0);
×
402
        v1.normalize();
×
UNCOV
403
        v2.normalize();
×
404

405
        // Compute the chordal distance
406
        return (v1-v2).normSquared();
×
407
}
408

409
void MosaicCamera::setRA(const QString& cameraName, double ra)
×
410
{
UNCOV
411
        if (cameras.contains(cameraName))
×
412
        {
413
                cameras[cameraName].ra = ra;
×
UNCOV
414
                if(configDialog->visible())
×
415
                {
UNCOV
416
                        if (configDialog->getCurrentCameraName() == cameraName)
×
417
                                configDialog->setRA(ra);
×
418
                }
419
        }
420
}
×
421

422
void MosaicCamera::setDec(const QString& cameraName, double dec)
×
423
{
UNCOV
424
        if (cameras.contains(cameraName))
×
425
        {
426
                cameras[cameraName].dec = dec;
×
UNCOV
427
                if(configDialog->visible())
×
428
                {
UNCOV
429
                        if (configDialog->getCurrentCameraName() == cameraName)
×
430
                                configDialog->setDec(dec);
×
431
                }
432
        }
433
}
×
434

435
void MosaicCamera::setRotation(const QString& cameraName, double rotation)
×
436
{
437
        if (cameras.contains(cameraName))
×
438
        {
439
                cameras[cameraName].rotation = rotation;
×
UNCOV
440
                if(configDialog->visible())
×
441
                {
442
                        if (configDialog->getCurrentCameraName() == cameraName)
×
443
                                configDialog->setRotation(rotation);
×
444
                }
445
        }
UNCOV
446
}
×
447

UNCOV
448
void MosaicCamera::setVisibility(const QString& cameraName, bool visible)
×
449
{
450
        if (cameras.contains(cameraName))
×
451
        {
UNCOV
452
                cameras[cameraName].visible = visible;
×
453
                if(configDialog->visible())
×
454
                {
455
                        if (configDialog->getCurrentCameraName() == cameraName)
×
456
                                configDialog->setVisibility(visible);
×
457
                }
458
        }
459
}
×
460

461
void MosaicCamera::setPosition(const QString& cameraName, double ra, double dec, double rotation)
×
462
{
463
        setRA(cameraName, ra);
×
UNCOV
464
        setDec(cameraName, dec);
×
465
        setRotation(cameraName, rotation);
×
466
}
×
467

468
void MosaicCamera::setRADecToView()
×
469
{
470
        Vec3d current = GETSTELMODULE(StelMovementMgr)->getViewDirectionJ2000();
×
471
        double ra, dec;
472
        StelUtils::rectToSphe(&ra, &dec, current);
×
473
        // convert to degrees from radians
UNCOV
474
        ra = std::fmod((ra*M_180_PI)+360., 360.);
×
475
        dec = dec*M_180_PI;
×
UNCOV
476
        setCurrentRA(ra);
×
477
        setCurrentDec(dec);
×
478
}
×
479

480
void MosaicCamera::setRADecToObject()
×
481
{
482
        const QList<StelObjectP> selection = GETSTELMODULE(StelObjectMgr)->getSelectedObject();
×
UNCOV
483
        if (selection.isEmpty())
×
484
                return;
×
485

486
        StelObjectP obj = selection[0];
×
487
        double ra, dec;
UNCOV
488
        Vec3d pos = obj->getJ2000EquatorialPos(core);
×
489
        StelUtils::rectToSphe(&ra, &dec, pos);
×
UNCOV
490
        ra = std::fmod((ra*M_180_PI)+360., 360.);
×
491
        dec = dec*M_180_PI;
×
492
        setCurrentRA(ra);
×
493
        setCurrentDec(dec);
×
494
}
×
495

496
void MosaicCamera::setViewToCamera()
×
497
{
498
        double ra = getRA(currentCamera);
×
499
        double dec = getDec(currentCamera);
×
500

501
        Vec3d aim;
×
UNCOV
502
        StelUtils::spheToRect(ra/M_180_PI, dec/M_180_PI, 1.0, aim);
×
503
        const Vec3d aimUp(0.0, 0.0, 1.0);
×
UNCOV
504
        GETSTELMODULE(StelMovementMgr)->moveToJ2000(aim, aimUp);
×
505
        GETSTELMODULE(StelMovementMgr)->zoomTo(5 * cameras[currentCamera].fieldDiameter);
×
UNCOV
506
}
×
507

508
void MosaicCamera::incrementRotation()
×
509
{
510
        double rotation = getRotation(currentCamera);
×
UNCOV
511
        rotation += 5.0;
×
UNCOV
512
        setRotation(currentCamera, rotation);
×
513
}
×
514

515
void MosaicCamera::decrementRotation()
×
516
{
UNCOV
517
        double rotation = getRotation(currentCamera);
×
518
        rotation -= 5.0;
×
UNCOV
519
        setRotation(currentCamera, rotation);
×
520
}
×
521

UNCOV
522
void MosaicCamera::nextCamera()
×
523
{
UNCOV
524
        int index = cameraOrder.indexOf(currentCamera);
×
525
        index = (index + 1) % cameraOrder.size();
×
UNCOV
526
        setCurrentCamera(cameraOrder[index]);
×
527
}
×
528

529
void MosaicCamera::previousCamera()
×
530
{
UNCOV
531
        int index = cameraOrder.indexOf(currentCamera);
×
532
        index = (index - 1 + cameraOrder.size()) % cameraOrder.size();
×
UNCOV
533
        setCurrentCamera(cameraOrder[index]);
×
534
}
×
535

536
double MosaicCamera::getRA(const QString& cameraName) const
×
537
{
538
        return cameras.value(cameraName).ra;
×
539
}
540

UNCOV
541
double MosaicCamera::getDec(const QString& cameraName) const
×
542
{
543
        return cameras.value(cameraName).dec;
×
544
}
545

546
double MosaicCamera::getRotation(const QString& cameraName) const
×
547
{
548
        return cameras.value(cameraName).rotation;
×
549
}
550

UNCOV
551
bool MosaicCamera::getVisibility(const QString& cameraName) const
×
552
{
UNCOV
553
        return cameras.value(cameraName).visible;
×
554
}
555

556
void MosaicCamera::setCurrentCamera(const QString& cameraName)
×
557
{
558
        if (cameras.contains(cameraName))
×
559
        {
560
                currentCamera = cameraName;
×
561
                emit currentCameraChanged(cameraName);
×
UNCOV
562
                if(configDialog->visible())
×
563
                        configDialog->setCurrentCameraName(cameraName, cameras[cameraName].cameraName, cameras[cameraName].cameraDescription, cameras[cameraName].cameraURLDetails);
×
564
        }
UNCOV
565
}
×
566

UNCOV
567
void MosaicCamera::setCurrentRA(double ra)
×
568
{
UNCOV
569
        setRA(currentCamera, ra);
×
570
        emit currentRAChanged(ra);
×
571
}
×
572

573
void MosaicCamera::setCurrentDec(double dec)
×
574
{
575
        setDec(currentCamera, dec);
×
UNCOV
576
        emit currentDecChanged(dec);
×
577
}
×
578

UNCOV
579
void MosaicCamera::setCurrentRotation(double rotation)
×
580
{
581
        setRotation(currentCamera, rotation);
×
UNCOV
582
        emit currentRotationChanged(rotation);
×
583
}
×
584

UNCOV
585
void MosaicCamera::setCurrentVisibility(bool visible)
×
586
{
UNCOV
587
        setVisibility(currentCamera, visible);
×
UNCOV
588
        emit currentVisibilityChanged(visible);
×
UNCOV
589
}
×
590

UNCOV
591
void MosaicCamera::draw(StelCore* core)
×
592
{
593
        if (!isEnabled())
×
UNCOV
594
                return;
×
595

596
        const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
×
UNCOV
597
        StelPainter painter(prj);
×
598

599
        Vec3d startPoint, endPoint;
×
600

UNCOV
601
        for (const auto& camera : cameras)
×
602
        {
603
                if (!camera.visible)
×
604
                        continue;
×
605

UNCOV
606
                double alpha = camera.ra / M_180_PI + M_PI_2;
×
607
                double beta = M_PI_2 - camera.dec / M_180_PI;
×
608
                double rot = camera.rotation / M_180_PI;
×
609

610
                double cosBeta = cos(beta);
×
611
                double sinBeta = sin(beta);
×
612

UNCOV
613
                double cosAlpha = cos(alpha);
×
614
                double sinAlpha = sin(alpha);
×
615

616
                for (const auto& polygonSet : camera.polygon_sets)
×
617
                {
618
                        // Set color for this polygon set
619
                        painter.setColor(
×
620
                                                polygonSet.color.redF(),
621
                                                polygonSet.color.greenF(),
622
                                                polygonSet.color.blueF(),
623
                                                polygonSet.color.alphaF()
624
                                                );
625

UNCOV
626
                        for (const auto& polygon : polygonSet.corners)
×
627
                        {
628
                                // Loop through points in the polygon
629
                                for (int i = 0; i < polygon.size(); ++i)
×
630
                                {
UNCOV
631
                                        const QPointF& p1 = polygon[i];
×
UNCOV
632
                                        const QPointF& p2 = polygon[(i + 1) % polygon.size()];
×
633

634
                                        // Apply camera rotator
UNCOV
635
                                        double r1x = cos(rot) * p1.x() + sin(rot) * p1.y();
×
UNCOV
636
                                        double r1y = -sin(rot) * p1.x() + cos(rot) * p1.y();
×
UNCOV
637
                                        double r2x = cos(rot) * p2.x() + sin(rot) * p2.y();
×
638
                                        double r2y = -sin(rot) * p2.x() + cos(rot) * p2.y();
×
639

640
                                        double r1z = 1.0;
×
UNCOV
641
                                        double r2z = 1.0;
×
642

UNCOV
643
                                        double den1 = sqrt(r1x*r1x + r1y*r1y + r1z*r1z);
×
UNCOV
644
                                        double den2 = sqrt(r2x*r2x + r2y*r2y + r2z*r2z);
×
645

646
                                        // Apply declination
647
                                        double s1x = r1x;
×
648
                                        double s1y = r1y * cosBeta - r1z * sinBeta;
×
649
                                        double s1z = r1y * sinBeta + r1z * cosBeta;
×
UNCOV
650
                                        double s2x = r2x;
×
UNCOV
651
                                        double s2y = r2y * cosBeta - r2z * sinBeta;
×
UNCOV
652
                                        double s2z = r2y * sinBeta + r2z * cosBeta;
×
653

654
                                        // Apply right ascension
UNCOV
655
                                        startPoint.set(
×
UNCOV
656
                                                                (s1x*cosAlpha - s1y*sinAlpha)/den1,
×
UNCOV
657
                                                                (s1x*sinAlpha + s1y*cosAlpha)/den1,
×
658
                                                                s1z/den1
659
                                                                );
UNCOV
660
                                        endPoint.set(
×
UNCOV
661
                                                                (s2x*cosAlpha - s2y*sinAlpha)/den2,
×
UNCOV
662
                                                                (s2x*sinAlpha + s2y*cosAlpha)/den2,
×
663
                                                                s2z/den2
664
                                                                );
665

UNCOV
666
                                        painter.drawGreatCircleArc(startPoint, endPoint);
×
667
                                }
668
                        }
669
                }
670
        }
UNCOV
671
}
×
672

UNCOV
673
QStringList MosaicCamera::getCameraNames() const
×
674
{
UNCOV
675
        return cameraOrder;
×
676
}
677

UNCOV
678
bool MosaicCamera::configureGui(bool show)
×
679
{
UNCOV
680
        if (show)
×
UNCOV
681
                configDialog->setVisible(true);
×
UNCOV
682
        return true;
×
683
}
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