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

James Bowlin bowlin at mindspring.com
Wed Sep 5 00:26:35 CEST 2007


SVN commit 708436 by jbowlin:

Made a bool SkyMap:onscreenLine2() routine that uses the return value
to flag if a line is entirely offscreen instead of changing the values
of the points.

Fixed a minor bug in onscreenLine2() where a line would disappear if
one endpoint of the line was barely offscreen.  This bug probably
still exists in onscreenLine().

Varied the point density of the coordinate grid lines of constant
declination so the lines near the poles have fewer points.

CCMAIL: kstars-devel at kde.org


 M  +11 -4     skycomponents/coordinategrid.cpp  
 M  +2 -3      skycomponents/linelistindex.cpp  
 M  +112 -0    skymap.cpp  
 M  +2 -0      skymap.h  


--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/coordinategrid.cpp #708435:708436
@@ -26,6 +26,7 @@
 #include "skymap.h"
 #include "coordinategrid.h"
 #include "linelist.h"
+#include "dms.h"
 
 CoordinateGrid::CoordinateGrid( SkyComponent *parent ) 
 	: NoPrecessIndex(parent, i18n("Coordinate Grid") ) 
@@ -58,7 +59,7 @@
     double maxDec =  90.0;
     double dDec   =  20.0;
     double dDec2  =   4.0;
-    double dRa2   =  2. / 5.;
+    double dRa2   =   0.2;
 
     double max, dec, dec2, ra, ra2;
 
@@ -76,18 +77,24 @@
                 p->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
                 lineList->append( p );
             }
-
             appendLine( lineList );
             //printf("\n");
         }
     }
 
     for ( dec = minDec; dec < maxDec + eps; dec += dDec ) {
+
+		// Adjust point density 
+		int nPoints = int(round( fabs(cos(dec* dms::PI / 180.0)) * dRa / dRa2 )); 
+		if ( nPoints < 5 ) nPoints = 5;
+		double dRa3 = dRa / nPoints;
+		//printf( "npoints = %d\n", nPoints);
+
         for ( ra = minRa; ra < maxRa + eps; ra += dRa ) {
            lineList = new LineList();
            //printf("%6.2f: ", dec);
-           for ( ra2 = ra; ra2 <= ra + dRa + eps; ra2 += dRa2 ) {
-                //printf("%4d %6.2f ", components().size(), ra2);
+           for ( ra2 = ra; ra2 <= ra + dRa + eps; ra2 += dRa3 ) {
+                //printf("%4d %6.2f ", components().size(), ra3);
                 SkyPoint* p = new SkyPoint( ra2, dec );
                 p->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
                 lineList->append( p );
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/linelistindex.cpp #708435:708436
@@ -269,11 +269,10 @@
                 if ( map->onScreen( oThis, oLast) && ! skipAt( lineList, i ) ) {
 
                     if ( isVisible && isVisibleLast ) {
-						map->onscreenLine( oLast, oThis );
-                        if ( ! map->isPointNull( oLast ) && 
-								! map->isPointNull( oThis ) ) {
+						if ( map->onscreenLine2( oLast, oThis ) ) {
                             psky.drawLine( oLast, oThis );
                             updateLabelCandidates( oThis, lineList, i );
+							//psky.drawEllipse( QRectF( oThis.x(), oThis.y(), 2, 2 ) );
                         }
                     }
                     else if ( isVisibleLast ) {
--- trunk/KDE/kdeedu/kstars/kstars/skymap.cpp #708435:708436
@@ -1041,6 +1041,118 @@
 	return screenLine;
 }
 
+bool SkyMap::onscreenLine2( QPointF &p1, QPointF &p2 ) {
+	//If the SkyMap rect contains both points or either point is null, 
+	//we can return immediately
+	bool on1 = rect().contains( p1.toPoint() );
+	bool on2 = rect().contains( p2.toPoint() );
+	if ( on1 && on2 )
+		return true;
+
+	//Given two points defining a line segment, determine the 
+	//endpoints of the segment which is clipped by the boundaries 
+	//of the SkyMap QRectF.
+	QLineF screenLine( p1, p2 );
+
+	//Define screen edges to be just beyond the rect() bounds, so that clipped 
+	//positions are considered "offscreen"
+	QPoint topLeft( rect().left()-1, rect().top()-1 );
+	QPoint bottomLeft( rect().left()-1, rect().top() + height()+1 );
+	QPoint topRight( rect().left() + rect().width()+1, rect().top()-1 );
+	QPoint bottomRight( rect().left() + rect().width()+1, rect().top() + height()+1 );
+	QLine topEdge( topLeft, topRight );
+	QLine bottomEdge( bottomLeft, bottomRight );
+	QLine leftEdge( topLeft, bottomLeft );
+	QLine rightEdge( topRight, bottomRight );
+
+	QPointF edgePoint1;
+	QPointF edgePoint2;
+
+	//If both points are offscreen in the same direction, return a null point.
+	if ( ( p1.x() <= topLeft.x()    && p2.x() <= topLeft.x() ) ||
+		 ( p1.y() <= topLeft.y()    && p2.y() <= topLeft.y() ) ||
+		 ( p1.x() >= topRight.x()   && p2.x() >= topRight.x() ) ||
+		 ( p1.y() >= bottomLeft.y() && p2.y() >= bottomLeft.y() ) ) {
+		return false;
+	}
+
+	//When an intersection betwen the line and a screen edge is found, the 
+	//intersection point is stored in edgePoint2.
+	//If two intersection points are found for the same line, then we'll 
+	//return the line joining those two intersection points.
+	if ( screenLine.intersect( QLineF(topEdge), &edgePoint1 ) == 1 ) {
+		edgePoint2 = edgePoint1;
+	}
+
+	if ( screenLine.intersect( QLineF(leftEdge), &edgePoint1 ) == 1 ) {
+		if ( edgePoint2.isNull() ) 
+			edgePoint2 = edgePoint1;
+		else {
+			//Two intersection points found.  Return this line segment
+			//First make sure that edgePoint1 corresponds to p1
+			if ( p1.x() < p2.x() == edgePoint1.x() < edgePoint2.x() ) {
+				p1 = edgePoint1;
+				p2 = edgePoint2;
+			} else {
+				p1 = edgePoint2;
+				p2 = edgePoint1;
+			}
+			return true;
+		}
+	}
+
+	if ( screenLine.intersect( QLineF(rightEdge), &edgePoint1 ) == 1 ) {
+		if ( edgePoint2.isNull() ) 
+			edgePoint2 = edgePoint1;
+		else {
+			//Two intersection points found.  Return this line segment
+			//First make sure that edgePoint1 corresponds to p1
+			if ( p1.x() < p2.x() == edgePoint1.x() < edgePoint2.x() ) {
+				p1 = edgePoint1;
+				p2 = edgePoint2;
+			} else {
+				p1 = edgePoint2;
+				p2 = edgePoint1;
+			}
+			return true;
+		}
+	}
+	if ( screenLine.intersect( QLineF(bottomEdge), &edgePoint1 ) == 1 ) {
+		if ( edgePoint2.isNull() ) 
+			edgePoint2 = edgePoint1;
+		else {
+			//Two intersection points found.  Return this line segment
+			//First make sure that edgePoint1 corresponds to p1
+			if ( p1.x() < p2.x() == edgePoint1.x() < edgePoint2.x() ) {
+				p1 = edgePoint1;
+				p2 = edgePoint2;
+			} else {
+				p1 = edgePoint2;
+				p2 = edgePoint1;
+			}
+			return true;
+		}
+	}
+	//If we get here, zero or one intersection point was found.
+	//If no intersection points were found, the line must be totally offscreen
+	//return a null point
+	if ( edgePoint2.isNull() ) {
+		return true;
+	}
+
+	//If one intersection point was found, then one of the original endpoints
+	//was onscreen.  Return the line that connects this point to the edgePoint
+
+	//edgePoint2 is the one defined edgePoint.
+	if ( on2 ) 
+		p1 = edgePoint2;
+	else 
+		p2 = edgePoint2;
+
+	return true;
+}
+
+
 void SkyMap::onscreenLine( QPointF &p1, QPointF &p2 ) {
 	//If the SkyMap rect contains both points or either point is null, 
 	//we can return immediately
--- trunk/KDE/kdeedu/kstars/kstars/skymap.h #708435:708436
@@ -447,6 +447,8 @@
 
 	void onscreenLine( QPointF &p1, QPointF &p2 );
 
+	bool onscreenLine2( QPointF &p1, QPointF &p2 );
+
 /**Determine RA, Dec coordinates of the pixel at (dx, dy), which are the
 	*screen pixel coordinate offsets from the center of the Sky pixmap.
 	*@param dx horizontal pixel offset from center of SkyMap.


More information about the Kstars-devel mailing list