File indexing completed on 2024-04-14 03:43:20

0001 /*
0002     SPDX-FileCopyrightText: 2003 Jason Harris <jharris@30doradus.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "jmoontool.h"
0008 
0009 #include "ksnumbers.h"
0010 #include "kstars.h"
0011 
0012 #include "skymapcomposite.h"
0013 #include "skyobjects/jupitermoons.h"
0014 #include "skyobjects/ksplanet.h"
0015 #include "skyobjects/kssun.h"
0016 
0017 #include <KPlotting/KPlotObject>
0018 #include <KPlotting/KPlotWidget>
0019 #include <KPlotAxis>
0020 
0021 #include <QFrame>
0022 #include <QGridLayout>
0023 #include <QKeyEvent>
0024 #include <QVBoxLayout>
0025 
0026 JMoonTool::JMoonTool(QWidget *parent) : QDialog(parent)
0027 {
0028     QFrame *page = new QFrame(this);
0029 
0030     setWindowTitle(i18nc("@title:window", "Jupiter Moons Tool"));
0031     setModal(false);
0032 #ifdef Q_OS_OSX
0033     setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
0034 #endif
0035 
0036     QVBoxLayout *vlay = new QVBoxLayout;
0037     vlay->setContentsMargins(0, 0, 0, 0);
0038     vlay->setSpacing(0);
0039 
0040     setLayout(vlay);
0041 
0042     colJp = QColor(Qt::white);
0043     colIo = QColor(Qt::red);
0044     colEu = QColor(Qt::yellow);
0045     colGn = QColor(Qt::cyan);
0046     colCa = QColor(Qt::green);
0047 
0048     QLabel *labIo = new QLabel(i18n("Io"), page);
0049     QLabel *labEu = new QLabel(i18n("Europa"), page);
0050     QLabel *labGn = new QLabel(i18n("Ganymede"), page);
0051     QLabel *labCa = new QLabel(i18n("Callisto"), page);
0052 
0053     labIo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0054     labEu->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0055     labGn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0056     labCa->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
0057     labIo->setAlignment(Qt::AlignHCenter);
0058     labEu->setAlignment(Qt::AlignHCenter);
0059     labGn->setAlignment(Qt::AlignHCenter);
0060     labCa->setAlignment(Qt::AlignHCenter);
0061 
0062     QPalette p = palette();
0063     p.setColor(QPalette::Window, Qt::black);
0064     p.setColor(QPalette::WindowText, colIo);
0065     labIo->setPalette(p);
0066     p.setColor(QPalette::WindowText, colEu);
0067     labEu->setPalette(p);
0068     p.setColor(QPalette::WindowText, colGn);
0069     labGn->setPalette(p);
0070     p.setColor(QPalette::WindowText, colCa);
0071     labCa->setPalette(p);
0072     labIo->setAutoFillBackground(true);
0073     labEu->setAutoFillBackground(true);
0074     labGn->setAutoFillBackground(true);
0075     labCa->setAutoFillBackground(true);
0076 
0077     QGridLayout *glay = new QGridLayout();
0078     glay->addWidget(labIo, 0, 0);
0079     glay->addWidget(labEu, 1, 0);
0080     glay->addWidget(labGn, 0, 1);
0081     glay->addWidget(labCa, 1, 1);
0082 
0083     pw = new KPlotWidget(page);
0084     pw->setShowGrid(false);
0085     pw->setAntialiasing(true);
0086     pw->setLimits(-12.0, 12.0, -11.0, 11.0);
0087     pw->axis(KPlotWidget::BottomAxis)->setLabel(i18n("offset from Jupiter (arcmin)"));
0088     pw->axis(KPlotWidget::LeftAxis)->setLabel(i18n("time since now (days)"));
0089     vlay->addLayout(glay);
0090     vlay->addWidget(pw);
0091     resize(350, 600);
0092 
0093     QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
0094     vlay->addWidget(buttonBox);
0095     connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
0096 
0097     initPlotObjects();
0098     update();
0099 }
0100 
0101 void JMoonTool::initPlotObjects()
0102 {
0103     KPlotObject *orbit[4];
0104     KPlotObject *jpath;
0105     long double jd0 = KStarsData::Instance()->ut().djd();
0106     KSSun *ksun     = dynamic_cast<KSSun *>(KStarsData::Instance()->skyComposite()->findByName(i18n("Sun")));
0107     KSPlanet *jup   = dynamic_cast<KSPlanet *>(KStarsData::Instance()->skyComposite()->findByName(i18n("Jupiter")));
0108     JupiterMoons jm;
0109 
0110     pw->removeAllPlotObjects();
0111 
0112     orbit[0] = new KPlotObject(colIo, KPlotObject::Lines, 1.0);
0113     orbit[1] = new KPlotObject(colEu, KPlotObject::Lines, 1.0);
0114     orbit[2] = new KPlotObject(colGn, KPlotObject::Lines, 1.0);
0115     orbit[3] = new KPlotObject(colCa, KPlotObject::Lines, 1.0);
0116     jpath    = new KPlotObject(colJp, KPlotObject::Lines, 1.0);
0117 
0118     QRectF dataRect = pw->dataRect();
0119     double dy       = 0.01 * dataRect.height();
0120 
0121     /*Debug
0122     //For testing position of each satellite
0123     for(double t = dataRect.y(); t <= dataRect.bottom(); t += 1){
0124         KSNumbers num(jd0 + t);
0125         jm.findPosition(&num, jup, ksun);
0126 
0127         qDebug() << Q_FUNC_INFO << "Position [Io] : " << 0.5 * jup->angSize() * jm.x(0) << " at " << t << " arcmin";
0128         qDebug() << Q_FUNC_INFO << "Position [Europa] : " << 0.5 * jup->angSize() * jm.x(1) << " at " << t << " arcmin";
0129         qDebug() << Q_FUNC_INFO << "Position [Ganymede] : " << 0.5 * jup->angSize() * jm.x(2) << " at " << t << " arcmin";
0130         qDebug() << Q_FUNC_INFO << "Position [Callisto] : " << 0.5 * jup->angSize() * jm.x(3) << " at " << t << " arcmin";
0131     }
0132     */
0133 
0134     //t is the offset from jd0, in days.
0135     for (double t = dataRect.y(); t <= dataRect.bottom(); t += dy)
0136     {
0137         KSNumbers num(jd0 + t);
0138         jm.findPosition(&num, jup, ksun);
0139 
0140         //jm.x(i) tells the offset from Jupiter, in units of Jupiter's angular radius.
0141         //multiply by 0.5*jup->angSize() to get arcminutes
0142         for (unsigned int i = 0; i < 4; ++i)
0143             orbit[i]->addPoint(0.5 * jup->angSize() * jm.x(i), t);
0144 
0145         jpath->addPoint(0.0, t);
0146     }
0147 
0148     for (unsigned int i = 0; i < 4; ++i)
0149         pw->addPlotObject(orbit[i]);
0150 
0151     pw->addPlotObject(jpath);
0152 }
0153 
0154 void JMoonTool::keyPressEvent(QKeyEvent *e)
0155 {
0156     QRectF dataRect = pw->dataRect();
0157     switch (e->key())
0158     {
0159         case Qt::Key_BracketRight:
0160         {
0161             double dy = 0.02 * dataRect.height();
0162             pw->setLimits(dataRect.x(), dataRect.right(), dataRect.y() + dy, dataRect.bottom() + dy);
0163             initPlotObjects();
0164             pw->update();
0165             break;
0166         }
0167         case Qt::Key_BracketLeft:
0168         {
0169             double dy = 0.02 * dataRect.height();
0170             pw->setLimits(dataRect.x(), dataRect.right(), dataRect.y() - dy, dataRect.bottom() - dy);
0171             initPlotObjects();
0172             pw->update();
0173             break;
0174         }
0175         case Qt::Key_Plus:
0176         case Qt::Key_Equal:
0177         {
0178             if (dataRect.height() > 2.0)
0179             {
0180                 double dy = 0.45 * dataRect.height();
0181                 double y0 = dataRect.y() + 0.5 * dataRect.height();
0182                 pw->setLimits(dataRect.x(), dataRect.right(), y0 - dy, y0 + dy);
0183                 initPlotObjects();
0184                 pw->update();
0185             }
0186             break;
0187         }
0188         case Qt::Key_Minus:
0189         case Qt::Key_Underscore:
0190         {
0191             if (dataRect.height() < 40.0)
0192             {
0193                 double dy = 0.55 * dataRect.height();
0194                 double y0 = dataRect.y() + 0.5 * dataRect.height();
0195                 pw->setLimits(dataRect.x(), dataRect.right(), y0 - dy, y0 + dy);
0196                 initPlotObjects();
0197                 pw->update();
0198             }
0199             break;
0200         }
0201         case Qt::Key_Escape:
0202         {
0203             close();
0204             break;
0205         }
0206 
0207         default:
0208         {
0209             e->ignore();
0210             break;
0211         }
0212     }
0213 }