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

Jason Harris kstars at 30doradus.org
Mon Mar 13 06:22:12 CET 2006


SVN commit 518090 by harris:

Improved SkyMapComposite::objectNearest( SkyPoint *p, double &maxrad ) 
with some "fuzzy logic".  Instead of returning the object which is 
actually the nearest to point p, we now weight objects differently based 
on their type (on the theory that users are more likely to click on 
certain types of objects).

We determine the nearest object to point p in each category separately, 
and then, before comparing between categories to find the overall best 
match, the distance from p in each category is multiplied by the 
following factors:

Stars: 1.0 (i.e., no weighting)
IC objects: 0.8
NGC objects: 0.5
"other" catalog: 0.4
Messier objects: 0.25
custom catalogs: 0.2
solar system: 0.1

This just means that (for example) if a star and a comet are both within 
the nominal search radius from point p, then the star will only be 
selected if it is ten times closer to p than the comet (because the 
comet's distance is multiplied by 0.1).

It might sound odd, but it really works much better.  Give it a try, let 
me know if you have suggestions on the above weighting scheme.

CCMAIL: kstars-devel at kde.org



 M  +48 -15    skycomponents/deepskycomponent.cpp  
 M  +47 -0     skycomponents/skymapcomposite.cpp  
 M  +2 -0      skycomponents/skymapcomposite.h  
 M  +1 -1      skymapevents.cpp  


--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/deepskycomponent.cpp #518089:518090
@@ -324,42 +324,75 @@
 	return 0;
 }
 
+//we multiply each catalog's smallest angular distance by the 
+//following factors before selecting the final nearest object:
+// IC catalog = 0.8
+// NGC catalog = 0.5
+// "other" catalog = 0.4
+// Messier object = 0.25
 SkyObject* DeepSkyComponent::objectNearest( SkyPoint *p, double &maxrad ) {
+	SkyObject *oTry = 0;
 	SkyObject *oBest = 0;
+	double rTry = maxrad;
+	double rBest = maxrad;
 	double r;
 
-	foreach ( SkyObject *o, m_MessierList ) {
+	foreach ( SkyObject *o, m_ICList )  {
 		r = o->angularDistanceTo( p ).Degrees();
-		if ( r < maxrad ) {
-			maxrad = r;
-			oBest = o;
+		if ( r < rTry ) {
+			rTry = r;
+			oTry = o;
 		}
 	}
+	rTry *= 0.8;
+	if ( rTry < rBest ) {
+		rBest = rTry;
+		oBest = oTry;
+	}
 
+	rTry = maxrad;
 	foreach ( SkyObject *o, m_NGCList )  {
 		r = o->angularDistanceTo( p ).Degrees();
-		if ( r < maxrad ) {
-			maxrad = r;
-			oBest = o;
+		if ( r < rTry ) {
+			rTry = r;
+			oTry = o;
 		}
 	}
+	rTry *= 0.5;
+	if ( rTry < rBest ) {
+		rBest = rTry;
+		oBest = oTry;
+	}
 
-	foreach ( SkyObject *o, m_ICList )  {
+	rTry = maxrad;
+	foreach ( SkyObject *o, m_OtherList )  {
 		r = o->angularDistanceTo( p ).Degrees();
-		if ( r < maxrad ) {
-			maxrad = r;
-			oBest = o;
+		if ( r < rTry ) {
+			rTry = r;
+			oTry = o;
 		}
 	}
+	rTry *= 0.4;
+	if ( rTry < rBest ) {
+		rBest = rTry;
+		oBest = oTry;
+	}
 
-	foreach ( SkyObject *o, m_OtherList )  {
+	rTry = maxrad;
+	foreach ( SkyObject *o, m_MessierList ) {
 		r = o->angularDistanceTo( p ).Degrees();
-		if ( r < maxrad ) {
-			maxrad = r;
-			oBest = o;
+		if ( r < rTry ) {
+			rTry = r;
+			oTry = o;
 		}
 	}
+	rTry *= 0.25;
+	if ( rTry < rBest ) {
+		rBest = rTry;
+		oBest = oTry;
+	}
 
+	maxrad = rBest;
 	return oBest;
 }
 
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/skymapcomposite.cpp #518089:518090
@@ -136,6 +136,53 @@
 
 }
 
+//Select nearest object to the given skypoint, but give preference 
+//to certain object types.
+//we multiply each object type's smallest angular distance by the 
+//following factors before selecting the final nearest object:
+// stars = 1.0 (not weighted)
+// IC catalog = 0.8
+// NGC catalog = 0.5
+// "other" catalog = 0.4
+// Messier object = 0.25
+// custom object = 0.2
+// Solar system = 0.1
+SkyObject* SkyMapComposite::objectNearest( SkyPoint *p, double &maxrad ) {
+	double rTry = maxrad;
+	double rBest = maxrad;
+	SkyObject *oTry = 0;
+	SkyObject *oBest = 0;
+
+	oBest = m_Stars->objectNearest( p, rBest );
+	//m_DeepSky internally discriminates among deepsky catalogs
+	//and remormalizes rTry
+	oTry = m_DeepSky->objectNearest( p, rTry ); 
+	if ( rTry < rBest ) {
+		rBest = rTry;
+		oBest = oTry;
+	}
+
+	rTry = maxrad;
+	oTry = m_CustomCatalogs->objectNearest( p, rTry );
+	rTry *= 0.2;
+	if ( rTry < rBest ) {
+		rBest = rTry;
+		oBest = oTry;
+	}
+
+	rTry = maxrad;
+	oTry = m_SolarSystem->objectNearest( p, rTry );
+	rTry *= 0.1;
+	if ( rTry < rBest ) {
+		rBest = rTry;
+		oBest = oTry;
+	}
+
+	maxrad = rBest;
+	return oBest; //will be 0 if no object nearer than maxrad was found
+
+}
+
 bool SkyMapComposite::addNameLabel( SkyObject *o ) {
 	if ( !o ) return false;
 	labelObjects().append( o );
--- trunk/KDE/kdeedu/kstars/kstars/skycomponents/skymapcomposite.h #518089:518090
@@ -116,6 +116,8 @@
 			*/
 		virtual void draw(KStars *ks, QPainter& psky, double scale = 1.0);
 
+		virtual SkyObject* objectNearest( SkyPoint *p, double &maxrad );
+
 		/**
 			*@short Add a Trail to the specified SkyObject
 			*Loop over all child SkyComponents; if the SkyObject
--- trunk/KDE/kdeedu/kstars/kstars/skymapevents.cpp #518089:518090
@@ -675,7 +675,7 @@
 		setClickedPoint( mousePoint() );
 
 		//Find object nearest to clickedPoint()
-		double maxrad = 200.0/Options::zoomFactor();
+		double maxrad = 1000.0/Options::zoomFactor();
 		setClickedObject( data->skyComposite()->objectNearest( clickedPoint(), maxrad ) );
 
 		if ( clickedObject() ) {


More information about the Kstars-devel mailing list