[Kstars-devel] [kstars] kstars/tools: Correctly draws planets rise/set time in sky calendar for circompolar places.

Jérôme SONRIER jsid at emor3j.fr.eu.org
Sun Apr 15 12:48:31 UTC 2012


Git commit 79a354570014867d990f746f81e2e6159da2b620 by Jérôme SONRIER.
Committed on 06/04/2012 at 01:57.
Pushed by jsonrier into branch 'master'.

Correctly draws planets rise/set time in sky calendar for circompolar places.

CCMAIL: kstars-devel at kde.org

M  +2    -2    kstars/tools/calendarwidget.cpp
M  +2    -0    kstars/tools/calendarwidget.h
M  +112  -37   kstars/tools/skycalendar.cpp

http://commits.kde.org/kstars/79a354570014867d990f746f81e2e6159da2b620

diff --git a/kstars/tools/calendarwidget.cpp b/kstars/tools/calendarwidget.cpp
index e2ae198..8ef3eb5 100644
--- a/kstars/tools/calendarwidget.cpp
+++ b/kstars/tools/calendarwidget.cpp
@@ -57,12 +57,12 @@ void CalendarWidget::paintEvent( QPaintEvent *e ) {
     p.setClipRect( pixRect() );
     p.setClipping( true );
 
+    drawHorizon( &p );
+    
     foreach ( KPlotObject *po, plotObjects() ) {
         po->draw( &p, this );
     }
 
-    drawHorizon( &p );
-
     p.setClipping( false );
     drawAxes( &p );
     
diff --git a/kstars/tools/calendarwidget.h b/kstars/tools/calendarwidget.h
index 19526e2..29dabba 100644
--- a/kstars/tools/calendarwidget.h
+++ b/kstars/tools/calendarwidget.h
@@ -30,6 +30,8 @@ class CalendarWidget : public KPlotWidget
     public:
         explicit CalendarWidget( QWidget *parent=0 );
         void setHorizon();
+        inline float getRiseTime( int i ) { return riseTimeList.at( i ); }
+        inline float getSetTime( int i ) { return setTimeList.at( i ); }
     
     protected:
         void paintEvent( QPaintEvent *e );
diff --git a/kstars/tools/skycalendar.cpp b/kstars/tools/skycalendar.cpp
index 428d1f1..8b55848 100644
--- a/kstars/tools/skycalendar.cpp
+++ b/kstars/tools/skycalendar.cpp
@@ -153,69 +153,144 @@ void SkyCalendar::addPlanetEvents( int nPlanet ) {
 
     for( KStarsDateTime kdt( QDate( year(), 1, 1 ), QTime( 12, 0, 0 ) );
          kdt.date().year() == year();
-         kdt = kdt.addDays( 7 ))
+         kdt = kdt.addDays( 7 ) )
     {
+        float rTime, sTime, tTime;
+        
         //Compute rise/set/transit times.  If they occur before noon, 
         //recompute for the following day
-        QTime rtime = ksp->riseSetTime( kdt, geo, true, true );//rise time, exact
-        if ( rtime.secsTo( QTime( 12, 0, 0 ) ) > 0 ) {
-            rtime = ksp->riseSetTime( kdt.addDays( 1 ), geo, true, true );
-        }
-        QTime stime = ksp->riseSetTime( kdt, geo, false, true );//set time, exact
-        if ( stime.secsTo( QTime( 12, 0, 0 ) ) > 0 ) {
-            stime = ksp->riseSetTime( kdt.addDays( 1 ), geo, false, true );
+        QTime tmp_rTime = ksp->riseSetTime( kdt, geo, true, true );     //rise time, exact
+        QTime tmp_sTime = ksp->riseSetTime( kdt, geo, false, true );    //set time, exact
+        QTime tmp_tTime = ksp->transitTime( kdt, geo );
+        QTime midday( 12, 0, 0 );
+        
+        if ( tmp_rTime == tmp_sTime ) {
+            tmp_rTime = QTime();
+            tmp_sTime = QTime();
         }
-        QTime ttime = ksp->transitTime( kdt, geo );
-        if ( ttime.secsTo( QTime( 12, 0, 0 ) ) > 0 ) {
-            ttime = ksp->transitTime( kdt.addDays( 1 ), geo );
+        
+        if ( tmp_rTime.isValid() && tmp_sTime.isValid() ) {
+            rTime = tmp_rTime.secsTo( midday ) * 24.0 / 86400.0;
+            sTime = tmp_sTime.secsTo( midday ) * 24.0 / 86400.0;
+            
+            if ( tmp_rTime <= midday )
+                rTime = 12.0 - rTime;
+            else
+                rTime = -12.0 - rTime;
+            
+            if ( tmp_sTime <= midday )
+                sTime = 12.0 - sTime;
+            else
+                sTime = -12.0 - sTime;
+        } else {
+            if ( ksp->transitAltitude( kdt, geo ).degree() > 0 ) {
+                rTime = -24.0;
+                sTime =  24.0;
+            } else {
+                rTime =  24.0;
+                sTime = -24.0;
+            }
         }
-
+        
+        tTime = tmp_tTime.secsTo( midday ) * 24.0 / 86400.0;
+        if ( tmp_tTime <= midday )
+            tTime = 12.0 - tTime;
+        else
+            tTime = -12.0 - tTime;
+        
         float dy = kdt.date().daysInYear() - kdt.date().dayOfYear();
-        vRise    << QPointF( timeToHours( rtime ), dy );
-        vSet     << QPointF( timeToHours( stime ), dy );
-        vTransit << QPointF( timeToHours( ttime ), dy );
-    }
+        vRise << QPointF( rTime, dy );
+        vSet << QPointF( sTime, dy );
+        vTransit << QPointF( tTime, dy );
+    }    
 
     //Now, find continuous segments in each QVector and add each segment 
     //as a separate KPlotObject
 
-    // Flags to indicate whether the set / rise / transit labels should be drawn
-
     KPlotObject *oRise = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
     KPlotObject *oSet = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
     KPlotObject *oTransit = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
+    bool needRiseLabel = true;
+    bool needSetLabel = true;
+    bool needTransertLabel = true;
+    QString label;
 
     for ( int i=0; i<vRise.size(); ++i ) {
-        if ( i > 0 && fabs(vRise.at(i).x() - vRise.at(i-1).x()) > 6.0 ) { 
+        /* if rise time is set under -23.0 or above 23.0, it means the planet never rise or set,
+         * we add the current KPlotObject to CalendarView and create a new one. */
+        if ( vRise.at( i ).x() > -23.0 && vRise.at( i ).x() < 23.0 ) {
+            /* If the difference between to points is more than 6 hours,
+             * we consider the line continues on the other side of the view.
+             * Add the current KPlotObject to CalendarView and create a new one. */
+            if ( i > 0 && fabs( vRise.at( i ).x() - vRise.at( i-1 ).x() ) > 6.0 ) { 
+                scUI->CalendarView->addPlotObject( oRise );
+                oRise = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
+                needRiseLabel = true;
+            }
+            // Set label if the line is on the night area, and if it needs one.
+            if ( needRiseLabel 
+                 && vRise.at(i).x() > scUI->CalendarView->getSetTime( i ) 
+                 && vRise.at(i).x() < scUI->CalendarView->getRiseTime( i ) ) {
+                label = i18nc( "A planet rises from the horizon", "%1 rises", ksp->name() );
+                needRiseLabel = false;
+            } else
+                label = QString();
+            /* When the line is over day area, we set needRiseLabel to true, so, the next
+             * time the line pass over the night area, a label will be draw. */
+            if ( vRise.at(i).x() >= scUI->CalendarView->getRiseTime( i ) )
+                needRiseLabel = true;
+            // Add the current point to KPlotObject
+            oRise->addPoint( vRise.at(i), label );
+        } else {
             scUI->CalendarView->addPlotObject( oRise );
             oRise = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
-            scUI->CalendarView->update();
+            needRiseLabel = true;
         }
-        if ( i > 0 && fabs(vSet.at(i).x() - vSet.at(i-1).x()) > 6.0 ) {
+        
+        // Set
+        if ( vSet.at( i ).x() > -23.0 && vSet.at( i ).x() < 23.0) {
+            if ( i > 0 && fabs( vSet.at( i ).x() - vSet.at( i-1 ).x() ) > 6.0 ) {
+                scUI->CalendarView->addPlotObject( oSet );
+                oSet = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
+                needSetLabel = true;
+            }
+            if ( needSetLabel && vSet.at(i).x() > scUI->CalendarView->getSetTime( i ) && vSet.at(i).x() < scUI->CalendarView->getRiseTime( i ) ){
+                label = i18nc( "A planet sets from the horizon", "%1 sets", ksp->name() );
+                needSetLabel = false;
+            } else
+                label  = QString();
+            if ( vSet.at(i).x() <= scUI->CalendarView->getSetTime( i ) )
+                needSetLabel = true;
+            oSet->addPoint( vSet.at(i), label );
+        } else {
             scUI->CalendarView->addPlotObject( oSet );
             oSet = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
-            scUI->CalendarView->update();
+            needSetLabel = true;
         }
-        if ( i > 0 && fabs(vTransit.at(i).x() - vTransit.at(i-1).x()) > 6.0 ) {
+        
+        // Transit
+        if ( vTransit.at( i ).x() > -23.0 && vTransit.at( i ).x() < 23.0) {
+            if ( i > 0 && fabs( vTransit.at( i ).x() - vTransit.at( i-1 ).x() ) > 6.0 ) {
+                scUI->CalendarView->addPlotObject( oTransit );
+                oTransit = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
+                needTransertLabel = true;
+            }
+            if ( needTransertLabel && vTransit.at(i).x() > scUI->CalendarView->getSetTime( i ) && vTransit.at(i).x() < scUI->CalendarView->getRiseTime( i ) ) {
+                label = i18nc( "A planet transits across the meridian", "%1 transits", ksp->name() );
+                needTransertLabel = false;
+            } else
+                label = QString();
+            if ( vTransit.at(i).x() <= scUI->CalendarView->getSetTime( i ) || vTransit.at(i).x() >= scUI->CalendarView->getRiseTime( i ) )
+                needTransertLabel = true;
+            oTransit->addPoint( vTransit.at(i), label );
+        } else {
             scUI->CalendarView->addPlotObject( oTransit );
             oTransit = new KPlotObject( pColor, KPlotObject::Lines, 2.0 );
-            scUI->CalendarView->update();
+            needTransertLabel = true;
         }
-        
-        bool riseLabel    = isAxisCrossed(vRise,    i)  || isAtExtremum(vRise,    i);
-        bool transitLabel = isAxisCrossed(vTransit, i)  || isAtExtremum(vTransit, i);
-        bool setLabel     = isAxisCrossed(vSet,     i)  || isAtExtremum(vSet,     i);
-        oRise->addPoint(
-            vRise.at(i),
-            riseLabel ? i18nc( "A planet rises from the horizon", "%1 rises", ksp->name() ) : QString() );
-        oSet->addPoint(
-            vSet.at(i),
-            setLabel ? i18nc( "A planet sets from the horizon", "%1 sets", ksp->name() ) : QString() );
-        oTransit->addPoint(
-            vTransit.at(i),
-            transitLabel ? i18nc( "A planet transits across the meridian", "%1 transits", ksp->name() ) : QString() );
     }
     
+    // Add the last points
     scUI->CalendarView->addPlotObject( oRise );
     scUI->CalendarView->addPlotObject( oSet );
     scUI->CalendarView->addPlotObject( oTransit );



More information about the Kstars-devel mailing list