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

Jason Harris kstars at 30doradus.org
Fri Mar 10 15:15:42 CET 2006


SVN commit 517267 by harris:

Fixing crash at high zoom levels, which was related to the Horizon.
Made HorizonComponent::draw() more efficient; it does more intelligent 
things when horizon is offscreen.

I now believe you can't crash KStars unless you open a tool or other 
dialog window (although some work, like Find Object and 
Details)...please prove me wrong :)

CCMAIL: kstars-devel at kde.org



 M  +78 -29    horizoncomponent.cpp  


--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/horizoncomponent.cpp #517266:517267
@@ -55,7 +55,7 @@
 	}
 }
 
-void HorizonComponent::update( KStarsData *data, KSNumbers *num ) {
+void HorizonComponent::update( KStarsData *data, KSNumbers * ) {
 	if ( visible() ) {
 		foreach ( SkyPoint *p, pointList() ) {
 			p->HorizontalToEquatorial( data->lst(), data->geo()->lat() );
@@ -75,7 +75,7 @@
 	float Width = scale * map->width();
 	float Height = scale * map->height();
 	QPolygonF groundPoly;
-	SkyPoint *pAnchor, *pAnchor2;
+	SkyPoint *pAnchor(0), *pAnchor2(0);
 
 	psky.setPen( QPen( QColor( ks->data()->colorScheme()->colorNamed( "HorzColor" ) ), 1, Qt::SolidLine ) );
 
@@ -84,16 +84,29 @@
 	else
 		psky.setBrush( Qt::NoBrush );
 	
-	double az1 = map->focus()->az()->Degrees() - 90.;
-	double az2 = map->focus()->az()->Degrees() + 90.;
+	double daz = 0.5*Width*57.3/Options::zoomFactor(); //center to edge, in degrees
+	if ( daz > 90.0 ) daz = 90.0;
+	double az1 = map->focus()->az()->Degrees() - daz;
+	double az2 = map->focus()->az()->Degrees() + daz;
 
 	QPointF o;
+	bool allGround(true);
+	bool allSky(true);
+
 	//Add points on the left that may be slightly West of North
 	if ( az1 < 0. ) {
 		az1 += 360.;
 		foreach ( SkyPoint *p, pointList() ) {
-			if ( p->az()->Degrees() > az1 ) 
+			if ( p->az()->Degrees() > az1 ) {
 				groundPoly << map->getXY( p, Options::useAltAz(), false, scale );
+
+				//Set the anchor point if this point is onscreen
+				if ( o.x() < Width && o.y() > 0. && o.y() < Height ) 
+					pAnchor = p;
+
+				if ( o.y() > 0. ) allGround = false;
+				if ( o.y() < Height && o.y() > 0. ) allSky = false;
+			}
 		}
 		az1 = 0.0;
 	}
@@ -107,6 +120,9 @@
 			//Set the anchor point if this point is onscreen
 			if ( o.x() < Width && o.y() > 0. && o.y() < Height ) 
 				pAnchor = p;
+
+			if ( o.y() > 0. ) allGround = false;
+			if ( o.y() < Height && o.y() > 0. ) allSky = false;
 		} else if ( p->az()->Degrees() > az2 )
 			break;
 	}
@@ -122,44 +138,71 @@
 				//Set the anchor point if this point is onscreen
 				if ( o.x() < Width && o.y() > 0. && o.y() < Height ) 
 					pAnchor = p;
+
+				if ( o.y() > 0. ) allGround = false;
+				if ( o.y() < Height && o.y() > 0. ) allSky = false;
 			} else
 				break;
 		}
 	}
 
+	if ( allSky ) return; //no horizon onscreen
+
+	if ( allGround ) { 
+		//Ground fills the screen.  Reset groundPoly to surround screen perimeter
+		groundPoly.clear();
+		groundPoly << QPointF( -10., -10. ) 
+					<< QPointF( Width + 10., -10. )
+					<< QPointF( Width + 10., Height + 10. )
+					<< QPointF( -10., Height + 10. );
+
+		//Just draw the poly (in case ground is filled)
+		//No need for compass labels or "Horizon" label
+		psky.drawPolygon( groundPoly );
+		return;
+	}
+
 	//groundPoly now contains QPointF's of the screen coordinates of points 
 	//along the "front half" of the Horizon, in order from left to right.
-	//Now we need to complete the ground polygon by going right to left along 
-	//the bottom edge of the visible sky circle.  The visible sky circle has 
+	//Now we need to complete the ground polygon by going right to left.
+	//If the zoomLevel is high (as indicated by (daz<75.0)), then we 
+	//complete the polygon by simply adding points along thebottom edge 
+	//of the screen.  If the zoomLevel is high (daz>75.0), then we add points 
+	//along the bottom edge of the sky circle.  The sky circle has 
 	//a radius of 2*sin(pi/4)*ZoomFactor, and the endpoints of the current 
 	//groundPoly points lie 180 degrees apart along its circumference.  
 	//We determine the polar angles t1, t2 corresponding to these end points, 
 	//and then step along the circumference, adding points between them.
 	//(In Horizontal coordinates, t1 and t2 are always 360 and 180, respectively).
-	double r0 = 2.0*sin(0.25*dms::PI);
-	double t1 = 360.;
-	double t2 = 180.;
-	if ( ! Options::useAltAz() ) { //compute t1,t2
-		//groundPoly.last() is the point on the Horizon that intersects 
-		//the visible sky circle on the right
-		t1 = -1.0*acos( (groundPoly.last().x() - 0.5*Width)/r0/Options::zoomFactor() )/dms::DegToRad; //angle in degrees
-		//Resolve quadrant ambiguity
-		if ( groundPoly.last().y() < 0. ) t1 = 360. - t1;
+	if ( daz < 75.0 ) { //complete polygon with offscreen points
+		groundPoly << QPointF( Width + 10., groundPoly.last().y() )
+					<< QPointF( Width + 10., Height + 10. )
+					<< QPointF( -10., Height + 10. )
+					<< QPointF( -10., groundPoly.first().y() );
 
-		t2 = t1 - 180.;
-	}
+	} else { //complete polygon along bottom of sky circle
+		double r0 = 2.0*sin(0.25*dms::PI);
+		double t1 = 360.;
+		double t2 = 180.;
+		if ( ! Options::useAltAz() ) { //compute t1,t2
+			//groundPoly.last() is the point on the Horizon that intersects 
+			//the visible sky circle on the right
+			t1 = -1.0*acos( (groundPoly.last().x() - 0.5*Width)/r0/Options::zoomFactor() )/dms::DegToRad; //angle in degrees
+			//Resolve quadrant ambiguity
+			if ( groundPoly.last().y() < 0. ) t1 = 360. - t1;
+	
+			t2 = t1 - 180.;
+		}
 
-// 	//DEBUG
-// 	kDebug() << "groundPoly last x: " << groundPoly.last().x() << " : " << r0*Options::zoomFactor() << endl;
-
-	for ( double t=t1; t >= t2; t-=2. ) {  //step along circumference
-		dms a( t );
-		double sa(0.), ca(0.);
-		a.SinCos( sa, ca );
-		float xx = 0.5*Width  + r0*Options::zoomFactor()*ca;
-		float yy = 0.5*Height - r0*Options::zoomFactor()*sa;
-
-		groundPoly << QPointF( xx, yy );
+		for ( double t=t1; t >= t2; t-=2. ) {  //step along circumference
+			dms a( t );
+			double sa(0.), ca(0.);
+			a.SinCos( sa, ca );
+			float xx = 0.5*Width  + r0*Options::zoomFactor()*ca;
+			float yy = 0.5*Height - r0*Options::zoomFactor()*sa;
+	
+			groundPoly << QPointF( xx, yy );
+		}
 	}
 
 	//Finally, draw the ground Polygon.
@@ -169,6 +212,12 @@
 
 	//--- Horizon name label
 
+	//DEBUG
+	if ( ! pAnchor ) {
+		kDebug() << k_funcinfo << ": pAnchor is undefined." << endl;
+		return;
+	}
+
 	//pAnchor contains the last point of the Horizon before it went offcreen 
 	//on the right/top/bottom edge.  oAnchor2 is the next point after oAnchor.
 	int iAnchor = pointList().indexOf( pAnchor );


More information about the Kstars-devel mailing list