Observability.cpp   Observability.cpp 
skipping to change at line 19 skipping to change at line 19
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include <QSettings>
#include <QPixmap>
#include <QTimer>
#include <QString>
#include <QDebug> #include <QDebug>
#include <QAction>
#include <QKeyEvent>
#include <QtNetwork>
#include <QKeyEvent> #include <QKeyEvent>
#include <QMouseEvent> #include <QMouseEvent>
#include <QPixmap>
#include <QSettings>
#include <QString>
#include <QTimer>
#include "renderer/StelRenderer.hpp" //#include <QtNetwork> // Why do we need a full part of the framwork again?
#include "StelIniParser.hpp"
#include "StelProjector.hpp" #include "Observability.hpp"
#include "ObservabilityDialog.hpp"
#include "Planet.hpp"
#include "SolarSystem.hpp"
#include "StarMgr.hpp" #include "StarMgr.hpp"
#include "StelObject.hpp" #include "StelActionMgr.hpp"
#include "StelObserver.hpp"
#include "StelUtils.hpp"
#include "StelApp.hpp" #include "StelApp.hpp"
#include "StelObjectMgr.hpp" #include "StelCore.hpp"
#include "StelLocaleMgr.hpp" #include "StelFader.hpp"
#include "StelModuleMgr.hpp" #include "StelFileMgr.hpp"
#include "StelGui.hpp" #include "StelGui.hpp"
#include "StelGuiItems.hpp" #include "StelGuiItems.hpp"
#include "StelIniParser.hpp"
#include "StelLocaleMgr.hpp"
#include "StelModuleMgr.hpp"
#include "StelMovementMgr.hpp" #include "StelMovementMgr.hpp"
#include "StelFileMgr.hpp" #include "StelObject.hpp"
#include "StelCore.hpp" #include "StelObjectMgr.hpp"
#include "ZoneArray.hpp" #include "StelObserver.hpp"
#include "StelProjector.hpp"
#include "StelSkyDrawer.hpp" #include "StelSkyDrawer.hpp"
#include "Observability.hpp" #include "StelUtils.hpp"
#include "ObservabilityDialog.hpp" #include "StelPainter.hpp"
#include "ZoneArray.hpp"
#include "SolarSystem.hpp"
#include "Planet.hpp"
#include "StelFader.hpp"
StelModule* ObservabilityStelPluginInterface::getStelModule() const StelModule* ObservabilityStelPluginInterface::getStelModule() const
{ {
return new Observability(); return new Observability();
} }
StelPluginInfo ObservabilityStelPluginInterface::getPluginInfo() const StelPluginInfo ObservabilityStelPluginInterface::getPluginInfo() const
{ {
Q_INIT_RESOURCE(Observability); Q_INIT_RESOURCE(Observability);
StelPluginInfo info; StelPluginInfo info;
info.id = "Observability"; info.id = "Observability";
info.displayedName = N_("Observability analysis"); info.displayedName = N_("Observability Analysis");
info.authors = "Ivan Marti-Vidal (Onsala Space Observatory)"; // non -translatable field info.authors = "Ivan Marti-Vidal (Onsala Space Observatory)"; // non -translatable field
info.contact = "i.martividal@gmail.com"; info.contact = "i.martividal@gmail.com";
info.description = N_("Reports an analysis of source observability info.description = N_("Displays an analysis of a selected object's o
(rise, set, and transit times), as well as the epochs of year when the sour bservability (rise, set, and transit times) for the current date, as well a
ce is best observed. It assumes that a source is observable if it is above s when it is observable through the year. An object is assumed to be observ
the horizon during a fraction of the night. The plugin also gives the day f able if it is above the horizon during a fraction of the night. Also includ
or largest separation from the Sun and the days of Acronychal and Cosmical ed are the dates of the largest separation from the Sun and acronychal and
rise/set.<br><br> An explanation of the quantities shown by this script is cosmical rising and setting. (Explanations are provided in the 'About' tab
given in the 'About' tab of the configuration window"); of the plugin's configuration window.)");
return info; info.version = OBSERVABILITY_PLUGIN_VERSION;
return info;
} }
Q_EXPORT_PLUGIN2(Observability, ObservabilityStelPluginInterface)
Observability::Observability() Observability::Observability()
: flagShowObservability(false), OnIcon(NULL), OffIcon(NULL), GlowIco : Jan1stJD(0.)
n(NULL),toolbarButton(NULL) , GMTShift(0.)
, twilightAltRad(0.)
, twilightAltDeg(0.)
, horizonAltitude(0.)
, horizonAltDeg(0.)
, selRA(0.)
, selDec(0.)
, alti(0.)
, horizH(0.)
, culmAlt(0.)
, MoonRise(0.)
, MoonSet(0.)
, MoonCulm(0.)
, lastJDMoon(0.)
, ObserverLoc(0.)
, myPlanet(NULL)
, nDays(0)
, dmyFormat(false)
, hasRisen(false)
, configChanged(false)
, souChanged(false)
, lastType(0)
, show_AcroCos(false)
, show_Good_Nights(false)
, show_Best_Night(false)
, show_Today(false)
, show_FullMoon(false)
, flagShowReport(false)
, fontSize(14)
, button(NULL)
{ {
setObjectName("Observability"); setObjectName("Observability");
configDialog = new ObservabilityDialog(); configDialog = new ObservabilityDialog();
// TODO: Migrate to static const? --BM
// Some useful constants: // Some useful constants:
Rad2Deg = 180./3.1415927; // Convert degrees into radians Rad2Deg = 180./3.1415927; // Convert degrees into radians
Rad2Hr = 12./3.1415927; // Convert hours into radians Rad2Hr = 12./3.1415927; // Convert hours into radians
UA = 1.4958e+8; // Astronomical Unit in Km. UA = 1.4958e+8; // Astronomical Unit in Km.
TFrac = 0.9972677595628414; // Convert sidereal time into Solar tim e TFrac = 0.9972677595628414; // Convert sidereal time into Solar tim e
JDsec = 1./86400.; // A second in days. JDsec = 1./86400.; // A second in days.
halfpi = 1.57079632675; // pi/2 halfpi = 1.57079632675; // pi/2
MoonT = 29.530588; // Moon synodic period (used as first estimate of Full Moon). MoonT = 29.530588; // Moon synodic period (used as first estimate of Full Moon).
RefFullMoon = 2451564.696; // Reference Julian date of a Full Moon. RefFullMoon = 2451564.696; // Reference Julian date of a Full Moon.
MoonPerilune = 0.0024236308; // Smallest Earth-Moon distance (in AU) . MoonPerilune = 0.0024236308; // Smallest Earth-Moon distance (in AU) .
nextFullMoon = 0.0; nextFullMoon = 0.0;
prevFullMoon = 0.0; prevFullMoon = 0.0;
RefracHoriz = 0.0; // Geometric altitude at refraction-corrected h orizon. refractedHorizonAlt = 0.0;
selName = ""; selName = "";
////////////////////////////
// Read configuration:
QSettings* conf = StelApp::getInstance().getSettings();
// Setup defaults if not present
conf->beginGroup("Observability");
if (!conf->contains("font_size"))
conf->setValue("font_size", 15);
if (!conf->contains("font_color"))
conf->setValue("font_color", "0,0.5,1");
if (!conf->contains("show_AcroCos"))
conf->setValue("show_AcroCos", true);
if (!conf->contains("show_Good_Nights"))
conf->setValue("show_Good_Nights", true);
if (!conf->contains("show_Best_Night"))
conf->setValue("show_Best_Night", true);
if (!conf->contains("show_Today"))
conf->setValue("show_Today", true);
if (!conf->contains("Sun_Altitude"))
conf->setValue("Sun_Altitude", 12);
if (!conf->contains("Horizon_Altitude"))
conf->setValue("Horizon_Altitude", 0);
if (!conf->contains("show_FullMoon"))
conf->setValue("show_FullMoon", true);
// if (!conf->contains("show_Crescent"))
// conf->setValue("show_Crescent", true);
// if (!conf->contains("show_SuperMoon"))
// conf->setValue("show_SuperMoon", true);
// Load settings from main config file
fontSize = conf->value("font_size",15).toInt();
iAltitude = conf->value("Sun_Altitude",12).toInt();
iHorizAltitude = conf->value("Horizon_Altitude",0).toInt();
AstroTwiAlti = -((double) iAltitude)/Rad2Deg ;
HorizAlti = ((double) iHorizAltitude)/Rad2Deg ;
font.setPixelSize(fontSize);
QString fontColorStr = conf->value("font_color", "0,0.5,1").toString
();
fontColor = StelUtils::strToVec3f(fontColorStr);
show_AcroCos = conf->value("show_AcroCos", true).toBool();
show_Good_Nights = conf->value("show_Good_Nights", true).toBool();
show_Best_Night = conf->value("show_Best_Night", true).toBool();
show_Today = conf->value("show_Today", true).toBool();
show_FullMoon = conf->value("show_FullMoon", true).toBool();
// show_Crescent = conf->value("show_Crescent", true).toBool();
// show_SuperMoon = conf->value("show_SuperMoon", true).toBool();
conf->endGroup();
/////////////////////////////////
// Apply format for date from main settings
if (conf->value("localization/date_display_format", "system_default"
).toString() == "ddmmyyyy")
setDateFormat(true);
else
setDateFormat(false);
// Dummy initial values for parameters and data vectors: // Dummy initial values for parameters and data vectors:
mylat = 1000.; mylon = 1000.; mylat = 1000.; mylon = 1000.;
myJD = 0.0; myJD = 0.0;
currYear = 0; curYear = 0;
isStar = true; isStar = true;
isMoon = false; isMoon = false;
isSun = false; isSun = false;
isScreen = true; isScreen = true;
raised=false;
ObserverLoc[0]=0.0;ObserverLoc[1]=0.0;ObserverLoc[2]=0.0;
//Get pointer to the Earth: //Get pointer to the Earth:
PlanetP Earth = GETSTELMODULE(SolarSystem)->getEarth(); PlanetP Earth = GETSTELMODULE(SolarSystem)->getEarth();
myEarth = Earth.data(); myEarth = Earth.data();
// Get pointer to the Moon/Sun: // Get pointer to the Moon/Sun:
PlanetP Moon = GETSTELMODULE(SolarSystem)->getMoon(); PlanetP Moon = GETSTELMODULE(SolarSystem)->getMoon();
myMoon = Moon.data(); myMoon = Moon.data();
// I think this can be done in a more simple way...--BM
for (int i=0;i<366;i++) { for (int i=0;i<366;i++) {
SunRA[i] = 0.0; SunDec[i] = 0.0; sunRA[i] = 0.0; sunDec[i] = 0.0;
ObjectRA[i] = 0.0; ObjectDec[i]=0.0; objectRA[i] = 0.0; objectDec[i]=0.0;
SunSidT[0][i]=0.0; SunSidT[1][i]=0.0; sunSidT[0][i]=0.0; sunSidT[1][i]=0.0;
ObjectSidT[0][i]=0.0; ObjectSidT[1][i]=0.0; objectSidT[0][i]=0.0; objectSidT[1][i]=0.0;
ObjectH0[i] = 0.0; objectH0[i] = 0.0;
yearJD[i] = 0.0; yearJD[i] = 0.0;
}; };
} }
Observability::~Observability() Observability::~Observability()
{ {
if (GlowIcon!=NULL) // Shouldn't this be in the deinit()? --BM
delete GlowIcon; if (configDialog != NULL)
if (OnIcon!=NULL) delete configDialog;
delete OnIcon;
if (OffIcon!=NULL)
delete OffIcon;
delete configDialog;
} }
void Observability::updateMessageText() void Observability::updateMessageText()
{ {
// Set names of the months: // Set names of the months:
QString mons[12]={qc_("Jan", "short month name"), qc_("Feb", "short monthNames.clear();
month name"), qc_("Mar", "short month name"), qc_("Apr", "short month name" monthNames << qc_("Jan", "short month name")
), qc_("May", "short month name"), qc_("Jun", "short month name"), qc_("Jul << qc_("Feb", "short month name")
", "short month name"), qc_("Aug", "short month name"), qc_("Sep", "short m << qc_("Mar", "short month name")
onth name"), qc_("Oct", "short month name"), qc_("Nov", "short month name") << qc_("Apr", "short month name")
, qc_("Dec", "short month name")}; << qc_("May", "short month name")
<< qc_("Jun", "short month name")
for (int i=0;i<12;i++) { << qc_("Jul", "short month name")
months[i]=mons[i]; << qc_("Aug", "short month name")
}; << qc_("Sep", "short month name")
<< qc_("Oct", "short month name")
<< qc_("Nov", "short month name")
<< qc_("Dec", "short month name");
// TRANSLATORS: Short for "hours".
msgH = q_("h"); msgH = q_("h");
// TRANSLATORS: Short for "minutes".
msgM = q_("m"); msgM = q_("m");
// TRANSLATORS: Short for "seconds".
msgS = q_("s"); msgS = q_("s");
msgSetsAt = q_("Sets at %1 (in %2)"); msgSetsAt = q_("Sets at %1 (in %2)");
msgRoseAt = q_("Rose at %1 (%2 ago)"); msgRoseAt = q_("Rose at %1 (%2 ago)");
msgSetAt = q_("Set at %1 (%2 ago)"); msgSetAt = q_("Set at %1 (%2 ago)");
msgRisesAt = q_("Rises at %1 (in %2)"); msgRisesAt = q_("Rises at %1 (in %2)");
msgCircumpolar = q_("Circumpolar."); msgCircumpolar = q_("Circumpolar.");
msgNoRise = q_("No rise."); msgNoRise = q_("No rise.");
msgCulminatesAt = q_("Culminates at %1 (in %2) at %3 deg."); msgCulminatesAt = q_("Culminates at %1 (in %2) at %3 deg.");
msgCulminatedAt = q_("Culminated at %1 (%2 ago) at %3 deg."); msgCulminatedAt = q_("Culminated at %1 (%2 ago) at %3 deg.");
msgSrcNotObs = q_("Source is not observable."); msgSrcNotObs = q_("Source is not observable.");
msgNoACRise = q_("No Acronychal nor Cosmical rise/set."); msgNoACRise = q_("No acronychal nor cosmical rise/set.");
msgGreatElong = q_("Greatest elongation: "); msgGreatElong = q_("Greatest elongation: %1 (at %2 deg.)");
msgLargSSep = q_("Largest Sun separation: "); msgLargSSep = q_("Largest Sun separation: %1 (at %2 deg.)");
msgAtDeg = q_(" (at %1 deg.)");
msgNone = q_("None"); msgNone = q_("None");
msgAcroRise = q_("Acronychal rise/set"); // TRANSLATORS: The space at the end is significant - another senten
msgNoAcroRise = q_("No Acronychal rise/set."); ce may follow.
msgCosmRise = q_("Cosmical rise/set"); msgAcroRise = q_("Acronychal rise/set: %1/%2. ");
msgNoCosmRise = q_("No Cosmical rise/set."); // TRANSLATORS: The space at the end is significant - another senten
ce may follow.
msgNoAcroRise = q_("No acronychal rise/set. ");
msgCosmRise = q_("Cosmical rise/set: %1/%2.");
msgNoCosmRise = q_("No cosmical rise/set.");
msgWholeYear = q_("Observable during the whole year."); msgWholeYear = q_("Observable during the whole year.");
msgNotObs = q_("Not observable at dark night."); msgNotObs = q_("Not observable at dark night.");
msgAboveHoriz = q_("Nights above horizon: "); msgAboveHoriz = q_("Nights above horizon: %1");
msgToday = q_("TODAY:"); msgToday = q_("TODAY:");
msgThisYear = q_("THIS YEAR:"); msgThisYear = q_("THIS YEAR:");
// TRANSLATORS: The space at the end is significant - another senten ce may follow.
msgPrevFullMoon = q_("Previous Full Moon: %1 %2 at %3:%4. "); msgPrevFullMoon = q_("Previous Full Moon: %1 %2 at %3:%4. ");
msgNextFullMoon = q_("Next Full Moon: %1 %2 at %3:%4. "); msgNextFullMoon = q_("Next Full Moon: %1 %2 at %3:%4. ");
} }
double Observability::getCallOrder(StelModuleActionName actionName) const double Observability::getCallOrder(StelModuleActionName actionName) const
{ {
if (actionName==StelModule::ActionDraw) if (actionName==StelModule::ActionDraw)
return StelApp::getInstance().getModuleMgr().getModule("Land return StelApp::getInstance().getModuleMgr().getModule("Land
scapeMgr")->getCallOrder(actionName)+10.; scapeMgr")->getCallOrder(actionName)+10.;
return 0; return 0;
} }
void Observability::init() void Observability::init()
{ {
qDebug() << "init called for Observability"; loadConfiguration();
try StelAction* actionShow = addAction("actionShow_Observability",
{ N_("Observability"),
StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance() N_("Observability"),
.getGui()); "flagShowReport");
GlowIcon = new QPixmap(":/graphicGui/glow32x32.png"); // actionShow->setChecked(flagShowReport); //Unnecessary?
OnIcon = new QPixmap(":/observability/bt_observab_on.png"); addAction("actionShow_Observability_ConfigDialog",
OffIcon = new QPixmap(":/observability/bt_observab_off.png") N_("Observability"),
; N_("Observability configuration window"),
configDialog, "visible");
gui->getGuiAction("actionShow_Observability")->setChecked(fl
agShowObservability); StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui(
toolbarButton = new StelButton(NULL, *OnIcon, *OffIcon, *Glo ));
wIcon, gui->getGuiAction("actionShow_Observability")); if (gui!=NULL)
gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGr {
oup"); button = new StelButton(NULL,
connect(gui->getGuiAction("actionShow_Observability"), SIGNA QPixmap(":/observability/bt_observab
L(toggled(bool)), this, SLOT(enableObservability(bool))); _on.png"),
connect(gui->getGuiAction("actionShow_Observability_ConfigDi QPixmap(":/observability/bt_observab
alog"), SIGNAL(toggled(bool)), configDialog, SLOT(setVisible(bool))); _off.png"),
connect(configDialog, SIGNAL(visibleChanged(bool)), gui->get QPixmap(":/graphicGui/glow32x32.png"
GuiAction("actionShow_Observability_ConfigDialog"), SLOT(setChecked(bool))) ),
; actionShow);
gui->getButtonBar()->addButton(button, "065-pluginsGroup");
} }
catch (std::exception &e)
{
qWarning() << "WARNING: unable create toolbar button for Obs
ervability plugin (or load gonfig GUI). " << e.what();
};
updateMessageText(); updateMessageText();
connect(&StelApp::getInstance(), SIGNAL(languageChanged()), this, SL connect(&StelApp::getInstance(), SIGNAL(languageChanged()),
OT(updateMessageText())); this, SLOT(updateMessageText()));
} }
///////////////////////////////////////////// /////////////////////////////////////////////
// MAIN CODE: // MAIN CODE:
void Observability::draw(StelCore* core, StelRenderer* renderer) void Observability::draw(StelCore* core)
{ {
if (!flagShowReport)
if (!flagShowObservability) return; // Button is off. return; // Button is off.
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// PRELIMINARS: // PRELIMINARS:
bool locChanged, yearChanged; bool locChanged, yearChanged;
StelObjectP selectedObject; StelObjectP selectedObject;
Planet* currPlanet; PlanetP ssObject, parentPlanet;
PlanetP Object, parent;
// Only execute plugin if we are on Earth. // Only execute plugin if we are on Earth.
if (core->getCurrentLocation().planetName != "Earth") {return;}; if (core->getCurrentLocation().planetName != "Earth")
return;
// Set the painter: // Set the painter:
StelProjectorP projector = core->getProjection2d(); StelPainter painter(core->getProjection2d());
renderer->setGlobalColor(fontColor[0],fontColor[1],fontColor[2],1); painter.setColor(fontColor[0],fontColor[1],fontColor[2],1);
font.setPixelSize(fontSize); font.setPixelSize(fontSize);
renderer->setFont(font); painter.setFont(font);
// Get current date, location, and check if there is something selected. // Get current date, location, and check if there is something selected.
double currlat = (core->getCurrentLocation().latitude)/Rad2Deg; double currlat = (core->getCurrentLocation().latitude)/Rad2Deg;
double currlon = (core->getCurrentLocation().longitude)/Rad2Deg; double currlon = (core->getCurrentLocation().longitude)/Rad2Deg;
double currheight = (6371.+(core->getCurrentLocation().altitude)/100 0.)/UA; double currheight = (6371.+(core->getCurrentLocation().altitude)/100 0.)/UA;
double currJD = core->getJDay(); double currJD = core->getJDay();
double currJDint; double currJDint;
// GMTShift = StelUtils::getGMTShiftFromQT(currJD)/24.0; // GMTShift = StelUtils::getGMTShiftFromQT(currJD)/24.0;
GMTShift = StelApp::getInstance().getLocaleMgr().getGMTShift(currJD) /24.0; GMTShift = StelApp::getInstance().getLocaleMgr().getGMTShift(currJD) /24.0;
// qDebug() << QString("%1%2 ").arg(GMTShift); // qDebug() << QString("%1%2 ").arg(GMTShift);
double currLocalT = 24.*modf(currJD + GMTShift,&currJDint); double currLocalT = 24.*modf(currJD + GMTShift,&currJDint);
int auxm, auxd, auxy; int auxm, auxd, auxy;
StelUtils::getDateFromJulianDay(currJD,&auxy,&auxm,&auxd); StelUtils::getDateFromJulianDay(currJD, &auxy, &auxm, &auxd);
bool isSource = StelApp::getInstance().getStelObjectMgr().getWasSele cted(); bool isSource = StelApp::getInstance().getStelObjectMgr().getWasSele cted();
bool show_Year = show_Best_Night || show_Good_Nights || show_AcroCos ; bool show_Year = show_Best_Night || show_Good_Nights || show_AcroCos ;
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// NOW WE CHECK THE CHANGED PARAMETERS W.R.T. THE PREVIOUS FRAME: // NOW WE CHECK THE CHANGED PARAMETERS W.R.T. THE PREVIOUS FRAME:
// Update JD. // Update JD.
myJD = currJD; myJD = currJD;
// If we have changed the year, we must recompute the Sun's position for ea // If the year changed, we must recompute the Sun's position for each new d
ch new day: ay:
if (auxy != currYear) { if (auxy != curYear)
{
yearChanged = true; yearChanged = true;
currYear = auxy; curYear = auxy;
SunRADec(core);} updateSunData(core);
else { }
else
{
yearChanged = false; yearChanged = false;
}; };
// Have we changed the latitude or longitude? // Have we changed the latitude or longitude?
if (currlat == mylat && currlon == mylon) { if (currlat == mylat && currlon == mylon)
locChanged = false;} {
else { locChanged = false;
}
else
{
locChanged = true; locChanged = true;
mylat = currlat; mylon = currlon; mylat = currlat; mylon = currlon;
double temp1 = currheight*std::cos(currlat); double temp1 = currheight*std::cos(currlat);
ObserverLoc[0] = temp1*std::cos(currlon); ObserverLoc[0] = temp1*std::cos(currlon);
ObserverLoc[1] = temp1*std::sin(currlon); ObserverLoc[1] = temp1*std::sin(currlon);
ObserverLoc[2] = currheight*std::sin(currlat); ObserverLoc[2] = currheight*std::sin(currlat);
}; };
// Add refraction, if necessary: // Add refraction, if necessary:
Vec3d TempRefr; Vec3d TempRefr;
TempRefr[0] = std::cos(HorizAlti); TempRefr[0] = std::cos(horizonAltitude);
TempRefr[1] = 0.0; TempRefr[1] = 0.0;
TempRefr[2] = std::sin(HorizAlti); TempRefr[2] = std::sin(horizonAltitude);
Vec3d CorrRefr = core->altAzToEquinoxEqu(TempRefr,StelCore::Refracti onAuto); Vec3d CorrRefr = core->altAzToEquinoxEqu(TempRefr,StelCore::Refracti onAuto);
TempRefr = core->equinoxEquToAltAz(CorrRefr,StelCore::RefractionOff) ; TempRefr = core->equinoxEquToAltAz(CorrRefr,StelCore::RefractionOff) ;
double RefracAlt = std::asin(TempRefr[2]); double RefracAlt = std::asin(TempRefr[2]);
if (std::abs(RefracHoriz-RefracAlt)>2.91e-4) // Diference larger th // If the diference is larger than 1 arcminute...
an 1 arcminute. if (std::abs(refractedHorizonAlt-RefracAlt)>2.91e-4)
{ // Configuration for refraction changed notably: {
RefracHoriz = RefracAlt; //... configuration for refraction changed notably.
refractedHorizonAlt = RefracAlt;
configChanged = true; configChanged = true;
souChanged = true; souChanged = true;
}; };
// If we have changed latitude (or year), we update the vector of Sun's hou r // If we have changed latitude (or year), we update the vector of Sun's hou r
// angles at twilight, and re-compute Sun/Moon ephemeris (if selected): // angles at twilight, and re-compute Sun/Moon ephemeris (if selected):
if (locChanged || yearChanged || configChanged) if (locChanged || yearChanged || configChanged)
{ {
SunHTwi(); updateSunH();
lastJDMoon = 0.0; lastJDMoon = 0.0;
}; };
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////
// NOW WE DEAL WITH THE SOURCE (OR SCREEN-CENTER) POSITION: // NOW WE DEAL WITH THE SOURCE (OR SCREEN-CENTER) POSITION:
if (isScreen) souChanged=true; // Always re-compute everything for t if (isScreen) // Always re-compute everything for the screen center.
he screen center. souChanged = true;
if (isSource) { // There is something selected! if (isSource) // There is something selected!
{
// Get the selected source and its name: // Get the selected source and its name:
selectedObject = StelApp::getInstance().getStelObjectMgr().g etSelectedObject()[0]; selectedObject = StelApp::getInstance().getStelObjectMgr().g etSelectedObject()[0];
// Don't do anything for satellites: // Don't do anything for satellites:
if(selectedObject->getType()== "Satellite") return; if(selectedObject->getType() == "Satellite")
return;
QString tempName = selectedObject->getEnglishName();
// Check if the source is Sun or Moon (i.e., it changes quite a bit during QString name = selectedObject->getEnglishName();
one day): isMoon = ("Moon" == name);
isMoon = ("Moon" == tempName)?true:false; isSun = ("Sun" == name);
isSun = ("Sun" == tempName)?true:false;
// If Moon is not selected (or was unselected), force re-compute of Full Mo on next time it is selected: // If Moon is not selected (or was unselected), force re-compute of Full Mo on next time it is selected:
if (!isMoon) {prevFullMoon=0.0; nextFullMoon=0.0;}; if (!isMoon)
{
prevFullMoon = 0.0;
nextFullMoon = 0.0;
};
//Update position: //Update position:
EquPos = selectedObject->getEquinoxEquatorialPos(core); EquPos = selectedObject->getEquinoxEquatorialPos(core);
EquPos.normalize(); EquPos.normalize();
LocPos = core->equinoxEquToAltAz(EquPos,StelCore::Refraction Off); LocPos = core->equinoxEquToAltAz(EquPos, StelCore::Refractio nOff);
// Check if the user has changed the source (or if the source is Sun/Moon). // Check if the user has changed the source (or if the source is Sun/Moon).
if (tempName == selName) if (name == selName)
{ {
souChanged = false;} souChanged = false;
}
else else
{ // Check also if the (new) source belongs to the Solar Sys tem: { // Check also if the (new) source belongs to the Solar Sys tem:
souChanged = true; souChanged = true;
selName = tempName; selName = name;
currPlanet = dynamic_cast<Planet*>(selectedObject.da Planet* planet = dynamic_cast<Planet*>(selectedObjec
ta()); t.data());
isStar = (currPlanet)?false:true; isStar = (planet == NULL);
if (!isStar && !isMoon && !isSun) // Object in the Solar System, but is not Sun nor Moon. if (!isStar && !isMoon && !isSun) // Object in the Solar System, but is not Sun nor Moon.
{ {
int gene = -1; int gene = -1;
// If object is a planet's moon, we get its parent p lanet: // If object is a planet's moon, we get its parent p lanet:
Object = GETSTELMODULE(SolarSystem)->searchB ssObject = GETSTELMODULE(SolarSystem)->searc
yEnglishName(selName); hByEnglishName(selName);
// TODO: Isn't it easier just to use the pla
net object we just cast? --BM
parent = Object->getParent(); parentPlanet = ssObject->getParent();
if (parentPlanet)
if (parent)
{ {
while (parent) { while (parentPlanet)
gene += 1; {
parent = parent->getParent();} gene += 1;
}; parentPlanet = parentPlanet-
for (int g=0; g<gene;g++) { >getParent();
Object = Object->getParent(); }
}; }
for (int g=0; g<gene; g++)
{
ssObject = ssObject->getParent();
}
// Now get a pointer to the planet's instance: // Now get a pointer to the planet's instance:
myPlanet = Object.data(); myPlanet = ssObject.data();
}; }
}
};
} }
else { // There is no source selected! else // There is no source selected!
{
// If no source is selected, get the position vector of the screen center: // If no source is selected, get the position vector of the screen c
selName = ""; isStar=true; isMoon = false; isSun = false; is enter:
Screen=true; selName.clear();
isStar = true;
isMoon = false;
isSun = false;
isScreen = true;
Vec3d currentPos = GETSTELMODULE(StelMovementMgr)->getViewDi rectionJ2000(); Vec3d currentPos = GETSTELMODULE(StelMovementMgr)->getViewDi rectionJ2000();
currentPos.normalize(); currentPos.normalize();
EquPos = core->j2000ToEquinoxEqu(currentPos); EquPos = core->j2000ToEquinoxEqu(currentPos);
LocPos = core->j2000ToAltAz(currentPos,StelCore::RefractionO ff); LocPos = core->j2000ToAltAz(currentPos, StelCore::Refraction Off);
} }
// Convert EquPos to RA/Dec: // Convert EquPos to RA/Dec:
toRADec(EquPos,selRA,selDec); toRADec(EquPos, selRA, selDec);
// Compute source's altitude (in radians): // Compute source's altitude (in radians):
alti = std::asin(LocPos[2]); alti = std::asin(LocPos[2]);
// Force re-computation of ephemeris if the location changes or the user ch anges the configuration: // Force re-computation of ephemeris if the location changes or the user ch anges the configuration:
if (locChanged || configChanged) if (locChanged || configChanged)
{ {
souChanged=true; souChanged=true;
configChanged=false; configChanged=false;
}; };
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// NOW WE COMPUTE RISE/SET/TRANSIT TIMES FOR THE CURRENT DAY: // NOW WE COMPUTE RISE/SET/TRANSIT TIMES FOR THE CURRENT DAY:
double currH = HourAngle(mylat,alti,selDec); double currH = calculateHourAngle(mylat,alti,selDec);
horizH = HourAngle(mylat,RefracHoriz,selDec); horizH = calculateHourAngle(mylat,refractedHorizonAlt,selDec);
QString RS1, RS2, Cul; // strings with Rise/Set/Culmination times QString RS1, RS2, Cul; // strings with Rise/Set/Culmination times
double Rise, Set; // Actual Rise/Set times (in GMT). double risingTime = 0, settingTime = 0; // Actual Rise/Set times (in GMT).
int d1,m1,s1,d2,m2,s2,dc,mc,sc; // Integers for the time spans in hh :mm:ss. int d1,m1,s1,d2,m2,s2,dc,mc,sc; // Integers for the time spans in hh :mm:ss.
bool solvedMoon = false; // Check if solutions were found for Sun, M oon, or planet. bool solvedMoon = false; // Check if solutions were found for Sun, M oon, or planet.
bool transit = false; // Is the source above the horizon? Did it cul minate? bool transit = false; // Is the source above the horizon? Did it cul minate?
int ephHour, ephMinute, ephSecond; // Local time for selected ephem eris int ephHour, ephMinute, ephSecond; // Local time for selected ephem eris
if (show_Today) { // We show ephemeris for today (i.e., rise, set, if (show_Today)
and transit times). {
// Today's ephemeris (rise, set, and transit times)
if (!isStar) if (!isStar)
{ {
int Kind = (isSun)?1:0; // Set "Kind" according to int type = (isSun) ? 1:0;
the selected object. type += (isMoon) ? 2:0;
Kind += (isMoon)?2:0; Kind += (!isSun && !isMoon)?3: type += (!isSun && !isMoon) ? 3:0;
0;
solvedMoon = SolarSystemSolve(core, Kind); // False // Returns false if the calculation fails...
if fails; True otherwise. solvedMoon = calculateSolarSystemEvents(core, type);
currH = std::abs(24.*(MoonCulm-myJD)/TFrac); currH = std::abs(24.*(MoonCulm-myJD)/TFrac);
transit = MoonCulm-myJD<0.0; transit = MoonCulm-myJD<0.0;
if (solvedMoon) { // If failed, Set and Rise will b if (solvedMoon)
e dummy. { // If failed, Set and Rise will be dummy.
Set = std::abs(24.*(MoonSet-myJD)/TFrac); settingTime = std::abs(24.*(MoonSet-myJD)/TF
Rise = std::abs(24.*(MoonRise-myJD)/TFrac); rac);
}; risingTime = std::abs(24.*(MoonRise-myJD)/TF
} else if (horizH>0.0) { // The source is not circumpolar an rac);
d can be seen from this latitude.
if ( LocPos[1]>0.0 ) { // The source is at the east
ern side...
if ( currH>horizH ) { // ... and below the
horizon.
Set = 24.-currH-horizH;
Rise = currH-horizH;
raised = false;}
else { // ... and above the horizon.
Rise = horizH-currH;
Set = 2.*horizH-Rise;
raised = true;};
} }
else { // The source is at the western side... }
if ( currH>horizH ) { // ... and below the h else if (horizH>0.0)
orizon. { // The source is not circumpolar and can be seen from this
Set = currH-horizH; latitude.
Rise = 24.-currH-horizH;
raised = false;}
else { // ... and above the horizon.
Rise = horizH+currH;
Set = horizH-currH;
raised = true;};
};
}; if ( LocPos[1]>0.0 ) // The source is at the eastern
side...
{
if ( currH>horizH ) // ... and below the hor
izon.
{
settingTime = 24.-currH-horizH;
risingTime = currH-horizH;
hasRisen = false;
}
else // ... and above the horizon.
{
risingTime = horizH-currH;
settingTime = 2.*horizH-risingTime;
hasRisen = true;
}
}
else // The source is at the western side...
{
if ( currH>horizH ) // ... and below the hor
izon.
{
settingTime = currH-horizH;
risingTime = 24.-currH-horizH;
hasRisen = false;
}
else // ... and above the horizon.
{
risingTime = horizH+currH;
settingTime = horizH-currH;
hasRisen = true;
}
}
}
if ((solvedMoon && MoonRise>0.0) || (!isSun && !isMoon && ho rizH>0.0)) if ((solvedMoon && MoonRise>0.0) || (!isSun && !isMoon && ho rizH>0.0))
{ {
double2hms(TFrac*Set,d1,m1,s1); double2hms(TFrac*settingTime, d1, m1, s1);
double2hms(TFrac*Rise,d2,m2,s2); double2hms(TFrac*risingTime, d2, m2, s2);
// Strings with time spans for rise/set/transit: // Strings with time spans for rise/set
RS1 = (d1==0)?"":QString("%1%2 ").arg(d1).arg(msgH); /transit:
RS1 += (m1==0)?"":QString("%1%2 ").arg(m1).arg(msgM); RS1 += QString("%1%2 RS1 = (d1==0)?"":QString("%1%2 ").arg(d1).arg(msgH);
").arg(s1).arg(msgS); RS1 += (m1==0)?"":QString("%1%2 ").arg(m1).arg(msgM)
RS2 = (d2==0)?"":QString("%1%2 ").arg(d2).arg(msgH); ;
RS2 += (m2==0)?"":QString("%1%2 ").arg(m2).arg(msgM); RS2 += QString("%1%2 RS1 += QString("%1%2").arg(s1).arg(msgS);
").arg(s2).arg(msgS); RS2 = (d2==0)?"":QString("%1%2 ").arg(d2).arg(msgH);
if (raised) RS2 += (m2==0)?"":QString("%1%2 ").arg(m2).arg(msgM)
;
RS2 += QString("%1%2").arg(s2).arg(msgS);
if (hasRisen)
{ {
double2hms(toUnsignedRA(currLocalT+TFrac*Se double2hms(toUnsignedRA(currLocalT+TFrac*set
t+12.),ephHour,ephMinute,ephSecond); tingTime+12.),
SetTime = QString("%1:%2").arg(ephHour).arg( ephHour, ephMinute, ephSecond);
ephMinute,2,10,QLatin1Char('0')); // Local time for set. SetTime = QString("%1:%2").arg(ephHour).arg(
ephMinute,2,10,QChar('0')); // Local time for set.
double2hms(toUnsignedRA(currLocalT-TFrac*Ri double2hms(toUnsignedRA(currLocalT-TFrac*ris
se+12.),ephHour,ephMinute,ephSecond); // Local time for rise. ingTime+12.),
ephHour, ephMinute, ephSecond); /
/ Local time for rise.
RiseTime = QString("%1:%2").arg(ephHour).arg (ephMinute,2,10,QLatin1Char('0')); RiseTime = QString("%1:%2").arg(ephHour).arg (ephMinute,2,10,QLatin1Char('0'));
//RS1 = q_("Sets at %1 (in %2)").arg(SetTime ).arg(RS1); //RS1 = q_("Sets at %1 (in %2)").arg(SetTime ).arg(RS1);
//RS2 = q_("Rose at %1 (%2 ago)").arg(RiseTi me).arg(RS2); //RS2 = q_("Rose at %1 (%2 ago)").arg(RiseTi me).arg(RS2);
RS1 = msgSetsAt.arg(SetTime).arg(RS1); RS1 = msgSetsAt.arg(SetTime).arg(RS1);
RS2 = msgRoseAt.arg(RiseTime).arg(RS2); RS2 = msgRoseAt.arg(RiseTime).arg(RS2);
} }
else else
{ {
double2hms(toUnsignedRA(currLocalT-TFrac*Se double2hms(toUnsignedRA(currLocalT-TFrac*set
t+12.),ephHour,ephMinute,ephSecond); tingTime+12.),
ephHour, ephMinute, ephSecond);
SetTime = QString("%1:%2").arg(ephHour).arg( ephMinute,2,10,QLatin1Char('0')); SetTime = QString("%1:%2").arg(ephHour).arg( ephMinute,2,10,QLatin1Char('0'));
double2hms(toUnsignedRA(currLocalT+TFrac*Ri double2hms(toUnsignedRA(currLocalT+TFrac*ris
se+12.),ephHour,ephMinute,ephSecond); ingTime+12.),
ephHour, ephMinute, ephSecond);
RiseTime = QString("%1:%2").arg(ephHour).arg (ephMinute,2,10,QLatin1Char('0')); RiseTime = QString("%1:%2").arg(ephHour).arg (ephMinute,2,10,QLatin1Char('0'));
//RS1 = q_("Set at %1 (%2 ago)").arg(SetTime ).arg(RS1); //RS1 = q_("Set at %1 (%2 ago)").arg(SetTime ).arg(RS1);
//RS2 = q_("Rises at %1 (in %2)").arg(RiseTi me).arg(RS2); //RS2 = q_("Rises at %1 (in %2)").arg(RiseTi me).arg(RS2);
RS1 = msgSetAt.arg(SetTime).arg(RS1); RS1 = msgSetAt.arg(SetTime).arg(RS1);
RS2 = msgRisesAt.arg(RiseTime).arg(RS2); RS2 = msgRisesAt.arg(RiseTime).arg(RS2);
}; }
} }
else { // The source is either circumpolar or never rises: else // The source is either circumpolar or never rises:
(alti>RefracHoriz)? RS1 = msgCircumpolar: RS1 = msgN {
oRise; (alti>refractedHorizonAlt)? RS1 = msgCircumpolar: RS
1 = msgNoRise;
RS2 = ""; RS2 = "";
}; };
// Culmination: // Culmination:
if (isStar) if (isStar)
{
culmAlt = std::abs(mylat-selDec); // 90.-altitude at transit
.
transit = LocPos[1]<0.0;
};
if (culmAlt<halfpi-RefracHoriz) { // Source can be observed.
double altiAtCulmi = Rad2Deg*(halfpi-culmAlt-RefracHoriz);
double2hms(TFrac*currH,dc,mc,sc);
// String with the time span for culmination:
Cul = (dc==0)?"":QString("%1%2 ").arg(dc).arg(msgH); Cul +=
(mc==0)?"":QString("%1%2 ").arg(mc).arg(msgM); Cul += QString("%1%2").arg(s
c).arg(msgS);
if (transit==false) {
double2hms(toUnsignedRA(currLocalT+TFrac*currH+12.)
,ephHour,ephMinute,ephSecond); // Local time at transit.
CulmTime = QString("%1:%2").arg(ephHour).arg(ephMinu
te,2,10,QLatin1Char('0'));
//Cul = q_("Culminates at %1 (in %2) at %3 deg.").ar
g(CulmTime).arg(Cul).arg(altiAtCulmi,0,'f',1);
Cul = msgCulminatesAt.arg(CulmTime).arg(Cul).arg(alt
iAtCulmi,0,'f',1);
}
else
{ {
double2hms(toUnsignedRA(currLocalT-TFrac*currH+12.) culmAlt = std::abs(mylat-selDec); // 90.-altitude at
,ephHour,ephMinute,ephSecond); transit.
CulmTime = QString("%1:%2").arg(ephHour).arg(ephMinu transit = LocPos[1]<0.0;
te,2,10,QLatin1Char('0'));
//Cul = q_("Culminated at %1 (%2 ago) at %3 deg.").a
rg(CulmTime).arg(Cul).arg(altiAtCulmi,0,'f',1);
Cul = msgCulminatedAt.arg(CulmTime).arg(Cul).arg(alt
iAtCulmi,0,'f',1);
}; };
};
}; // This comes from show_Today==True if (culmAlt < (halfpi - refractedHorizonAlt)) // Source can
be observed.
{
double altiAtCulmi = Rad2Deg*(halfpi-culmAlt-refract
edHorizonAlt);
double2hms(TFrac*currH,dc,mc,sc);
//String with the time span for culmination:
Cul = (dc==0)?"":QString("%1%2 ").arg(dc).arg(msgH);
Cul += (mc==0)?"":QString("%1%2 ").arg(mc).arg(msgM)
;
Cul += QString("%1%2").arg(sc).arg(msgS);
if (!transit)
{
double2hms(toUnsignedRA(currLocalT + TFrac*c
urrH + 12.),
ephHour, ephMinute, ephSecond); /
/ Local time at transit.
CulmTime = QString("%1:%2").arg(ephHour).arg
(ephMinute,2,10,QLatin1Char('0'));
//Cul = q_("Culminates at %1 (in %2) at %3 d
eg.").arg(CulmTime).arg(Cul).arg(altiAtCulmi,0,'f',1);
Cul = msgCulminatesAt.arg(CulmTime).arg(Cul)
.arg(altiAtCulmi,0,'f',1);
}
else
{
double2hms(toUnsignedRA(currLocalT - TFrac*c
urrH + 12.),
ephHour, ephMinute, ephSecond);
CulmTime = QString("%1:%2").arg(ephHour).arg
(ephMinute,2,10,QLatin1Char('0'));
//Cul = q_("Culminated at %1 (%2 ago) at %3
deg.").arg(CulmTime).arg(Cul).arg(altiAtCulmi,0,'f',1);
Cul = msgCulminatedAt.arg(CulmTime).arg(Cul)
.arg(altiAtCulmi,0,'f',1);
}
}
} // This comes from show_Today==True
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// NOW WE ANALYZE THE SOURCE OBSERVABILITY FOR THE WHOLE YEAR: // NOW WE ANALYZE THE SOURCE OBSERVABILITY FOR THE WHOLE YEAR:
// Compute yearly ephemeris (only if necessary, and not for Sun nor Moon): // Compute yearly ephemeris (only if necessary, and not for Sun nor Moon):
if (isSun) if (isSun)
{ {
bestNight=""; ObsRange = ""; lineBestNight.clear();
lineObservableRange.clear();
} }
else if (!isMoon && show_Year) { else if (!isMoon && show_Year)
{
if (isStar==false && (souChanged || yearChanged)) { // Objec
t moves.
PlanetRADec(core);} // Re-compute ephemeris.
else { // Object is fixed on the sky. if (!isStar && (souChanged || yearChanged)) // Object moves.
double auxH = HourAngle(mylat,RefracHoriz,selDec); updatePlanetData(core); // Re-compute ephemeris.
else
{ // Object is fixed on the sky.
double auxH = calculateHourAngle(mylat,refractedHori
zonAlt,selDec);
double auxSidT1 = toUnsignedRA(selRA - auxH); double auxSidT1 = toUnsignedRA(selRA - auxH);
double auxSidT2 = toUnsignedRA(selRA + auxH); double auxSidT2 = toUnsignedRA(selRA + auxH);
for (int i=0;i<nDays;i++) { for (int i=0;i<nDays;i++) {
ObjectH0[i] = auxH; objectH0[i] = auxH;
ObjectRA[i] = selRA; objectRA[i] = selRA;
ObjectDec[i] = selDec; objectDec[i] = selDec;
ObjectSidT[0][i] = auxSidT1; objectSidT[0][i] = auxSidT1;
ObjectSidT[1][i] = auxSidT2; objectSidT[1][i] = auxSidT2;
}; };
}; };
// Determine source observability (only if something changed): // Determine source observability (only if something changed):
if ((souChanged || locChanged || yearChanged)) { if ((souChanged || locChanged || yearChanged))
bestNight=""; ObsRange = ""; {
lineBestNight.clear();
lineObservableRange.clear();
if (culmAlt>=halfpi-RefracHoriz) { // Source cannot // Check if the target cannot be seen.
be seen. if (culmAlt >= (halfpi - refractedHorizonAlt))
{
//ObsRange = q_("Source is not observable.") ; //ObsRange = q_("Source is not observable.") ;
//AcroCos = q_("No Acronychal nor Cosmical r ise/set."); //AcroCos = q_("No Acronychal nor Cosmical r ise/set.");
ObsRange = msgSrcNotObs; lineObservableRange = msgSrcNotObs;
AcroCos = msgNoACRise; lineAcroCos = msgNoACRise;
} }
else { // Source can be seen. else
{ // Source can be seen.
/////////////////////////// ///////////////////////////
// - Part 1. Determine the best observing night (i.e., opposition to the Su n): // - Part 1. Determine the best observing night (i.e., opposition to the Su n):
if (show_Best_Night) { if (show_Best_Night)
{
int selday = 0; int selday = 0;
double deltaPhs = -1.0; // Initial d ummy value double deltaPhs = -1.0; // Initial d ummy value
double tempPhs; double tempPhs;
for (int i=0;i<nDays;i++) { // Maxim for (int i=0; i<nDays; i++) // Maxim
ize the Sun-object separation. ize the Sun-object separation.
tempPhs = Lambda(ObjectRA[i] {
,ObjectDec[i],SunRA[i],SunDec[i]); tempPhs = Lambda(objectRA[i]
if (tempPhs>deltaPhs) {selda , objectDec[i],
y=i;deltaPhs=tempPhs;}; sunRA[i], s
}; unDec[i]);
if (tempPhs > deltaPhs)
{
selday = i;
deltaPhs = tempPhs;
}
}
if (selName=="Mercury" || selName==" Venus") if (selName=="Mercury" || selName==" Venus")
{ {
//bestNight = q_("Greatest e lineBestNight = msgGreatElon
longation: "); g;
bestNight = msgGreatElong; }
} else else
{ {
//bestNight = q_("Largest Su lineBestNight = msgLargSSep;
n separation: "); }
bestNight = msgLargSSep;
};
//bestNight = bestNight + CalenDate( lineBestNight = lineBestNight
selday) + q_(" (at %1 deg.)").arg(deltaPhs*Rad2Deg,0,'f',1); .arg(formatAsDate(se
bestNight = bestNight + CalenDate(se lday))
lday) + msgAtDeg.arg(deltaPhs*Rad2Deg,0,'f',1); .arg(deltaPhs*Rad2De
}; g, 0, 'f', 1);
}
/////////////////////////////// ///////////////////////////////
// - Part 2. Determine Acronychal and Cosmical rise and set: // - Part 2. Determine Acronychal and Cosmical rise and set:
if (show_AcroCos) { if (show_AcroCos)
int selRise, selSet, selRise2, selSe {
t2; // days of year for Acronical and Cosmical rise/set. int acroRise, acroSet, cosRise, cosS
int Acro = CheckAcro(selRise,selSet, et;
selRise2,selSet2); int result = calculateAcroCos(acroRi
QString AcroRiseStr, AcroSetStr; se, acroSet,
QString CosmRiseStr, CosmSetStr; cosRis
e, cosSet);
AcroRiseStr = (selRise>0)?CalenDate( QString acroRiseStr, acroSetStr;
selRise):msgNone; QString cosRiseStr, cosSetStr;
AcroSetStr = (selSet>0)?CalenDate(se // TODO: Possible error? Day 0 is 1
lSet):msgNone; Jan.
acroRiseStr = (acroRise>0)?formatAsD
CosmRiseStr = (selRise2>0)?CalenDate ate(acroRise):msgNone;
(selRise2):msgNone; acroSetStr = (acroSet>0)?formatAsDat
CosmSetStr = (selSet2>0)?CalenDate(s e(acroSet):msgNone;
elSet2):msgNone; cosRiseStr = (cosRise>0)?formatAsDat
e(cosRise):msgNone;
//AcroCos = (Acro==3 || Acro==1)?QSt cosSetStr = (cosSet>0)?formatAsDate(
ring("%1: %2/%3.").arg(q_("Acronychal rise/set")).arg(AcroRiseStr).arg(Acro cosSet):msgNone;
SetStr):q_("No Acronychal rise/set.");
//AcroCos += (Acro==3 || Acro==2)?QS if (result==3 || result==1)
tring(" %1: %2/%3.").arg(q_("Cosmical rise/set")).arg(CosmRiseStr).arg(Cosm lineAcroCos = msgAcroRise
SetStr):QString(" %1").arg(q_("No Cosmical rise/set.")); .arg(acroRise
AcroCos = (Acro==3 || Acro==1)?QStri Str)
ng("%1: %2/%3.").arg(msgAcroRise).arg(AcroRiseStr).arg(AcroSetStr):msgNoAcr .arg(acroSetS
oRise; tr);
AcroCos += (Acro==3 || Acro==2)?QStr else
ing(" %1: %2/%3.").arg(msgCosmRise).arg(CosmRiseStr).arg(CosmSetStr):QStrin lineAcroCos = msgNoAcroRise
g(" %1").arg(msgNoCosmRise); ;
}; if (result==3 || result==2)
lineAcroCos += msgCosmRise
.arg(cosRiseS
tr)
.arg(cosSetSt
r);
else
lineAcroCos += msgNoCosmRise
;
}
//////////////////////////// ////////////////////////////
// - Part 3. Determine range of good nights // - Part 3. Determine range of good nights
// (i.e., above horizon before/after twilight): // (i.e., above horizon before/after twilight):
if (show_Good_Nights) { if (show_Good_Nights)
{
int selday = 0; int selday = 0;
int selday2 = 0; int selday2 = 0;
bool bestBegun = false; // Are we in side a good time range? bool bestBegun = false; // Are we in side a good time range?
bool atLeastOne = false; bool atLeastOne = false;
QString dateRange = ""; QString dateRange;
bool PoleNight, twiGood; bool poleNight, twiGood;
for (int i=0; i<nDays; i++)
{
for (int i=0;i<nDays;i++) { poleNight = sunSidT[0][i]<0.
0 && std::abs(sunDec[i]-mylat)>=halfpi; // Is it night during 24h?
twiGood = (poleNight && std:
:abs(objectDec[i]-mylat)<halfpi)?true:CheckRise(i);
PoleNight = SunSidT[0][i]<0. if (twiGood && bestBegun ==
0 && std::abs(SunDec[i]-mylat)>=halfpi; // Is it night during 24h? false)
twiGood = (PoleNight && std: {
:abs(ObjectDec[i]-mylat)<halfpi)?true:CheckRise(i);
if (twiGood && bestBegun ==
false) {
selday = i; selday = i;
bestBegun = true; bestBegun = true;
atLeastOne = true; atLeastOne = true;
}; };
if (!twiGood && bestBegun == if (!twiGood && bestBegun ==
true) { true)
{
selday2 = i; selday2 = i;
bestBegun = false; bestBegun = false;
if (selday2 > selday if (selday2 > selday
) { )
if (dateRang {
e!="") { dateRange += ", ";}; // FIXME: Th
dateRange += is kind of concatenation is bad for i18n.
QString("%1").arg(RangeCalenDates(selday, selday2)); if (!dateRan
ge.isEmpty())
date
Range += ", ";
dateRange +=
QString("%1").arg(formatAsDateRange(selday, selday2));
}; };
}; };
}; };
if (bestBegun) { // There were good // Check if there were good dates ti
dates till the end of the year. ll the end of the year.
if (dateRange!="") { dateRa if (bestBegun)
nge += ", ";}; {
dateRange += RangeCalenDates // FIXME: This kind of conca
(selday, 0); tenation is bad for i18n.
if (!dateRange.isEmpty())
dateRange += ", ";
dateRange += formatAsDateRan
ge(selday, 0);
}; };
if (dateRange == "") if (dateRange.isEmpty())
{ {
if (atLeastOne) if (atLeastOne)
{ // The whole year is good. {
//ObsRange = q_("Obs ervable during the whole year."); //ObsRange = q_("Obs ervable during the whole year.");
ObsRange = msgWholeY ear; lineObservableRange = msgWholeYear;
} }
else else
{ {
//ObsRange = q_("Not observable at dark night."); //ObsRange = q_("Not observable at dark night.");
ObsRange = msgNotObs ; lineObservableRange = msgNotObs;
}; };
} }
else else
{ {
//ObsRange = QString("%1 %2" // Nights when the target is
).arg(q_("Nights above horizon: ")).arg(dateRange); above the horizon
ObsRange = QString("%1 %2"). lineObservableRange = msgAbo
arg(msgAboveHoriz).arg(dateRange); veHoriz.arg(dateRange);
}; };
}; // Comes from show_Good_Nights==True" }; // Comes from show_Good_Nights==True"
}; // Comes from the "else" of "culmAlt>=..." }; // Comes from the "else" of "culmAlt>=..."
};// Comes from "souChanged || ..." };// Comes from "souChanged || ..."
}; // Comes from the "else" with "!isMoon" }; // Comes from the "else" with "!isMoon"
// Print all results: // Print all results:
int spacing = (int) (1.3* ( (double) fontSize)); // between lines int lineSpacing = (int) (1.3* ( (double) fontSize)); // between lin
int spacing2 = 6*fontSize; // between daily and yearly results es
int groupSpacing = 6*fontSize; // between daily and yearly results
int yLine = 8*fontSize+110; int yLine = 8*fontSize+110;
int xLine = 80; int xLine = 80;
if (show_Today) if (show_Today)
{ {
//renderer->drawText(TextParams(xLine, yLine,q_("TODAY:"))); //renderer->drawText(TextParams(xLine, yLine,q_("TODAY:")));
renderer->drawText(TextParams(xLine, yLine,msgToday)); painter.drawText(xLine, yLine, msgToday);
renderer->drawText(TextParams(xLine+fontSize, yLine-spacing, painter.drawText(xLine + fontSize, yLine - lineSpacing, RS2)
RS2)); ;
renderer->drawText(TextParams(xLine+fontSize, yLine-spacing* painter.drawText(xLine + fontSize, yLine - lineSpacing*2, RS
2, RS1)); 1);
renderer->drawText(TextParams(xLine+fontSize, yLine-spacing* painter.drawText(xLine + fontSize, yLine - lineSpacing*3, Cu
3, Cul)); l);
yLine -= spacing2; yLine -= groupSpacing;
}; }
if ((isMoon && show_FullMoon) || (!isSun && !isMoon && show_Year)) if ((isMoon && show_FullMoon) || (!isSun && !isMoon && show_Year))
{ {
//renderer->drawText(TextParams(xLine,yLine,q_("THIS YEAR:") painter.drawText(xLine, yLine, msgThisYear);
));
renderer->drawText(TextParams(xLine,yLine,msgThisYear));
if (show_Best_Night || show_FullMoon) if (show_Best_Night || show_FullMoon)
{ {
yLine -= spacing; yLine -= lineSpacing;
renderer->drawText(TextParams(xLine+fontSize, yLine, painter.drawText(xLine + fontSize, yLine, lineBestNi
bestNight)); ght);
}; }
if (show_Good_Nights) if (show_Good_Nights)
{ {
yLine -= spacing; yLine -= lineSpacing;
renderer->drawText(TextParams(xLine+fontSize, yLine, painter.drawText(xLine + fontSize, yLine, lineObserv
ObsRange)); ableRange);
}; }
if (show_AcroCos) if (show_AcroCos)
{ {
yLine -= spacing; yLine -= lineSpacing;
renderer->drawText(TextParams(xLine+fontSize, yLine, painter.drawText(xLine + fontSize, yLine, lineAcroCo
AcroCos)); s);
}; }
}
};
} }
// END OF MAIN CODE // END OF MAIN CODE
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
////////////////////////////// //////////////////////////////
// AUXILIARY FUNCTIONS // AUXILIARY FUNCTIONS
//////////////////////////////////// ////////////////////////////////////
// Returns the hour angle for a given altitude: // Returns the hour angle for a given altitude:
double Observability::HourAngle(double lat, double h, double Dec) double Observability::calculateHourAngle(double latitude,
double elevation,
double declination)
{ {
double Denom = std::cos(lat)*std::cos(Dec); double denom = std::cos(latitude)*std::cos(declination);
double Numer = (std::sin(h)-std::sin(lat)*std::sin(Dec)); double numer = (std::sin(elevation)-std::sin(latitude)*std::sin(decl
ination));
if ( std::abs(Numer)>std::abs(Denom) ) if ( std::abs(numer) > std::abs(denom) )
{return -0.5/86400.;} // Source doesn't reach that altitude. {
return -0.5/86400.; // Source doesn't reach that altitude.
}
else else
{return Rad2Hr*std::acos(Numer/Denom);} {
return Rad2Hr * std::acos(numer/denom);
}
} }
//////////////////////////////////// ////////////////////////////////////
//////////////////////////////////// ////////////////////////////////////
// Returns the angular separation between two points on the Sky: // Returns the angular separation between two points on the Sky:
// RA is given in hours and Dec in radians. // RA is given in hours and Dec in radians.
double Observability::Lambda(double RA1, double Dec1, double RA2, double De c2) double Observability::Lambda(double RA1, double Dec1, double RA2, double De c2)
{ {
return std::acos(std::sin(Dec1)*std::sin(Dec2)+std::cos(Dec1)*std::c os(Dec2)*std::cos((RA1-RA2)/Rad2Hr)); return std::acos(std::sin(Dec1)*std::sin(Dec2)+std::cos(Dec1)*std::c os(Dec2)*std::cos((RA1-RA2)/Rad2Hr));
} }
//////////////////////////////////// ////////////////////////////////////
//////////////////////////////////// ////////////////////////////////////
// Returns the hour angle for a given a Sid. Time: // Returns the hour angle for a given a Sid. Time:
double Observability::HourAngle2(double RA, double ST) double Observability::HourAngle2(double RA, double ST)
{ {
double Htemp = toUnsignedRA(RA-ST/15.); double result = toUnsignedRA(RA-ST/15.);
Htemp -= (Htemp>12.)?24.0:0.0; result -= (result > 12.) ? 24.0 : 0.0;
return Htemp; return result;
} }
//////////////////////////////////// ////////////////////////////////////
//////////////////////////////////// ////////////////////////////////////
// Converts a float time/angle span (in hours/degrees) in the (integer) for mat hh/dd,mm,ss: // Converts a float time/angle span (in hours/degrees) in the (integer) for mat hh/dd,mm,ss:
void Observability::double2hms(double hfloat, int &h1, int &h2, int &h3) void Observability::double2hms(double hfloat, int &h1, int &h2, int &h3)
{ {
double f1,f2,f3; double f1,f2,f3;
hfloat = std::abs(hfloat); hfloat = std::abs(hfloat);
skipping to change at line 842 skipping to change at line 903
{ {
double tempRA,tempmod; double tempRA,tempmod;
//FIXME: tempmod is unused variable; need fix //FIXME: tempmod is unused variable; need fix
if (RA<0.0) {tempmod = std::modf(-RA/24.,&tempRA); RA += 24.*(tempRA +1.0)+0.0*tempmod;}; if (RA<0.0) {tempmod = std::modf(-RA/24.,&tempRA); RA += 24.*(tempRA +1.0)+0.0*tempmod;};
double auxRA = 24.*std::modf(RA/24.,&tempRA); double auxRA = 24.*std::modf(RA/24.,&tempRA);
auxRA += (auxRA<0.0)?24.0:((auxRA>24.0)?-24.0:0.0); auxRA += (auxRA<0.0)?24.0:((auxRA>24.0)?-24.0:0.0);
return auxRA; return auxRA;
} }
//////////////////////////////////// ////////////////////////////////////
/////////////////////////////////////////////// QString Observability::formatAsDate(int dayNumber)
// Returns the day and month of year (to put it in format '25 Apr')
QString Observability::CalenDate(int selday)
{ {
int day,month,year; int day, month, year;
StelUtils::getDateFromJulianDay(yearJD[selday],&year,&month,&day); StelUtils::getDateFromJulianDay(yearJD[dayNumber], &year, &month, &d
ay);
QString r; QString formatString = (getDateFormat()) ? "%1 %2" : "%2 %1";
if (getDateFormat()) QString result = formatString.arg(day).arg(monthNames[month-1]);
r = QString("%1 %2").arg(day).arg(months[month-1]); return result;
else
r = QString("%1 %2").arg(months[month-1]).arg(day);
return r;
} }
//////////////////////////////////////////////
/////////////////////////////////////////////// ///////////////////////////////////////////////
// Returns the day and month of year (to put it in format '25 Apr') // Returns the day and month of year (to put it in format '25 Apr')
QString Observability::RangeCalenDates(int fDoY, int sDoY) QString Observability::formatAsDateRange(int startDay, int endDay)
{ {
int day1,month1,year1,day2,month2,year2; int sDay, sMonth, sYear, eDay, eMonth, eYear;
QString range; QString range;
StelUtils::getDateFromJulianDay(yearJD[fDoY],&year1,&month1,&day1); StelUtils::getDateFromJulianDay(yearJD[startDay], &sYear, &sMonth, &
StelUtils::getDateFromJulianDay(yearJD[sDoY],&year2,&month2,&day2); sDay);
if (sDoY==0) StelUtils::getDateFromJulianDay(yearJD[endDay], &eYear, &eMonth, &eD
ay);
if (endDay == 0)
{ {
day2 = 31; eDay = 31;
month2 = 12; eMonth = 12;
} }
if (fDoY==0) if (startDay == 0)
{ {
day1 = 1; sDay = 1;
month1 = 1; sMonth = 1;
} }
if (month1==month2)
// If it's the same month, display "X-Y Month" or "Month X-Y"
if (sMonth == eMonth)
{ {
if (getDateFormat()) QString formatString = (getDateFormat()) ? "%1 - %2 %3" : "%
range = QString("%1 - %2 %3").arg(day1).arg(day2).ar 3 %1 - %2";
g(months[month1-1]); range = formatString.arg(sDay).arg(eDay).arg(monthNames[sMon
else th-1]);;
range = QString("%3 %1 - %2").arg(day1).arg(day2).ar
g(months[month1-1]);
} }
else else
{ {
if (getDateFormat()) QString formatString = (getDateFormat()) ? "%1 %2 - %3 %4"
range = QString("%1 %2 - %3 %4").arg(day1).arg(month : "%2 %1 - %4 %3";
s[month1-1]).arg(day2).arg(months[month2-1]); range = formatString.arg(sDay)
else .arg(monthNames[sMonth-1])
range = QString("%1 %2 - %3 %4").arg(months[month1-1 .arg(eDay)
]).arg(day1).arg(months[month2-1]).arg(day2); .arg(monthNames[eMonth-1]);
} }
return range; return range;
} }
////////////////////////////////////////////// //////////////////////////////////////////////
//////////////////////////////////////////////////
// Returns the RA and Dec of the selected planet
//for each day of the current year:
void Observability::PlanetRADec(StelCore *core)
{
double TempH;
// Compute planet's position for each day of the current year: // Compute planet's position for each day of the current year:
void Observability::updatePlanetData(StelCore *core)
for (int i=0;i<nDays;i++) { {
getPlanetCoords(core,yearJD[i],ObjectRA[i],ObjectDec[i],fals double tempH;
e); for (int i=0; i<nDays; i++)
TempH = HourAngle(mylat,RefracHoriz,ObjectDec[i]); {
ObjectH0[i] = TempH; getPlanetCoords(core, yearJD[i], objectRA[i], objectDec[i],
ObjectSidT[0][i] = toUnsignedRA(ObjectRA[i]-TempH); false);
ObjectSidT[1][i] = toUnsignedRA(ObjectRA[i]+TempH); tempH = calculateHourAngle(mylat, refractedHorizonAlt, objec
tDec[i]);
objectH0[i] = tempH;
objectSidT[0][i] = toUnsignedRA(objectRA[i]-tempH);
objectSidT[1][i] = toUnsignedRA(objectRA[i]+tempH);
} }
// Return the planet to its current time: // Return the planet to its current time:
getPlanetCoords(core,myJD,ObjectRA[0],ObjectDec[0],true); getPlanetCoords(core, myJD, objectRA[0], objectDec[0], true);
} }
///////////////////////////////////////////////// /////////////////////////////////////////////////
// Computes the Sun's RA and Dec (and the JD) for // Computes the Sun's RA and Dec (and the JD) for
// each day of the current year. // each day of the current year.
void Observability::SunRADec(StelCore* core) void Observability::updateSunData(StelCore* core)
{ {
int day,month,year,year2; int day, month, year, sameYear;
// Get current date: // Get current date:
StelUtils::getDateFromJulianDay(myJD,&year,&month,&day); StelUtils::getDateFromJulianDay(myJD,&year,&month,&day);
// Get JD for the Jan 1 of current year: // Get JD for the Jan 1 of current year:
StelUtils::getJDFromDate(&Jan1stJD,year,1,1,0,0,0); StelUtils::getJDFromDate(&Jan1stJD,year,1,1,0,0,0);
// Check if we are on a leap year: // Check if we are on a leap year:
StelUtils::getDateFromJulianDay(Jan1stJD+365.,&year2,&month,&day); StelUtils::getDateFromJulianDay(Jan1stJD+365., &sameYear, &month, &d
nDays = (year==year2)?366:365; ay);
nDays = (year==sameYear)?366:365;
// Compute Earth's position throughout the year: // Compute Earth's position throughout the year:
for (int i=0;i<nDays;i++) { Vec3d pos, sunPos;
yearJD[i] = Jan1stJD+(double)i; for (int i=0; i<nDays; i++)
{
yearJD[i] = Jan1stJD + (double)i;
myEarth->computePosition(yearJD[i]); myEarth->computePosition(yearJD[i]);
myEarth->computeTransMatrix(yearJD[i]); myEarth->computeTransMatrix(yearJD[i]);
Pos1 = myEarth->getHeliocentricEclipticPos(); pos = myEarth->getHeliocentricEclipticPos();
Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Po sunPos = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-
s1)); pos));
EarthPos[i] = -Pos1; EarthPos[i] = -pos;
toRADec(Pos2,SunRA[i],SunDec[i]); toRADec(sunPos,sunRA[i],sunDec[i]);
}; };
//Return the Earth to its current time: //Return the Earth to its current time:
myEarth->computePosition(myJD); myEarth->computePosition(myJD);
myEarth->computeTransMatrix(myJD); myEarth->computeTransMatrix(myJD);
} }
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
//////////////////////////////////////////// ////////////////////////////////////////////
// Computes Sun's Sidereal Times at twilight and culmination: // Computes Sun's Sidereal Times at twilight and culmination:
void Observability::SunHTwi() void Observability::updateSunH()
{ {
double TempH, TempH00; double tempH, tempH00;
for (int i=0; i<nDays; i++) { for (int i=0; i<nDays; i++)
TempH = HourAngle(mylat,AstroTwiAlti,SunDec[i]); {
TempH00 = HourAngle(mylat,RefracHoriz,SunDec[i]); tempH = calculateHourAngle(mylat, twilightAltRad, sunDec[i])
if (TempH>0.0) { ;
SunSidT[0][i] = toUnsignedRA(SunRA[i]-TempH*(1.00278 tempH00 = calculateHourAngle(mylat, refractedHorizonAlt, sun
)); Dec[i]);
SunSidT[1][i] = toUnsignedRA(SunRA[i]+TempH*(1.00278 if (tempH > 0.0)
));} {
else { sunSidT[0][i] = toUnsignedRA(sunRA[i]-tempH*(1.00278
SunSidT[0][i] = -1000.0; ));
SunSidT[1][i] = -1000.0;}; sunSidT[1][i] = toUnsignedRA(sunRA[i]+tempH*(1.00278
if (TempH00>0.0) { ));
SunSidT[2][i] = toUnsignedRA(SunRA[i]+TempH00); }
SunSidT[3][i] = toUnsignedRA(SunRA[i]-TempH00);} else
else { {
SunSidT[2][i] = -1000.0; sunSidT[0][i] = -1000.0;
SunSidT[3][i] = -1000.0;}; sunSidT[1][i] = -1000.0;
}
}; if (tempH00>0.0)
{
sunSidT[2][i] = toUnsignedRA(sunRA[i]+tempH00);
sunSidT[3][i] = toUnsignedRA(sunRA[i]-tempH00);
}
else
{
sunSidT[2][i] = -1000.0;
sunSidT[3][i] = -1000.0;
}
}
} }
//////////////////////////////////////////// ////////////////////////////////////////////
/////////////////////////////////////////// ///////////////////////////////////////////
// Checks if a source can be observed with the Sun below the twilight altit ude. // Checks if a source can be observed with the Sun below the twilight altit ude.
bool Observability::CheckRise(int i) bool Observability::CheckRise(int day)
{ {
// If Sun can't reach twilight elevation, return false: // If Sun can't reach twilight elevation, the target is not visible.
if (SunSidT[0][i]<0.0 || SunSidT[1][i]<0.0) { return false;}; if (sunSidT[0][day]<0.0 || sunSidT[1][day]<0.0)
return false;
// Iterate over the whole year: // Iterate over the whole year:
int nBin = 1000; int nBin = 1000;
double auxSid1 = SunSidT[0][i]; double auxSid1 = sunSidT[0][day];
auxSid1 += (SunSidT[0][i] < SunSidT[1][i])?24.0:0.0; auxSid1 += (sunSidT[0][day] < sunSidT[1][day]) ? 24.0 : 0.0;
double deltaT = (auxSid1-SunSidT[1][i])/((double)nBin); double deltaT = (auxSid1-sunSidT[1][day]) / ((double)nBin);
double Hour; double hour;
for (int j=0;j<nBin;j++) { for (int j=0; j<nBin; j++)
Hour = toUnsignedRA(SunSidT[1][i]+deltaT*(double)j - ObjectR {
A[i]); hour = toUnsignedRA(sunSidT[1][day]+deltaT*(double)j - objec
Hour -= (Hour>12.)?24.0:0.0; tRA[day]);
if (std::abs(Hour)<ObjectH0[i] || (ObjectH0[i] < 0.0 && alti hour -= (hour>12.) ? 24.0 : 0.0;
>0.0)) {return true;}; if (std::abs(hour)<objectH0[day] || (objectH0[day] < 0.0 &&
}; alti>0.0))
return true;
}
return false; return false;
} }
/////////////////////////////////////////// ///////////////////////////////////////////
/////////////////////////////////////////// ///////////////////////////////////////////
// Finds the dates of Acronichal (Rise, Set) and Cosmical (Rise2, Set2) dat es. // Finds the dates of Acronichal (Rise, Set) and Cosmical (Rise2, Set2) dat es.
// Returns 0 if no dates found, 1 if Acro exists, 2 if Cosm exists, and 3 i int Observability::calculateAcroCos(int &acroRise, int &acroSet,
f both are found. int &cosRise, int &cosSet)
int Observability::CheckAcro(int &Rise, int &Set, int &Rise2, int &Set2)
{ {
acroRise = -1;
acroSet = -1;
cosRise = -1;
cosSet = -1;
double bestDiffAcroRise = 12.0;
double bestDiffAcroSet = 12.0;
double bestDiffCosRise = 12.0;
double bestDiffCosSet = 12.0;
Rise = -1; double hourDiffAcroRise, hourDiffAcroSet, hourDiffCosRise, hourCosDi
Set = -1; ffSet;
Rise2 = -1;
Set2 = -1;
double BestDiffRise = 12.0;
double BestDiffSet = 12.0;
double BestDiffRise2 = 12.0;
double BestDiffSet2 = 12.0;
double HourDiffRise, HourDiffSet, HourDiffRise2, HourDiffSet2;
bool success = false; bool success = false;
for (int i=0;i<366;i++) for (int i=0; i<366; i++)
{ {
if (ObjectH0[i]>0.0 && SunSidT[2][i]>0.0 && SunSidT[3][i]>0. if (objectH0[i]>0.0 && sunSidT[2][i]>0.0 && sunSidT[3][i]>0.
0) { 0)
{
success = true; success = true;
HourDiffRise = toUnsignedRA(ObjectRA[i] - ObjectH0[i hourDiffAcroRise = toUnsignedRA(objectRA[i] - object
]); H0[i]);
HourDiffRise2 = HourDiffRise-SunSidT[3][i]; hourDiffCosRise = hourDiffAcroRise-sunSidT[3][i];
HourDiffRise -= SunSidT[2][i]; hourDiffAcroRise -= sunSidT[2][i];
HourDiffSet = toUnsignedRA(ObjectRA[i] + ObjectH0[i] hourDiffAcroSet = toUnsignedRA(objectRA[i] + objectH
); 0[i]);
HourDiffSet2 = HourDiffSet - SunSidT[2][i]; hourCosDiffSet = hourDiffAcroSet - sunSidT[2][i];
HourDiffSet -= SunSidT[3][i]; hourDiffAcroSet -= sunSidT[3][i];
// Acronychal Rise/Set: // Acronychal rise/set:
if (std::abs(HourDiffRise)<BestDiffRise) if (std::abs(hourDiffAcroRise) < bestDiffAcroRise)
{ {
BestDiffRise = std::abs(HourDiffRise); bestDiffAcroRise = std::abs(hourDiffAcroRise
Rise = i; );
acroRise = i;
}; };
if (std::abs(HourDiffSet)<BestDiffSet) if (std::abs(hourDiffAcroSet) < bestDiffAcroSet)
{ {
BestDiffSet = std::abs(HourDiffSet); bestDiffAcroSet = std::abs(hourDiffAcroSet);
Set = i; acroSet = i;
}; };
// Cosmical Rise/Set: // Cosmical Rise/Set:
if (std::abs(HourDiffRise2)<BestDiffRise2) if (std::abs(hourDiffCosRise) < bestDiffCosRise)
{ {
BestDiffRise2 = std::abs(HourDiffRise2); bestDiffCosRise = std::abs(hourDiffCosRise);
Rise2 = i; cosRise = i;
}; };
if (std::abs(HourDiffSet2)<BestDiffSet2) if (std::abs(hourCosDiffSet) < bestDiffCosSet)
{ {
BestDiffSet2 = std::abs(HourDiffSet2); bestDiffCosSet = std::abs(hourCosDiffSet);
Set2 = i; cosSet = i;
}; };
}; };
}; };
Rise *= (BestDiffRise > 0.083)?-1:1; // Check that difference is low acroRise *= (bestDiffAcroRise > 0.083)?-1:1; // Check that differenc
er than 5 minutes. e is lower than 5 minutes.
Set *= (BestDiffSet > 0.083)?-1:1; // Check that difference is lower acroSet *= (bestDiffAcroSet > 0.083)?-1:1; // Check that difference
than 5 minutes. is lower than 5 minutes.
Rise2 *= (BestDiffRise2 > 0.083)?-1:1; // Check that difference is l cosRise *= (bestDiffCosRise > 0.083)?-1:1; // Check that difference
ower than 5 minutes. is lower than 5 minutes.
Set2 *= (BestDiffSet2 > 0.083)?-1:1; // Check that difference is low cosSet *= (bestDiffCosSet > 0.083)?-1:1; // Check that difference is
er than 5 minutes. lower than 5 minutes.
int Result = (Rise>0 || Set>0)?1:0; int result = (acroRise>0 || acroSet>0) ? 1 : 0;
Result += (Rise2>0 || Set2>0)?2:0; result += (cosRise>0 || cosSet>0) ? 2 : 0;
return (success)?Result:0; return (success) ? result : 0;
} }
/////////////////////////////////////////// ///////////////////////////////////////////
//////////////////////////////////////////// ////////////////////////////////////////////
// Convert an Equatorial Vec3d into RA and Dec: // Convert an Equatorial Vec3d into RA and Dec:
void Observability::toRADec(Vec3d TempLoc, double &RA, double &Dec) void Observability::toRADec(Vec3d vec3d, double& ra, double &dec)
{ {
TempLoc.normalize(); vec3d.normalize();
Dec = std::asin(TempLoc[2]); // in radians dec = std::asin(vec3d[2]); // in radians
RA = toUnsignedRA(std::atan2(TempLoc[1],TempLoc[0])*Rad2Hr); // in h ra = toUnsignedRA(std::atan2(vec3d[1],vec3d[0])*Rad2Hr); // in hours
ours. .
} }
//////////////////////////////////////////// ////////////////////////////////////////////
/////////////////////////// ///////////////////////////
// Just return the sign of a double // Just return the sign of a double
double Observability::sign(double d) double Observability::sign(double d)
{ {
return (d<0.0)?-1.0:1.0; return (d<0.0)?-1.0:1.0;
} }
////////////////////////// //////////////////////////
////////////////////////// //////////////////////////
// Get the coordinates of Sun or Moon for a given JD: // Get the coordinates of Sun or Moon for a given JD:
// getBack controls whether Earth and Moon must be returned to their origin al positions after computation. // getBack controls whether Earth and Moon must be returned to their origin al positions after computation.
void Observability::getSunMoonCoords(StelCore *core, double JD, double &RAS void Observability::getSunMoonCoords(StelCore *core, double jd,
un, double &DecSun, double &RAMoon, double &DecMoon, double &EclLon, bool g double &raSun, double &decSun,
etBack) //, Vec3d &AltAzVector) double &raMoon, double &decMoon,
double &eclLon, bool getBack)
//, Vec3d &AltAzVector)
{ {
if (getBack) // Return the Moon and Earth to their current position: if (getBack) // Return the Moon and Earth to their current position:
{ {
myEarth->computePosition(JD); myEarth->computePosition(jd);
myEarth->computeTransMatrix(JD); myEarth->computeTransMatrix(jd);
myMoon->computePosition(JD); myMoon->computePosition(jd);
myMoon->computeTransMatrix(JD); myMoon->computeTransMatrix(jd);
} }
else else // Compute coordinates:
{ // Compute coordinates: {
myEarth->computePosition(JD); myEarth->computePosition(jd);
myEarth->computeTransMatrix(JD); myEarth->computeTransMatrix(jd);
Pos0 = myEarth->getHeliocentricEclipticPos(); Vec3d earthPos = myEarth->getHeliocentricEclipticPos();
double currSidT; double curSidT;
// Sun coordinates: // Sun coordinates:
Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Po Vec3d sunPos = core->j2000ToEquinoxEqu((core->matVsop87ToJ20
s0)); 00)*(-earthPos));
toRADec(Pos2,RASun,DecSun); toRADec(sunPos, raSun, decSun);
// Moon coordinates: // Moon coordinates:
currSidT = myEarth->getSiderealTime(JD)/Rad2Deg; curSidT = myEarth->getSiderealTime(jd)/Rad2Deg;
RotObserver = (Mat4d::zrotation(currSidT))*ObserverLoc; RotObserver = (Mat4d::zrotation(curSidT))*ObserverLoc;
LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-ear
0)); thPos));
myMoon->computePosition(JD); myMoon->computePosition(jd);
myMoon->computeTransMatrix(JD); myMoon->computeTransMatrix(jd);
Pos1 = myMoon->getHeliocentricEclipticPos(); Vec3d moonPos = myMoon->getHeliocentricEclipticPos();
Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1))-RotObserver; sunPos = (core->j2000ToEquinoxEqu(LocTrans*moonPos))-RotObse
rver;
EclLon = Pos1[0]*Pos0[1] - Pos1[1]*Pos0[0]; eclLon = moonPos[0]*earthPos[1] - moonPos[1]*earthPos[0];
toRADec(Pos2,RAMoon,DecMoon); toRADec(sunPos,raMoon,decMoon);
}; };
} }
////////////////////////////////////////////// //////////////////////////////////////////////
////////////////////////// //////////////////////////
// Get the Observer-to-Moon distance JD: // Get the Observer-to-Moon distance JD:
// getBack controls whether Earth and Moon must be returned to their origin al positions after computation. // getBack controls whether Earth and Moon must be returned to their origin al positions after computation.
void Observability::getMoonDistance(StelCore *core, double JD, double &Dist ance, bool getBack) void Observability::getMoonDistance(StelCore *core, double jd, double &dist ance, bool getBack)
{ {
if (getBack) // Return the Moon and Earth to their current position: if (getBack) // Return the Moon and Earth to their current position:
{ {
myEarth->computePosition(JD); myEarth->computePosition(jd);
myEarth->computeTransMatrix(JD); myEarth->computeTransMatrix(jd);
myMoon->computePosition(JD); myMoon->computePosition(jd);
myMoon->computeTransMatrix(JD); myMoon->computeTransMatrix(jd);
} }
else else
{ // Compute coordinates: { // Compute coordinates:
myEarth->computePosition(JD); myEarth->computePosition(jd);
myEarth->computeTransMatrix(JD); myEarth->computeTransMatrix(jd);
Pos0 = myEarth->getHeliocentricEclipticPos(); Vec3d earthPos = myEarth->getHeliocentricEclipticPos();
// double currSidT; // double curSidT;
// Sun coordinates: // Sun coordinates:
// Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Po s0)); // Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Po s0));
// toRADec(Pos2,RASun,DecSun); // toRADec(Pos2,RASun,DecSun);
// Moon coordinates: // Moon coordinates:
// currSidT = myEarth->getSiderealTime(JD)/Rad2Deg; // curSidT = myEarth->getSiderealTime(JD)/Rad2Deg;
// RotObserver = (Mat4d::zrotation(currSidT))*ObserverLoc; // RotObserver = (Mat4d::zrotation(curSidT))*ObserverLoc;
LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-ear
0)); thPos));
myMoon->computePosition(JD); myMoon->computePosition(jd);
myMoon->computeTransMatrix(JD); myMoon->computeTransMatrix(jd);
Pos1 = myMoon->getHeliocentricEclipticPos(); Pos1 = myMoon->getHeliocentricEclipticPos();
Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1)); //-RotObser ver; Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1)); //-RotObser ver;
Distance = std::sqrt(Pos2*Pos2); distance = std::sqrt(Pos2*Pos2);
// toRADec(Pos2,RAMoon,DecMoon); // toRADec(Pos2,RAMoon,DecMoon);
}; };
} }
////////////////////////////////////////////// //////////////////////////////////////////////
////////////////////////////////////////////// //////////////////////////////////////////////
// Get the Coords of a planet: // Get the Coords of a planet:
void Observability::getPlanetCoords(StelCore *core, double JD, double &RA, double &Dec, bool getBack) void Observability::getPlanetCoords(StelCore *core, double JD, double &RA, double &Dec, bool getBack)
{ {
skipping to change at line 1199 skipping to change at line 1266
Pos2 = myEarth->getHeliocentricEclipticPos(); Pos2 = myEarth->getHeliocentricEclipticPos();
LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos 2)); LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos 2));
Pos2 = core->j2000ToEquinoxEqu(LocTrans*Pos1); Pos2 = core->j2000ToEquinoxEqu(LocTrans*Pos1);
toRADec(Pos2,RA,Dec); toRADec(Pos2,RA,Dec);
}; };
} }
////////////////////////////////////////////// //////////////////////////////////////////////
////////////////////////////////////////////// //////////////////////////////////////////////
// Solves Moon's, Sun's, or Planet's ephemeris by bissection. Returns JD: // Solves Moon's, Sun's, or Planet's ephemeris by bissection.
bool Observability::SolarSystemSolve(StelCore* core, int Kind) bool Observability::calculateSolarSystemEvents(StelCore* core, int bodyType
)
{ {
int Niter = 100; const int NUM_ITER = 100;
int i; int i;
double Hhoriz, RA, Dec, RAS, DecS, TempH, jd1, tempEphH, currSidT, E double hHoriz, ra, dec, raSun, decSun, tempH, tempJd, tempEphH, curS
clLon; idT, eclLon;
Vec3d Observer; //Vec3d Observer;
Hhoriz = HourAngle(mylat,RefracHoriz,selDec); hHoriz = calculateHourAngle(mylat, refractedHorizonAlt, selDec);
bool raises = Hhoriz > 0.0; bool raises = hHoriz > 0.0;
// Only recompute ephemeris from second to second (at least) // Only recompute ephemeris from second to second (at least)
// or if the source has changed (i.e., Sun <-> Moon). This saves resources: // or if the source has changed (i.e., Sun <-> Moon). This saves resources:
if (std::abs(myJD-lastJDMoon)>JDsec || LastObject!=Kind || souChange d) if (std::abs(myJD-lastJDMoon)>JDsec || lastType!=bodyType || souChan ged)
{ {
// qDebug() << q_("%1 %2 %3 %4").arg(Kind).arg(LastObject) .arg(myJD,0,'f',5).arg(lastJDMoon,0,'f',5); // qDebug() << q_("%1 %2 %3 %4").arg(Kind).arg(LastObject) .arg(myJD,0,'f',5).arg(lastJDMoon,0,'f',5);
LastObject = Kind; lastType = bodyType;
myEarth->computePosition(myJD); myEarth->computePosition(myJD);
myEarth->computeTransMatrix(myJD); myEarth->computeTransMatrix(myJD);
Pos0 = myEarth->getHeliocentricEclipticPos(); Vec3d earthPos = myEarth->getHeliocentricEclipticPos();
if (Kind==1) if (bodyType == 1) // Sun position
{ // Sun position: {
Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ20 Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ20
00)*(-Pos0)); 00)*(-earthPos));
} else if (Kind==2) }
{ // Moon position: else if (bodyType==2) // Moon position
currSidT = myEarth->getSiderealTime(myJD)/Rad2Deg; {
RotObserver = (Mat4d::zrotation(currSidT))*ObserverL curSidT = myEarth->getSiderealTime(myJD)/Rad2Deg;
oc; RotObserver = (Mat4d::zrotation(curSidT))*ObserverLo
LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translat c;
ion(-Pos0)); LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translat
ion(-earthPos));
myMoon->computePosition(myJD); myMoon->computePosition(myJD);
myMoon->computeTransMatrix(myJD); myMoon->computeTransMatrix(myJD);
Pos1 = myMoon->getHeliocentricEclipticPos(); Pos1 = myMoon->getHeliocentricEclipticPos();
Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1))-RotO bserver; Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1))-RotO bserver;
} else }
{ // Planet position: else // Planet position
myPlanet->computePosition(myJD); {
myPlanet->computeTransMatrix(myJD); myPlanet->computePosition(myJD);
Pos1 = myPlanet->getHeliocentricEclipticPos( myPlanet->computeTransMatrix(myJD);
); Pos1 = myPlanet->getHeliocentricEclipticPos();
LocTrans = (core->matVsop87ToJ2000)*(Mat4d:: LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translat
translation(-Pos0)); ion(-earthPos));
Pos2 = core->j2000ToEquinoxEqu(LocTrans*Pos1); Pos2 = core->j2000ToEquinoxEqu(LocTrans*Pos1);
}; };
toRADec(Pos2,RA,Dec); toRADec(Pos2,ra,dec);
Vec3d MoonAltAz = core->equinoxEquToAltAz(Pos2,StelCore::Ref Vec3d moonAltAz = core->equinoxEquToAltAz(Pos2, StelCore::Re
ractionOff); fractionOff);
raised = MoonAltAz[2] > RefracHoriz; hasRisen = moonAltAz[2] > refractedHorizonAlt;
// Initial guesses of rise/set/transit times. // Initial guesses of rise/set/transit times.
// They are called 'Moon', but are also used for the Sun or planet: // They are called 'Moon', but are also used for the Sun or planet:
double Hcurr = -HourAngle(mylat,alti,selDec)*sign(LocPos[1]) ; double Hcurr = -calculateHourAngle(mylat,alti,selDec)*sign(L ocPos[1]);
double SidT = toUnsignedRA(selRA + Hcurr); double SidT = toUnsignedRA(selRA + Hcurr);
MoonCulm = -Hcurr; MoonCulm = -Hcurr;
MoonRise = (-Hhoriz-Hcurr); MoonRise = (-hHoriz-Hcurr);
MoonSet = (Hhoriz-Hcurr); MoonSet = (hHoriz-Hcurr);
if (raises) { if (raises)
if (raised==false) { {
if (!hasRisen)
{
MoonRise += (MoonRise<0.0)?24.0:0.0; MoonRise += (MoonRise<0.0)?24.0:0.0;
MoonSet -= (MoonSet>0.0)?24.0:0.0; MoonSet -= (MoonSet>0.0)?24.0:0.0;
}; }
// Rise time: // Rise time:
tempEphH = MoonRise*TFrac; tempEphH = MoonRise*TFrac;
MoonRise = myJD + (MoonRise/24.); MoonRise = myJD + (MoonRise/24.);
for (i=0; i<Niter; i++) for (i=0; i<NUM_ITER; i++)
{ {
// Get modified coordinates: // Get modified coordinates:
jd1 = MoonRise; tempJd = MoonRise;
if (Kind<3) if (bodyType<3)
{ {
getSunMoonCoords(core,jd1,RAS,DecS,R getSunMoonCoords(core, tempJd,
A,Dec,EclLon,false); raSun, decSun,
ra, dec,
eclLon, false);
} else } else
{ {
getPlanetCoords(core,jd1,RA,Dec,fals e); getPlanetCoords(core, tempJd, ra, de c, false);
}; };
if (Kind==1) {RA = RAS; Dec = DecS;}; if (bodyType==1) {ra = raSun; dec = decSun;} ;
// Current hour angle at mod. coordinates: // Current hour angle at mod. coordinates:
Hcurr = toUnsignedRA(SidT-RA); Hcurr = toUnsignedRA(SidT-ra);
Hcurr -= (raised)?0.0:24.; Hcurr -= (hasRisen)?0.0:24.;
Hcurr -= (Hcurr>12.)?24.0:0.0; Hcurr -= (Hcurr>12.)?24.0:0.0;
// H at horizon for mod. coordinates: // H at horizon for mod. coordinates:
Hhoriz = HourAngle(mylat,RefracHoriz,Dec); hHoriz = calculateHourAngle(mylat,refractedH orizonAlt,dec);
// Compute eph. times for mod. coordinates: // Compute eph. times for mod. coordinates:
TempH = (-Hhoriz-Hcurr)*TFrac; tempH = (-hHoriz-Hcurr)*TFrac;
if (raised==false) TempH += (TempH<0.0)?24.0 if (hasRisen==false) tempH += (tempH<0.0)?24
:0.0; .0:0.0;
// Check convergence: // Check convergence:
if (std::abs(TempH-tempEphH)<JDsec) break; if (std::abs(tempH-tempEphH)<JDsec) break;
// Update rise-time estimate: // Update rise-time estimate:
tempEphH = TempH; tempEphH = tempH;
MoonRise = myJD + (tempEphH/24.); MoonRise = myJD + (tempEphH/24.);
}; };
// Set time: // Set time:
tempEphH = MoonSet; tempEphH = MoonSet;
MoonSet = myJD + (MoonSet/24.); MoonSet = myJD + (MoonSet/24.);
for (i=0; i<Niter; i++) for (i=0; i<NUM_ITER; i++)
{ {
// Get modified coordinates: // Get modified coordinates:
jd1 = MoonSet; tempJd = MoonSet;
if (Kind<3) if (bodyType < 3)
{ getSunMoonCoords(core, tempJd,
getSunMoonCoords(core,jd1,RAS,DecS,R raSun, decSun,
A,Dec,EclLon,false); ra, dec,
} else eclLon, false);
{ else
getPlanetCoords(core,jd1,RA,Dec,fals getPlanetCoords(core, tempJd, ra, de
e); c, false);
};
if (Kind==1) {RA = RAS; Dec = DecS;}; if (bodyType==1) {ra = raSun; dec = decSun;} ;
// Current hour angle at mod. coordinates: // Current hour angle at mod. coordinates:
Hcurr = toUnsignedRA(SidT-RA); Hcurr = toUnsignedRA(SidT-ra);
Hcurr -= (raised)?24.:0.; Hcurr -= (hasRisen)?24.:0.;
Hcurr += (Hcurr<-12.)?24.0:0.0; Hcurr += (Hcurr<-12.)?24.0:0.0;
// H at horizon for mod. coordinates: // H at horizon for mod. coordinates:
Hhoriz = HourAngle(mylat,RefracHoriz,Dec); hHoriz = calculateHourAngle(mylat, refracted HorizonAlt, dec);
// Compute eph. times for mod. coordinates: // Compute eph. times for mod. coordinates:
TempH = (Hhoriz-Hcurr)*TFrac; tempH = (hHoriz-Hcurr)*TFrac;
if (raised==false) TempH -= (TempH>0.0)?24.0 if (!hasRisen)
:0.0; tempH -= (tempH>0.0)?24.0:0.0;
// Check convergence: // Check convergence:
if (std::abs(TempH-tempEphH)<JDsec) break; if (std::abs(tempH-tempEphH)<JDsec)
break;
// Update set-time estimate: // Update set-time estimate:
tempEphH = TempH; tempEphH = tempH;
MoonSet = myJD + (tempEphH/24.); MoonSet = myJD + (tempEphH/24.);
}; };
} }
else // Comes from if(raises) else // Comes from if(raises)
{ {
MoonSet = -1.0; MoonRise = -1.0; MoonSet = -1.0;
MoonRise = -1.0;
}; };
// Culmination time: // Culmination time:
tempEphH = MoonCulm; tempEphH = MoonCulm;
MoonCulm = myJD + (MoonCulm/24.); MoonCulm = myJD + (MoonCulm/24.);
for (i=0; i<Niter; i++) for (i=0; i<NUM_ITER; i++)
{ {
// Get modified coordinates: // Get modified coordinates:
jd1 = MoonCulm; tempJd = MoonCulm;
if (Kind<3) if (bodyType<3)
{ {
getSunMoonCoords(core,jd1,RAS,DecS,R getSunMoonCoords(core,tempJd,raSun,decSun,ra
A,Dec,EclLon,false); ,dec,eclLon,false);
} else } else
{ {
getPlanetCoords(core,jd1,RA,Dec,fals getPlanetCoords(core,tempJd,ra,dec,false);
e); };
};
if (Kind==1) {RA = RAS; Dec = DecS;}; if (bodyType==1) {ra = raSun; dec = decSun;};
// Current hour angle at mod. coordinates: // Current hour angle at mod. coordinates:
Hcurr = toUnsignedRA(SidT-RA); Hcurr = toUnsignedRA(SidT-ra);
Hcurr += (LocPos[1]<0.0)?24.0:-24.0; Hcurr += (LocPos[1]<0.0)?24.0:-24.0;
Hcurr -= (Hcurr>12.)?24.0:0.0; Hcurr -= (Hcurr>12.)?24.0:0.0;
// Compute eph. times for mod. coordinates: // Compute eph. times for mod. coordinates:
TempH = -Hcurr*TFrac; tempH = -Hcurr*TFrac;
// Check convergence: // Check convergence:
if (std::abs(TempH-tempEphH)<JDsec) break; if (std::abs(tempH-tempEphH)<JDsec) break;
tempEphH = TempH; tempEphH = tempH;
MoonCulm = myJD + (tempEphH/24.); MoonCulm = myJD + (tempEphH/24.);
culmAlt = std::abs(mylat-Dec); // 90 - altitude at t ransit. culmAlt = std::abs(mylat-dec); // 90 - altitude at t ransit.
}; };
// qDebug() << q_("%1").arg(MoonCulm,0,'f',5); // qDebug() << q_("%1").arg(MoonCulm,0,'f',5);
lastJDMoon = myJD; lastJDMoon = myJD;
}; // Comes from if (std::abs(myJD-lastJDMoon)>JDsec || LastObject!= Kind) }; // Comes from if (std::abs(myJD-lastJDMoon)>JDsec || LastObject!= Kind)
// Find out the days of Full Moon: // Find out the days of Full Moon:
if (Kind==2 && show_FullMoon) // || show_SuperMoon)) if (bodyType==2 && show_FullMoon) // || show_SuperMoon))
{ {
// Only estimate date of Full Moon if we have changed Lunar month: // Only estimate date of Full Moon if we have changed Lunar month:
if (myJD > nextFullMoon || myJD < prevFullMoon) if (myJD > nextFullMoon || myJD < prevFullMoon)
{ {
// Estimate the nearest (in time) Full Moon: // Estimate the nearest (in time) Full Moon:
double nT; double nT;
double dT = std::modf((myJD-RefFullMoon)/MoonT,&nT); double dT = std::modf((myJD-RefFullMoon)/MoonT,&nT);
if (dT>0.5) {nT += 1.0;}; if (dT>0.5) {nT += 1.0;};
skipping to change at line 1411 skipping to change at line 1488
for (int j=0; j<2; j++) for (int j=0; j<2; j++)
{ // Two steps: one for the previos Full Moon and th e other for the next one. { // Two steps: one for the previos Full Moon and th e other for the next one.
iniEst1 = TempFullMoon - 0.25*MoonT; iniEst1 = TempFullMoon - 0.25*MoonT;
iniEst2 = TempFullMoon + 0.25*MoonT; iniEst2 = TempFullMoon + 0.25*MoonT;
Sec1 = iniEst1; // TempFullMoon - 0.05*MoonT ; // Initial estimates of Full-Moon dates Sec1 = iniEst1; // TempFullMoon - 0.05*MoonT ; // Initial estimates of Full-Moon dates
Sec2 = iniEst2; // TempFullMoon + 0.05*MoonT ; Sec2 = iniEst2; // TempFullMoon + 0.05*MoonT ;
getSunMoonCoords(core,Sec1,RAS,DecS,RA,Dec,E getSunMoonCoords(core,Sec1,raSun,decSun,ra,d
clLon,false); ec,eclLon,false);
Temp1 = EclLon; //Lambda(RA,Dec,RAS,DecS); Temp1 = eclLon; //Lambda(RA,Dec,RAS,DecS);
getSunMoonCoords(core,Sec2,RAS,DecS,RA,Dec,E getSunMoonCoords(core,Sec2,raSun,decSun,ra,d
clLon,false); ec,eclLon,false);
Temp2 = EclLon; //Lambda(RA,Dec,RAS,DecS); Temp2 = eclLon; //Lambda(RA,Dec,RAS,DecS);
for (int i=0; i<100; i++) // A limit of 100 iterations. for (int i=0; i<100; i++) // A limit of 100 iterations.
{ {
Phase1 = (Sec2-Sec1)/(Temp1-Temp2)* Phase1 = (Sec2-Sec1)/(Temp1-Temp2)*T
Temp1+Sec1; emp1+Sec1;
getSunMoonCoords(core,Phase1,RAS,Dec getSunMoonCoords(core,Phase1,raSun,d
S,RA,Dec,EclLon,false); ecSun,ra,dec,eclLon,false);
if (Temp1*EclLon < 0.0) if (Temp1*eclLon < 0.0)
{ {
Sec2 = Phase1; Sec2 = Phase1;
Temp2 = EclLon; Temp2 = eclLon;
} else { } else {
Sec1 = Phase1; Sec1 = Phase1;
Temp1 = EclLon; Temp1 = eclLon;
}; };
// qDebug() << QString("%1 %2 %3 %4 "). arg(Sec1).arg(Sec2).arg(Temp1).arg(Temp2); // qDebug() << QString("%1 %2 %3 %4 "). arg(Sec1).arg(Sec2).arg(Temp1).arg(Temp2);
if (std::abs(Sec2-Sec1) < 10.*dT) / / 1 minute accuracy; convergence. if (std::abs(Sec2-Sec1) < 10.*dT) / / 1 minute accuracy; convergence.
{ {
TempFullMoon = (Sec1+Sec2)/2 .; TempFullMoon = (Sec1+Sec2)/2 .;
// qDebug() << QString("%1%2 ") .arg(TempFullMoon); // qDebug() << QString("%1%2 ") .arg(TempFullMoon);
break; break;
skipping to change at line 1460 skipping to change at line 1537
}; };
}; };
// Update the string shown in the screen: // Update the string shown in the screen:
int fullDay, fullMonth,fullYear, fullHour, fullMinut e, fullSecond; int fullDay, fullMonth,fullYear, fullHour, fullMinut e, fullSecond;
double LocalPrev = prevFullMoon+GMTShift+0.5; // Sh ift to the local time. double LocalPrev = prevFullMoon+GMTShift+0.5; // Sh ift to the local time.
double LocalNext = nextFullMoon+GMTShift+0.5; double LocalNext = nextFullMoon+GMTShift+0.5;
double intMoon; double intMoon;
double LocalTMoon = 24.*modf(LocalPrev,&intMoon); double LocalTMoon = 24.*modf(LocalPrev,&intMoon);
StelUtils::getDateFromJulianDay(intMoon,&fullYear,&f ullMonth,&fullDay); StelUtils::getDateFromJulianDay(intMoon, &fullYear, &fullMonth, &fullDay);
double2hms(toUnsignedRA(LocalTMoon),fullHour,fullMin ute,fullSecond); double2hms(toUnsignedRA(LocalTMoon),fullHour,fullMin ute,fullSecond);
if (getDateFormat()) if (getDateFormat())
bestNight = msgPrevFullMoon.arg(fullDay).arg (months[fullMonth-1]).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0')); lineBestNight = msgPrevFullMoon.arg(fullDay) .arg(monthNames[fullMonth-1]).arg(fullHour).arg(fullMinute,2,10,QLatin1Char ('0'));
else else
bestNight = msgPrevFullMoon.arg(months[fullM onth-1]).arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0')); lineBestNight = msgPrevFullMoon.arg(monthNam es[fullMonth-1]).arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char ('0'));
LocalTMoon = 24.*modf(LocalNext,&intMoon); LocalTMoon = 24.*modf(LocalNext,&intMoon);
StelUtils::getDateFromJulianDay(intMoon,&fullYear,&f ullMonth,&fullDay); StelUtils::getDateFromJulianDay(intMoon,&fullYear,&f ullMonth,&fullDay);
double2hms(toUnsignedRA(LocalTMoon),fullHour,fullMin ute,fullSecond); double2hms(toUnsignedRA(LocalTMoon),fullHour,fullMin ute,fullSecond);
if (getDateFormat()) if (getDateFormat())
bestNight += msgNextFullMoon.arg(fullDay).ar g(months[fullMonth-1]).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0')); lineBestNight += msgNextFullMoon.arg(fullDay ).arg(monthNames[fullMonth-1]).arg(fullHour).arg(fullMinute,2,10,QLatin1Cha r('0'));
else else
bestNight += msgNextFullMoon.arg(months[full Month-1]).arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0')); lineBestNight += msgNextFullMoon.arg(monthNa mes[fullMonth-1]).arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Cha r('0'));
ObsRange = ""; lineObservableRange.clear();
AcroCos = ""; lineAcroCos.clear();
// Now, compute the days of all the Full Moons of the current year, and get the Earth/Moon distance: // Now, compute the days of all the Full Moons of the current year, and get the Earth/Moon distance:
// double monthFrac, monthTemp, maxMoonDate; // double monthFrac, monthTemp, maxMoonDate;
// monthFrac = std::modf((nextFullMoon-Jan1stJD)/MoonT, &monthTemp); // monthFrac = std::modf((nextFullMoon-Jan1stJD)/MoonT, &monthTemp);
// int PrevMonths = (int)(monthTemp+0.0*monthFrac); // int PrevMonths = (int)(monthTemp+0.0*monthFrac);
// double BestDistance = 1.0; // initial dummy value fo r Sun-Moon distance; // double BestDistance = 1.0; // initial dummy value fo r Sun-Moon distance;
// double Distance; // temporal variable to save Earth- Moon distance at each month. // double Distance; // temporal variable to save Earth- Moon distance at each month.
// qDebug() << q_("%1 ").arg(PrevMonths); // qDebug() << q_("%1 ").arg(PrevMonths);
skipping to change at line 1503 skipping to change at line 1580
// BestDistance = Distance; // BestDistance = Distance;
// maxMoonDate = jd1; // maxMoonDate = jd1;
// }; // };
// }; // };
// maxMoonDate += GMTShift+0.5; // maxMoonDate += GMTShift+0.5;
// StelUtils::getDateFromJulianDay(maxMoonDate,&fullYea r,&fullMonth,&fullDay); // StelUtils::getDateFromJulianDay(maxMoonDate,&fullYea r,&fullMonth,&fullDay);
// double MoonSize = MoonPerilune/BestDistance*100.; // double MoonSize = MoonPerilune/BestDistance*100.;
// ObsRange = q_("Greatest Full Moon: %1 "+months[fullM onth-1]+" (%2% of Moon at Perilune)").arg(fullDay).arg(MoonSize,0,'f',2); // ObsRange = q_("Greatest Full Moon: %1 "+months[fullM onth-1]+" (%2% of Moon at Perilune)").arg(fullDay).arg(MoonSize,0,'f',2);
}; };
} }
else if (Kind <3) else if (bodyType <3)
{ {
bestNight = ""; lineBestNight.clear();
ObsRange = ""; lineObservableRange.clear();
AcroCos = ""; lineAcroCos.clear();
}; };
// Return the Moon and Earth to its current position: // Return the Moon and Earth to its current position:
if (Kind<3) if (bodyType<3)
{ {
getSunMoonCoords(core,myJD,RAS,DecS,RA,Dec,EclLon,true); getSunMoonCoords(core, myJD, raSun, decSun, ra, dec, eclLon,
} else true);
}
else
{ {
getPlanetCoords(core,myJD,RA,Dec,true); getPlanetCoords(core, myJD, ra, dec, true);
}; };
return raises; return raises;
} }
////////////////////////////////// //////////////////////////////////
/// STUFF FOR THE GUI CONFIG /// STUFF FOR THE GUI CONFIG
bool Observability::configureGui(bool show) bool Observability::configureGui(bool show)
{ {
if (show) if (show)
{ configDialog->setVisible(true);
StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance()
.getGui());
gui->getGuiAction("actionShow_Observability_ConfigDialog")->
setChecked(true);
}
return true; return true;
} }
void Observability::restoreDefaults(void) void Observability::resetConfiguration()
{
restoreDefaultConfigIni();
readSettingsFromConfig();
}
void Observability::restoreDefaultConfigIni(void)
{ {
// Remove the plug-in's group from the configuration,
// after that it will be loaded with default values.
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
Q_ASSERT(conf);
conf->beginGroup("Observability"); conf->remove("Observability");
loadConfiguration();
// delete all existing settings...
conf->remove("");
// Set defaults
conf->setValue("font_size", 15);
conf->setValue("Sun_Altitude", 12);
conf->setValue("Horizon_Altitude", 0);
conf->setValue("font_color", "0,0.5,1");
conf->setValue("show_AcroCos", true);
conf->setValue("show_Good_Nights", true);
conf->setValue("show_Best_Night", true);
conf->setValue("show_Today", true);
conf->setValue("show_FullMoon", true);
// conf->setValue("show_Crescent", true);
// conf->setValue("show_SuperMoon", true);
conf->endGroup();
} }
void Observability::readSettingsFromConfig(void) void Observability::loadConfiguration()
{ {
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
conf->beginGroup("Observability"); conf->beginGroup("Observability");
// Load settings from main config file // Load settings from main config file
fontSize = conf->value("font_size",15).toInt(); fontSize = conf->value("font_size",15).toInt();
font.setPixelSize(fontSize); font.setPixelSize(fontSize);
fontColor = StelUtils::strToVec3f(conf->value("font_color", "0,0.5,1 ").toString()); fontColor = StelUtils::strToVec3f(conf->value("font_color", "0,0.5,1 ").toString());
show_AcroCos = conf->value("show_AcroCos", true).toBool(); show_AcroCos = conf->value("show_AcroCos", true).toBool();
show_Good_Nights = conf->value("show_Good_Nights", true).toBool(); show_Good_Nights = conf->value("show_Good_Nights", true).toBool();
show_Best_Night = conf->value("show_Best_Night", true).toBool(); show_Best_Night = conf->value("show_Best_Night", true).toBool();
show_Today = conf->value("show_Today", true).toBool(); show_Today = conf->value("show_Today", true).toBool();
show_FullMoon = conf->value("show_FullMoon", true).toBool(); show_FullMoon = conf->value("show_FullMoon", true).toBool();
// show_Crescent = conf->value("show_Crescent", true).toBool(); // show_Crescent = conf->value("show_Crescent", true).toBool();
// show_SuperMoon = conf->value("show_SuperMoon", true).toBool(); // show_SuperMoon = conf->value("show_SuperMoon", true).toBool();
iAltitude = conf->value("Sun_Altitude", 12).toInt(); // For backwards compatibility, the value of this key is stored with
AstroTwiAlti = -((double)iAltitude)/Rad2Deg ; // inverted sign.
// TODO: Skip the sign inversion when the key is changed.
int altitude = -(conf->value("Sun_Altitude", 12).toInt());
setTwilightAltitude(altitude);
iHorizAltitude = conf->value("Horizon_Altitude", 0).toInt(); altitude = conf->value("Horizon_Altitude", 0).toInt();
HorizAlti = ((double)iHorizAltitude)/Rad2Deg ; setHorizonAltitude(altitude);
conf->endGroup(); conf->endGroup();
// Load date format from main settings.
// TODO: Handle date format properly.
if (conf->value("localization/date_display_format", "system_default"
).toString() == "ddmmyyyy")
setDateFormat(true);
else
setDateFormat(false);
} }
void Observability::saveSettingsToConfig(void) void Observability::saveConfiguration()
{ {
QSettings* conf = StelApp::getInstance().getSettings(); QSettings* conf = StelApp::getInstance().getSettings();
QString fontColorStr = QString("%1,%2,%3").arg(fontColor[0],0,'f',2) .arg(fontColor[1],0,'f',2).arg(fontColor[2],0,'f',2); QString fontColorStr = QString("%1,%2,%3").arg(fontColor[0],0,'f',2) .arg(fontColor[1],0,'f',2).arg(fontColor[2],0,'f',2);
// Set updated values // Set updated values
conf->beginGroup("Observability"); conf->beginGroup("Observability");
conf->setValue("font_size", fontSize); conf->setValue("font_size", fontSize);
conf->setValue("Sun_Altitude", iAltitude); // For backwards compatibility, the value of this key is stored with
conf->setValue("Horizon_Altitude", iHorizAltitude); // inverted sign.
// TODO: Skip the sign inversion when the key is changed.
conf->setValue("Sun_Altitude", -twilightAltDeg);
conf->setValue("Horizon_Altitude", horizonAltDeg);
conf->setValue("font_color", fontColorStr); conf->setValue("font_color", fontColorStr);
conf->setValue("show_AcroCos", show_AcroCos); conf->setValue("show_AcroCos", show_AcroCos);
conf->setValue("show_Good_Nights", show_Good_Nights); conf->setValue("show_Good_Nights", show_Good_Nights);
conf->setValue("show_Best_Night", show_Best_Night); conf->setValue("show_Best_Night", show_Best_Night);
conf->setValue("show_Today", show_Today); conf->setValue("show_Today", show_Today);
conf->setValue("show_FullMoon", show_FullMoon); conf->setValue("show_FullMoon", show_FullMoon);
// conf->setValue("show_Crescent", show_Crescent); // conf->setValue("show_Crescent", show_Crescent);
// conf->setValue("show_SuperMoon", show_SuperMoon); // conf->setValue("show_SuperMoon", show_SuperMoon);
conf->endGroup(); conf->endGroup();
} }
void Observability::setShow(int output, bool setVal) void Observability::enableTodayField(bool enabled)
{ {
switch(output) show_Today = enabled;
{ configChanged = true;
case 1: {show_Today = setVal; break;} }
case 2: {show_AcroCos = setVal; break;}
case 3: {show_Good_Nights = setVal; break;} void Observability::enableAcroCosField(bool enabled)
case 4: {show_Best_Night = setVal; break;} {
case 5: {show_FullMoon = setVal; nextFullMoon=0.0; prevFullM show_AcroCos = enabled;
oon=0.0; break;} configChanged = true;
// case 6: {show_Crescent = setVal; break;} }
// case 7: {show_SuperMoon = setVal; break;}
}; void Observability::enableGoodNightsField(bool enabled)
{
show_Good_Nights = enabled;
configChanged = true;
}
void Observability::enableOppositionField(bool enabled)
{
show_Best_Night = enabled;
configChanged = true;
}
void Observability::enableFullMoonField(bool enabled)
{
show_FullMoon = enabled;
configChanged = true; configChanged = true;
} }
bool Observability::getShowFlags(int iFlag) bool Observability::getShowFlags(int iFlag)
{ {
switch (iFlag) switch (iFlag)
{ {
case 1: return show_Today; case 1: return show_Today;
case 2: return show_AcroCos; case 2: return show_AcroCos;
case 3: return show_Good_Nights; case 3: return show_Good_Nights;
skipping to change at line 1656 skipping to change at line 1736
Vec3f Observability::getFontColor(void) Vec3f Observability::getFontColor(void)
{ {
return fontColor; return fontColor;
} }
int Observability::getFontSize(void) int Observability::getFontSize(void)
{ {
return fontSize; return fontSize;
} }
int Observability::getSunAltitude(void) int Observability::getTwilightAltitude()
{ {
return iAltitude; return twilightAltDeg;
} }
int Observability::getHorizAltitude(void) int Observability::getHorizonAltitude()
{ {
return iHorizAltitude; return horizonAltDeg;
} }
void Observability::setFontColor(int color, int value) void Observability::setFontColor(const Vec3f& color)
{ {
float fValue = (float)(value) / 100.; fontColor = color; // Vector3::operator =() is overloaded. :)
fontColor[color] = fValue;
} }
void Observability::setFontSize(int value) void Observability::setFontSize(int size)
{ {
fontSize = value; fontSize = size;
} }
void Observability::setSunAltitude(int value) void Observability::setTwilightAltitude(int altitude)
{ {
AstroTwiAlti = -((double) value)/Rad2Deg ; twilightAltRad = ((double) altitude)/Rad2Deg ;
iAltitude = value; twilightAltDeg = altitude;
configChanged = true; configChanged = true;
} }
void Observability::setHorizAltitude(int value) void Observability::setHorizonAltitude(int altitude)
{ {
HorizAlti = ((double) value)/Rad2Deg ; horizonAltitude = ((double) altitude)/Rad2Deg ;
iHorizAltitude = value; horizonAltDeg = altitude;
configChanged = true; configChanged = true;
} }
/// END OF STUFF FOR THE GUI CONFIG. void Observability::showReport(bool b)
///////////////////////////////
// Enable the Observability:
void Observability::enableObservability(bool b)
{ {
flagShowObservability = b; flagShowReport = b;
} }
 End of changes. 273 change blocks. 
894 lines changed or deleted 955 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/