[Kstars-devel] KDE/kdeedu/kstars/kstars

Jason Harris kstars at 30doradus.org
Tue Apr 17 05:57:59 CEST 2007


SVN commit 654832 by harris:

Adding tickmarks and time labels to satellite tracks...looks really cool!

CCMAIL: kstars-devel at kde.org



 M  +91 -2     skycomponents/satellitecomponent.cpp  
 M  +5 -0      skycomponents/satellitecomponent.h  
 M  +3 -23     skycomponents/satellitecomposite.cpp  
 M  +2 -1      skycomponents/satellitecomposite.h  
 M  +32 -0     skyline.cpp  
 M  +9 -0      skyline.h  


--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/satellitecomponent.cpp #654831:654832
@@ -16,10 +16,14 @@
  ***************************************************************************/
 
 #include <QBrush>
+#include <QPainter>
 
+#include "kstars.h"
 #include "kstarsdata.h"
+#include "skymap.h"
 #include "skyline.h"
 #include "satellitecomponent.h"
+#include "Options.h"
 
 SatelliteComponent::SatelliteComponent(SkyComponent *parent, bool (*visibleMethod)())
 : LineListComponent(parent, visibleMethod)
@@ -36,18 +40,103 @@
 	setLabelPosition( LineListComponent::RightEdgeLabel );
 
 	setPen( QPen( QBrush( data->colorScheme()->colorNamed( "SatColor" ) ), 
-										 1, Qt::SolidLine ) );
+										 2.5, Qt::SolidLine ) );
 
 	p2.setAlt( pSat[0]->sat_ele );
 	p2.setAz( pSat[0]->sat_azi );
 	p2.HorizontalToEquatorial( data->lst(), data->geo()->lat() );
 
-	for ( int i=1; i<npos; i++ ) {
+	for ( uint i=1; i<npos; i++ ) {
 		p1 = p2;
 		p2.setAlt( pSat[i]->sat_ele );
 		p2.setAz( pSat[i]->sat_azi );
 		p2.HorizontalToEquatorial( data->lst(), data->geo()->lat() );
 
 		lineList().append( new SkyLine( p1, p2 ) );
+		jdList().append( pSat[i]->jd );
+
 	}
 }
+
+void SatelliteComponent::draw( KStars *ks, QPainter &psky, double scale ) {
+	LineListComponent::draw( ks, psky, scale );
+
+	if ( jdList().size() == 0 ) return;
+
+	//Add tickmarks and timestamps along the portion of the 
+	//satellite track that is above the horizon
+	//The time at each position is stored in the pSat array 
+	//as the julian day.  Parse these days, and interpolate to find 
+	//times with :00 seconds (e.g., 12:34:00)
+	KStarsDateTime dtLast( jdList()[0] );
+	for ( uint i=1; i<jdList().size(); ++i ) {
+		KStarsDateTime dt( jdList()[i] );
+		SkyLine *sl = lineList()[i];
+		SkyLine *sl2;
+		if ( i<lineList().size()-1 )
+			sl2 = lineList()[i+1];
+		else
+			sl2 = lineList()[i-1];
+
+		if ( sl->startPoint()->alt()->Degrees() > 0.0 
+				 && dt.time().minute() != dtLast.time().minute() ) {
+			double t1 = double(dtLast.time().second());
+			double t2 = double(dt.time().second()) + 60.0;
+			double f = ( 60.0 - t1 )/( t2 - t1 );
+
+			//Create a SkyLine which is a tickmark at the position along 
+			//the track corresponding to the even-second time.
+			//f is the fractional distance between the endpoints.
+			SkyLine *sl = lineList()[i];
+			double ra = f*sl->endPoint()->ra()->Hours() 
+				+ (1.0-f)*sl->startPoint()->ra()->Hours();
+			double dc = f*sl->endPoint()->dec()->Degrees() 
+				+ (1.0-f)*sl->startPoint()->dec()->Degrees();
+			SkyPoint sp(ra, dc);
+			SkyLine satTick( &sp, sl2->endPoint() );
+
+			//satTick is a skyline that starts at the tick position,
+			//and is parallel to the satellite track.  We want to change 
+			//the endpoint so it's perpendicular to the track, and 
+			//change its length to be a few pixels
+//			satTick.rotate( 90.0 );
+			satTick.setAngularSize( 300/Options::zoomFactor() );
+			satTick.startPoint()->EquatorialToHorizontal( ks->data()->lst(), ks->data()->geo()->lat() );
+			satTick.endPoint()->EquatorialToHorizontal( ks->data()->lst(), ks->data()->geo()->lat() );
+
+			QLineF tick = ks->map()->toScreen( &satTick, scale );
+			double labelpa = atan2( tick.dy(), tick.dx() )/dms::DegToRad;
+			QLineF tick2 = tick.normalVector();
+			if ( tick2.y2() < tick2.y1() ) {
+				//Rotate tick by 180 degrees
+				double x1 = tick2.x1();
+				double y1 = tick2.y1();
+				tick2 = QLineF( x1, y1, x1 - tick2.dx(), y1 - tick2.dy() );
+			}
+			psky.drawLine( tick2 );
+
+			//Now, add a label to the tickmark showing the time
+			if ( labelpa > 270.0 ) labelpa -= 360.0;
+			else if ( labelpa > 90.0 ) labelpa -= 180.0;
+			else if ( labelpa < -270.0 ) labelpa += 360.0;
+			else if ( labelpa < -90.0  ) labelpa += 180.0;
+
+			QTime tlabel = dt.time().addSecs( 3600.0*ks->data()->geo()->TZ() );
+			psky.save();
+			QFont stdFont( psky.font() );
+			QFont smallFont( stdFont );
+			smallFont.setPointSize( stdFont.pointSize() - 2 );
+			psky.setFont( smallFont );
+			psky.translate( tick.p2() );
+			psky.rotate( labelpa );
+			psky.drawText( QRectF(-25.0, 6.0, 40.0, 10.0), Qt::AlignCenter, 
+										 tlabel.toString( "hh:mm" ) );
+			psky.restore();
+			psky.setFont( stdFont );
+		}
+
+		dtLast = dt;
+	}
+
+}
+	
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/satellitecomponent.h #654831:654832
@@ -43,9 +43,14 @@
 		*/
 		void init(const QString &name, KStarsData *data, SPositionSat *pSat[], int nsteps);
 
+		void draw( KStars *ks, QPainter &psky, double scale );
+
+		QList<double>& jdList() { return JDList; }
+
 	private:
 		QStringList SatelliteNames;
 		long double JulianDate;
+		QList<double> JDList;
 };
 
 #endif
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/satellitecomposite.cpp #654831:654832
@@ -67,35 +67,24 @@
 		
 		//Julian Day value for current date and time:
 		JD_0 = data->ut().djd();
-		double dt = 10.; //10-sec time steps 
 
 		//Loop over desired satellites, construct their paths over the next hour, 
 		//and add visible paths to the list
 		foreach ( const QString &satName, SatelliteNames ) {
 			emitProgressText( i18n("Creating satellite: %1", satName ) );
 
-			SatFindPosition( satName.toAscii().data(), JD_0, dt, NSTEPS, pSat.data() );
+			SatFindPosition( satName.toAscii().data(), JD_0, DT, NSTEPS, pSat.data() );
 		
 			//Make sure the satellite track is visible before adding it to the list.
 			bool isVisible = false;
 			for ( int i=0; i<NSTEPS; i++ ) {
-				//DEBUG
-				if ( satName == "HST" ) 
-					kDebug() << "HST alt: " << pSat[i]->sat_ele << "  az: " << pSat[i]->sat_azi << endl;
-
 				if ( pSat[i]->sat_ele > 10.0 ) { 
 					isVisible = true;
 					break;
 				}
 			}
 		
-			//DEBUG
-			kDebug() << satName << endl;
-
 			if ( isVisible ) {
-				//DEBUG
-				kDebug() << satName << " is visible!  Adding it to the display." << endl;
-
 				SatelliteComponent *sc = new SatelliteComponent( this, Options::showSatellites );
 				sc->init( satName, data, pSat.data(), NSTEPS );
 				addComponent( sc );
@@ -106,12 +95,8 @@
 }
 
 void SatelliteComposite::update( KStarsData *data, KSNumbers * ) {
-	//DEBUG
-	kDebug() << k_funcinfo << endl;
-
 	//Julian Day value for current date and time:
 	JD_0 = data->ut().djd();
-	double dt = 10.; //10-sec time steps 
 
 	//Clear the current list of tracks
 	components().clear();
@@ -119,15 +104,11 @@
 	//Loop over desired satellites, construct their paths over the next hour, 
 	//and add visible paths to the list
 	foreach ( const QString &satName, SatelliteNames ) {
-		SatFindPosition( satName.toAscii().data(), JD_0, dt, NSTEPS, pSat.data() );
-	
+		SatFindPosition( satName.toAscii().data(), JD_0, DT, NSTEPS, pSat.data() );
+
 		//Make sure the satellite track is visible before adding it to the list.
 		bool isVisible = false;
 		for ( int i=0; i<NSTEPS; i++ ) {
-			//DEBUG
-			if ( satName == "HST" ) 
-				kDebug() << "HST alt: " << pSat[i]->sat_ele << "  az: " << pSat[i]->sat_azi << endl;
-
 			if ( pSat[i]->sat_ele > 10.0 ) { 
 				isVisible = true;
 				break;
@@ -138,7 +119,6 @@
 			SatelliteComponent *sc = new SatelliteComponent( this, Options::showSatellites );
 			sc->init( satName, data, pSat.data(), NSTEPS );
 			addComponent( sc );
-			
 		}
 	}
 }
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/satellitecomposite.h #654831:654832
@@ -25,7 +25,8 @@
 #include "satlib/SatLib.h"
 }
 
-#define NSTEPS 360
+#define DT 10.0    //10-sec timesteps
+#define NSTEPS 360 //360 steps == 1 hour of coverage
 
 class KStarsData;
 
--- trunk/KDE/kdeedu/kstars/kstars/skyline.cpp #654831:654832
@@ -37,6 +37,38 @@
 	return angDist;
 }
 
+void SkyLine::setAngularSize( double size ) {
+	double pa=positionAngle().radians();
+
+	double x = (startPoint()->ra()->Degrees()  + size*cos(pa))/15.0;
+	double y = startPoint()->dec()->Degrees() - size*sin(pa);
+	
+	setEndPoint( SkyPoint( x, y ) );
+}
+
+dms SkyLine::positionAngle() {
+	double dx = startPoint()->ra()->radians() - endPoint()->ra()->radians();
+	double dy = endPoint()->dec()->radians() - startPoint()->dec()->radians();
+	
+	return dms( atan2( dy, dx )/dms::DegToRad ); 
+}
+
+void SkyLine::rotate( const dms &angle ) {
+	double dx = endPoint()->ra()->Degrees()  - startPoint()->ra()->Degrees();
+	double dy = endPoint()->dec()->Degrees() - startPoint()->dec()->Degrees();
+
+	double s, c;
+	angle.SinCos( s, c );
+
+	double dx0 = dx*c - dy*s;
+	double dy0 = dx*s + dy*c;
+
+	double x = (startPoint()->ra()->Degrees() + dx0)/15.0;
+	double y = startPoint()->dec()->Degrees() + dy0;
+
+	setEndPoint( SkyPoint( x, y ) );
+}
+
 void SkyLine::update( KStarsData *d, KSNumbers *num ) {
 	if ( num ) {
 		startPoint()->updateCoords( num );
--- trunk/KDE/kdeedu/kstars/kstars/skyline.h #654831:654832
@@ -92,6 +92,15 @@
 			*/
 		dms angularSize();
 
+		void setAngularSize( double size );
+
+		/**
+			*@return the SkyLine's position angle on the sky
+			*/
+		dms positionAngle();
+
+		void rotate( const dms &angle );
+
 		void update( KStarsData *data, KSNumbers *num=0 );
 
 	private:


More information about the Kstars-devel mailing list