void modCalcEquinox::slotComputeEquinoxesAndSolstices (void) { long double julianDay = 0., jdf = 0.; float deltaJd; KStarsData *kd = (KStarsData*) parent()->parent()->parent(); KSSun *Sun = new KSSun(kd); int year0 = getYear( yearEdit->text() ); if (equinoxSolsticesComboBox->currentItem() == 0 ) { julianDay = Sun->springEquinox(year0); jdf = Sun->summerSolstice(year0); } else if(equinoxSolsticesComboBox->currentItem() == 1) { julianDay = Sun->summerSolstice(year0); jdf = Sun->autumnEquinox(year0); } else if (equinoxSolsticesComboBox->currentItem() == 2 ) { julianDay = Sun->autumnEquinox(year0); jdf = Sun->winterSolstice(year0); } else if(equinoxSolsticesComboBox->currentItem() == 3) { julianDay = Sun->winterSolstice(year0); jdf = Sun->springEquinox(year0+1); } deltaJd = (float) (jdf - julianDay); showStartDateTime(julianDay); showSeasonDuration(deltaJd); }
void modCalcDayLength::slotComputePosTime() { long double jd0 = getDateTime().djd(); getGeoLocation(); KSNumbers * num = new KSNumbers(jd0); KSSun *Sun = new KSSun(((KStars*) parent()->parent()->parent())->data()); Sun->findPosition(num); QTime setQtime = Sun->riseSetTime( jd0 , geoPlace, false ); QTime riseQtime = Sun->riseSetTime( jd0 , geoPlace, true ); QTime transitQtime = Sun->transitTime(jd0 , geoPlace); dms setAz = Sun->riseSetTimeAz(jd0, geoPlace, false); dms riseAz = Sun->riseSetTimeAz(jd0, geoPlace, true); dms transAlt = Sun->transitAltitude(jd0, geoPlace); if (setQtime.isValid() ) { azSetBox->show( setAz ); elTransitBox->show( transAlt ); azRiseBox->show( riseAz ); setTimeBox->showTime( setQtime ); riseTimeBox->showTime( riseQtime ); transitTimeBox->showTime( transitQtime ); QTime dayLQtime = lengthOfDay (setQtime,riseQtime); dayLBox->showTime( dayLQtime ); } else if (transAlt.Degrees() > 0. ) { azSetBox->setDMS(i18n("Circumpolar")); elTransitBox->show( transAlt ); azRiseBox->setDMS(i18n("Circumpolar")); setTimeBox->showTime( setQtime ); riseTimeBox->showTime( riseQtime ); transitTimeBox->showTime( transitQtime ); dayLBox->setEntry("24:00:00"); } else if (transAlt.Degrees() < 0. ) { azSetBox->setDMS("does not rise"); elTransitBox->setDMS("does not rise"); azRiseBox->setDMS("does not rise"); setTimeBox->clearFields(); riseTimeBox->clearFields(); transitTimeBox->clearFields(); dayLBox->showTime( QTime(0,0,0) ); } delete num; }
KStarsDateTime modCalcEquinox::findSolstice( int year, bool Summer ) { //Find the moment when the Sun reaches maximum declination //First find three points which bracket the maximum (i.e., x2 > x1,x3) //Start at June 16th, which will always be approaching the solstice long double jd1,jd2,jd3,jd4; double y2(0.0),y3(0.0), y4(0.0); int month = 6; if ( ! Summer ) month = 12; jd3 = KStarsDateTime( QDate( year, month, 16 ), QTime(0,0,0) ).djd(); KSNumbers num( jd3 ); KSSun Sun; Sun.findPosition( &num ); y3 = Sun.dec().Degrees(); int sgn = 1; if ( ! Summer ) sgn = -1; //find minimum if the winter solstice is sought do { jd3 += 1.0; num.updateValues( jd3 ); Sun.findPosition( &num ); y2 = y3; Sun.findPosition( &num ); y3 = Sun.dec().Degrees(); } while ( y3*sgn > y2*sgn ); //Ok, now y2 is larger(smaller) than both y3 and y1. jd2 = jd3 - 1.0; jd1 = jd3 - 2.0; //Choose a new starting jd2 that follows the golden ratio: // a/b = 1.618; a+b = 2...a = 0.76394 jd2 = jd1 + 0.76394; num.updateValues( jd2 ); Sun.findPosition( &num ); y2 = Sun.dec().Degrees(); while ( jd3 - jd1 > 0.0005 ) { //sub-minute pecision jd4 = jd1 + jd3 - jd2; num.updateValues( jd4 ); Sun.findPosition( &num ); y4 = Sun.dec().Degrees(); if ( y4*sgn > y2*sgn ) { //make jd4 the new center if ( jd4 > jd2 ) { jd1 = jd2; jd2 = jd4; y2 = y4; } else { jd3 = jd2; y3 = y2; jd2 = jd4; y2 = y4; } } else { //make jd4 a new endpoint if ( jd4 > jd2 ) { jd3 = jd4; y3 = y4; } else { jd1 = jd4; } } } return KStarsDateTime( jd2 ); }
void modCalcEquinox::slotCompute() { KStarsData* data = KStarsData::Instance(); KSSun Sun; int year0 = Year->value(); KStarsDateTime dt( QDate(year0, 1, 1), QTime(0,0,0) ); long double jd0 = dt.djd(); //save JD on Jan 1st for ( int imonth=0; imonth < 12; imonth++ ) { KStarsDateTime kdt( QDate(year0, imonth+1, 1), QTime(0,0,0) ); DMonth[imonth] = kdt.djd() - jd0; } Plot->removeAllPlotObjects(); //Add the celestial equator, just a single line bisecting the plot horizontally KPlotObject *ce = new KPlotObject( data->colorScheme()->colorNamed( "EqColor" ), KPlotObject::Lines, 2.0 ); ce->addPoint( 0.0, 0.0 ); ce->addPoint( 366.0, 0.0 ); Plot->addPlotObject( ce ); //Add Ecliptic. This is more complicated than simply incrementing the //ecliptic longitude, because we want the x-axis to be time, not RA. //For each day in the year, compute the Sun's position. KPlotObject *ecl = new KPlotObject( data->colorScheme()->colorNamed( "EclColor" ), KPlotObject::Lines, 2 ); ecl->setLinePen( QPen( ecl->pen().color(), 4 ) ); Plot->setLimits( 1.0, double(dt.date().daysInYear()), -30.0, 30.0 ); //Add top and bottom axis lines, and custom tickmarks at each month addDateAxes(); for ( int i=1; i<=dt.date().daysInYear(); i++ ) { KSNumbers num( dt.djd() ); Sun.findPosition( &num ); ecl->addPoint( double(i), Sun.dec().Degrees() ); dt = dt.addDays( 1 ); } Plot->addPlotObject( ecl ); dSpring = findEquinox( Year->value(), true, ecl ); dSummer = findSolstice( Year->value(), true ); dAutumn = findEquinox( Year->value(), false, ecl ); dWinter = findSolstice( Year->value(), false ); //Display the Date/Time of each event in the text fields VEquinox->setText( KGlobal::locale()->formatDateTime( dSpring, KLocale::LongDate ) ); SSolstice->setText( KGlobal::locale()->formatDateTime( dSummer, KLocale::LongDate ) ); AEquinox->setText( KGlobal::locale()->formatDateTime( dAutumn, KLocale::LongDate ) ); WSolstice->setText( KGlobal::locale()->formatDateTime( dWinter, KLocale::LongDate ) ); //Add vertical dotted lines at times of the equinoxes and solstices KPlotObject *poSpring = new KPlotObject( Qt::white, KPlotObject::Lines, 1 ); poSpring->setLinePen( QPen( Qt::white, 1.0, Qt::DotLine ) ); poSpring->addPoint( dSpring.djd()-jd0, Plot->dataRect().top() ); poSpring->addPoint( dSpring.djd()-jd0, Plot->dataRect().bottom() ); Plot->addPlotObject( poSpring ); KPlotObject *poSummer = new KPlotObject( Qt::white, KPlotObject::Lines, 1 ); poSummer->setLinePen( QPen( Qt::white, 1.0, Qt::DotLine ) ); poSummer->addPoint( dSummer.djd()-jd0, Plot->dataRect().top() ); poSummer->addPoint( dSummer.djd()-jd0, Plot->dataRect().bottom() ); Plot->addPlotObject( poSummer ); KPlotObject *poAutumn = new KPlotObject( Qt::white, KPlotObject::Lines, 1 ); poAutumn->setLinePen( QPen( Qt::white, 1.0, Qt::DotLine ) ); poAutumn->addPoint( dAutumn.djd()-jd0, Plot->dataRect().top() ); poAutumn->addPoint( dAutumn.djd()-jd0, Plot->dataRect().bottom() ); Plot->addPlotObject( poAutumn ); KPlotObject *poWinter = new KPlotObject( Qt::white, KPlotObject::Lines, 1 ); poWinter->setLinePen( QPen( Qt::white, 1.0, Qt::DotLine ) ); poWinter->addPoint( dWinter.djd()-jd0, Plot->dataRect().top() ); poWinter->addPoint( dWinter.djd()-jd0, Plot->dataRect().bottom() ); Plot->addPlotObject( poWinter ); }
void modCalcEquinox::processLines( QTextStream &istream ) { // we open the output file // QTextStream istream(&fIn); QString outputFileName; outputFileName = OutputLineEditBatch->text(); QFile fOut( outputFileName ); fOut.open(IO_WriteOnly); QTextStream ostream(&fOut); QString line; QString space = " "; int yearB; int i = 0; long double jdsp = 0., jdsu = 0., jdau = 0., jdwin = 0., jdsp1 = 0.; KStarsData *kd = (KStarsData*) parent()->parent()->parent(); KSSun *Sun = new KSSun(kd); while ( ! istream.eof() ) { line = istream.readLine(); line.stripWhiteSpace(); //Go through the line, looking for parameters QStringList fields = QStringList::split( " ", line ); i = 0; // Read year and write in ostream if corresponds if(yearCheckBatch->isChecked() ) { yearB = fields[i].toInt(); i++; } else yearB = yearEditBatch->text().toInt(); if ( allRadioBatch->isChecked() ) ostream << yearB << space; else if(yearCheckBatch->isChecked() ) ostream << yearB << space; jdsp = Sun->springEquinox(yearB); jdsu = Sun->summerSolstice(yearB); jdau = Sun->autumnEquinox(yearB); jdwin = Sun->winterSolstice(yearB); jdsp1 = Sun->springEquinox(yearB+1); KStarsDateTime dts( jdsp ); KStarsDateTime dtu( jdsu ); KStarsDateTime dta( jdau ); KStarsDateTime dtw( jdwin ); ostream << dts.toString(Qt::ISODate) << space << (float)(jdsu - jdsp) << space << dtu.toString(Qt::ISODate) << space << (float)(jdau - jdsu) << space << dta.toString(Qt::ISODate) << space << (float)(jdwin - jdau) << space << dtw.toString(Qt::ISODate) << space << (float)(jdsp1 - jdwin) << endl; } fOut.close(); }
void modCalcDayLength::updateAlmanac( const QDate &d, GeoLocation *geo ) { //Determine values needed for the Almanac long double jd0 = KStarsDateTime(d, QTime(8,0,0)).djd(); KSNumbers num(jd0); //Sun KSSun Sun; Sun.findPosition(&num); QTime ssTime = Sun.riseSetTime(jd0 , geo, false ); QTime srTime = Sun.riseSetTime(jd0 , geo, true ); QTime stTime = Sun.transitTime(jd0 , geo); dms ssAz = Sun.riseSetTimeAz(jd0, geo, false); dms srAz = Sun.riseSetTimeAz(jd0, geo, true); dms stAlt = Sun.transitAltitude(jd0, geo); //In most cases, the Sun will rise and set: if ( ssTime.isValid() ) { ssAzString = ssAz.toDMSString(); stAltString = stAlt.toDMSString(); srAzString = srAz.toDMSString(); ssTimeString = QLocale().toString( ssTime ); srTimeString = QLocale().toString( srTime ); stTimeString = QLocale().toString( stTime ); QTime daylength = lengthOfDay(ssTime,srTime); daylengthString = QLocale().toString( daylength); //...but not always! } else if ( stAlt.Degrees() > 0. ) { ssAzString = i18n("Circumpolar"); stAltString = stAlt.toDMSString(); srAzString = i18n("Circumpolar"); ssTimeString = "--:--"; srTimeString = "--:--"; stTimeString = QLocale().toString( stTime ); daylengthString = "24:00"; } else if (stAlt.Degrees() < 0. ) { ssAzString = i18n("Does not rise"); stAltString = stAlt.toDMSString(); srAzString = i18n("Does not set"); ssTimeString = "--:--"; srTimeString = "--:--"; stTimeString = QLocale().toString( stTime ); daylengthString = "00:00"; } //Moon KSMoon Moon; QTime msTime = Moon.riseSetTime( jd0 , geo, false ); QTime mrTime = Moon.riseSetTime( jd0 , geo, true ); QTime mtTime = Moon.transitTime(jd0 , geo); dms msAz = Moon.riseSetTimeAz(jd0, geo, false); dms mrAz = Moon.riseSetTimeAz(jd0, geo, true); dms mtAlt = Moon.transitAltitude(jd0, geo); //In most cases, the Moon will rise and set: if ( msTime.isValid() ) { msAzString = msAz.toDMSString(); mtAltString = mtAlt.toDMSString(); mrAzString = mrAz.toDMSString(); msTimeString = QLocale().toString( msTime ); mrTimeString = QLocale().toString( mrTime ); mtTimeString = QLocale().toString( mtTime ); //...but not always! } else if ( mtAlt.Degrees() > 0. ) { msAzString = i18n("Circumpolar"); mtAltString = mtAlt.toDMSString(); mrAzString = i18n("Circumpolar"); msTimeString = "--:--"; mrTimeString = "--:--"; mtTimeString = QLocale().toString( mtTime ); } else if ( mtAlt.Degrees() < 0. ) { msAzString = i18n("Does not rise"); mtAltString = mtAlt.toDMSString(); mrAzString = i18n("Does not rise"); msTimeString = "--:--"; mrTimeString = "--:--"; mtTimeString = QLocale().toString( mtTime ); } //after calling riseSetTime Phase needs to reset, setting it before causes Phase to set nan Moon.findPosition(&num); Moon.findPhase(0); lunarphaseString = Moon.phaseName()+" ("+QString::number( int( 100*Moon.illum() ) )+"%)"; //Fix length of Az strings if ( srAz.Degrees() < 100.0 ) srAzString = ' '+srAzString; if ( ssAz.Degrees() < 100.0 ) ssAzString = ' '+ssAzString; if ( mrAz.Degrees() < 100.0 ) mrAzString = ' '+mrAzString; if ( msAz.Degrees() < 100.0 ) msAzString = ' '+msAzString; }