File indexing completed on 2024-07-14 07:17:20

0001 /*
0002     SPDX-FileCopyrightText: 2005 Jason Harris <kstars@30doradus.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "constellationlines.h"
0008 
0009 #include "kstarsdata.h"
0010 #include "kstars_debug.h"
0011 #include "linelist.h"
0012 #ifdef KSTARS_LITE
0013 #include "skymaplite.h"
0014 #else
0015 #include "skymap.h"
0016 #endif
0017 #include "Options.h"
0018 #include "skypainter.h"
0019 #include "skycomponents/culturelist.h"
0020 #include "skycomponents/starcomponent.h"
0021 #include "ksfilereader.h"
0022 
0023 ConstellationLines::ConstellationLines(SkyComposite *parent, CultureList *cultures)
0024     : LineListIndex(parent, i18n("Constellation Lines")), m_reindexNum(J2000)
0025 {
0026     //Create the ConstellationLinesComponents.  Each is a series of points
0027     //connected by line segments.  A single constellation can be composed of
0028     //any number of these series, and we don't need to know which series
0029     //belongs to which constellation.
0030 
0031     //The constellation lines data file (clines.dat) contains lists
0032     //of abbreviated genetive star names in the same format as they
0033     //appear in the star data files (hipNNN.dat).
0034     //
0035     //Each constellation consists of a QList of SkyPoints,
0036     //corresponding to the stars at each "node" of the constellation.
0037     //These are pointers to the starobjects themselves, so the nodes
0038     //will automatically be fixed to the stars even as the star
0039     //positions change due to proper motions.  In addition, each node
0040     //has a corresponding flag that determines whether a line should
0041     //connect this node and the previous one.
0042 
0043     intro();
0044 
0045     bool culture = false;
0046     std::shared_ptr<LineList> lineList;
0047     double maxPM(0.0);
0048     KSFileReader fileReader;
0049 
0050     if (!fileReader.open("clines.dat"))
0051         return;
0052 
0053     while (fileReader.hasMoreLines())
0054     {
0055         QString line = fileReader.readLine();
0056 
0057         if (line.isEmpty())
0058             continue;
0059 
0060         QChar mode = line.at(0);
0061 
0062         //ignore lines beginning with "#":
0063         if (mode == '#')
0064             continue;
0065         //If the first character is "M", we are starting a new series.
0066         //In this case, add the existing clc component to the composite,
0067         //then prepare a new one.
0068 
0069         if (mode == 'C')
0070         {
0071             QString cultureName = line.mid(2).trimmed();
0072             culture             = cultureName == cultures->current();
0073             continue;
0074         }
0075 
0076         if (culture)
0077         {
0078             //Mode == 'M' starts a new series of line segments, joined end to end
0079             if (mode == 'M')
0080             {
0081                 if (lineList.get())
0082                     appendLine(lineList);
0083                 lineList.reset(new LineList());
0084             }
0085 
0086             int HDnum        = line.mid(2).trimmed().toInt();
0087             std::shared_ptr<SkyPoint> star;
0088             StarObject* tempStar = StarComponent::Instance()->findByHDIndex(HDnum);
0089 
0090             if (tempStar && lineList)
0091             {
0092                 double pm = tempStar->pmMagnitude();
0093 
0094                 star.reset(new StarObject(*tempStar));
0095                 if (maxPM < pm)
0096                     maxPM = pm;
0097 
0098                 lineList->append(std::move(star));
0099             }
0100             else if (!star.get())
0101                 qCWarning(KSTARS) << i18n("Star HD%1 not found.", HDnum);
0102         }
0103     }
0104     //Add the last clc component
0105     if (lineList.get())
0106         appendLine(lineList);
0107 
0108     m_reindexInterval = StarObject::reindexInterval(maxPM);
0109     //printf("CLines:           maxPM = %6.1f milliarcsec/year\n", maxPM );
0110     //printf("CLines: Update Interval = %6.1f years\n", m_reindexInterval * 100.0 );
0111     summary();
0112 }
0113 
0114 bool ConstellationLines::selected()
0115 {
0116 #ifndef KSTARS_LITE
0117     return Options::showCLines() && !(Options::hideOnSlew() && Options::hideCLines() && SkyMap::IsSlewing());
0118 #else
0119     return Options::showCLines() && !(Options::hideOnSlew() && Options::hideCLines() && SkyMapLite::IsSlewing());
0120 #endif
0121 }
0122 
0123 void ConstellationLines::preDraw(SkyPainter *skyp)
0124 {
0125     KStarsData *data = KStarsData::Instance();
0126     QColor color     = data->colorScheme()->colorNamed("CLineColor");
0127     skyp->setPen(QPen(QBrush(color), 1, Qt::SolidLine));
0128 }
0129 
0130 const IndexHash &ConstellationLines::getIndexHash(LineList *lineList)
0131 {
0132     return skyMesh()->indexStarLine(lineList->points());
0133 }
0134 
0135 // JIT updating makes this simple.  Star updates are called from within both
0136 // StarComponent and ConstellationLines.  If the update is redundant then
0137 // StarObject::JITupdate() simply returns without doing any work.
0138 void ConstellationLines::JITupdate(LineList *lineList)
0139 {
0140     KStarsData *data   = KStarsData::Instance();
0141     lineList->updateID = data->updateID();
0142 
0143     SkyList *points = lineList->points();
0144 
0145     for (const auto &point : *points)
0146     {
0147         StarObject *star = (StarObject *)point.get();
0148 
0149         star->JITupdate();
0150     }
0151 }
0152 
0153 void ConstellationLines::reindex(KSNumbers *num)
0154 {
0155     if (!num)
0156         return;
0157 
0158     if (fabs(num->julianCenturies() - m_reindexNum.julianCenturies()) < m_reindexInterval)
0159         return;
0160 
0161     //printf("Re-indexing CLines to year %4.1f...\n", 2000.0 + num->julianCenturies() * 100.0);
0162 
0163     m_reindexNum = KSNumbers(*num);
0164     skyMesh()->setKSNumbers(num);
0165     LineListIndex::reindexLines();
0166 
0167     //printf("Done.\n");
0168 }