Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

starbrowser.cpp

Go to the documentation of this file.
00001 // starbrowser.cpp
00002 // 
00003 // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
00004 //
00005 // Star browser tool for Celestia.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 
00012 #include <string>
00013 #include <algorithm>
00014 #include <set>
00015 #include "starbrowser.h"
00016 
00017 using namespace std;
00018 
00019 
00020 // TODO: More of the functions in this module should be converted to
00021 // methods of the StarBrowser class.
00022 
00023 struct CloserStarPredicate
00024 {
00025     Point3f pos;
00026     bool operator()(const Star* star0, const Star* star1) const
00027     {
00028         Point3f p0 = star0->getPosition();
00029         Point3f p1 = star1->getPosition();
00030         Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
00031         Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
00032         
00033         return (v0.lengthSquared() < v1.lengthSquared());                               
00034     }
00035 };
00036 
00037 
00038 struct BrighterStarPredicate
00039 {
00040     Point3f pos;
00041     UniversalCoord ucPos;
00042     bool operator()(const Star* star0, const Star* star1) const
00043     {
00044         Point3f p0 = star0->getPosition();
00045         Point3f p1 = star1->getPosition();
00046         Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
00047         Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
00048         float d0 = v0.length();
00049         float d1 = v1.length();
00050 
00051         return (star0->getApparentMagnitude(d0) <
00052                 star1->getApparentMagnitude(d1));
00053     }
00054 };
00055 
00056 
00057 struct BrightestStarPredicate
00058 {
00059     bool operator()(const Star* star0, const Star* star1) const
00060     {
00061         return (star0->getAbsoluteMagnitude() <
00062                 star1->getAbsoluteMagnitude());
00063     }
00064 };
00065 
00066 
00067 struct SolarSystemPredicate
00068 {
00069     Point3f pos;
00070     SolarSystemCatalog* solarSystems;
00071 
00072     bool operator()(const Star* star0, const Star* star1) const
00073     {
00074         SolarSystemCatalog::iterator iter;
00075 
00076         iter = solarSystems->find(star0->getCatalogNumber());
00077         bool hasPlanets0 = (iter != solarSystems->end());
00078         iter = solarSystems->find(star1->getCatalogNumber());
00079         bool hasPlanets1 = (iter != solarSystems->end());
00080         if (hasPlanets1 == hasPlanets0)
00081         {
00082             Point3f p0 = star0->getPosition();
00083             Point3f p1 = star1->getPosition();
00084             Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
00085             Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
00086             return (v0.lengthSquared() < v1.lengthSquared());
00087         }
00088         else
00089         {
00090             return hasPlanets0;
00091         }
00092     }
00093 };
00094 
00095 
00096 // Find the nearest/brightest/X-est N stars in a database.  The
00097 // supplied predicate determines which of two stars is a better match.
00098 template<class Pred> static std::vector<const Star*>*
00099 findStars(const StarDatabase& stardb, Pred pred, int nStars)
00100 {
00101     std::vector<const Star*>* finalStars = new std::vector<const Star*>();
00102     if (nStars == 0)
00103         return finalStars;
00104     if(nStars > 500)
00105         nStars = 500;
00106 
00107     typedef std::multiset<const Star*, Pred> StarSet;
00108     StarSet firstStars(pred);
00109 
00110     int totalStars = stardb.size();
00111     if (totalStars < nStars)
00112         nStars = totalStars;
00113 
00114     // We'll need at least nStars in the set, so first fill
00115     // up the list indiscriminately.
00116     int i = 0;
00117     for (i = 0; i < nStars; i++)
00118         firstStars.insert(stardb.getStar(i));
00119 
00120     // From here on, only add a star to the set if it's
00121     // a better match than the worst matching star already
00122     // in the set.
00123     const Star* lastStar = *--firstStars.end();
00124     for (; i < totalStars; i++)
00125     {
00126         Star* star = stardb.getStar(i);
00127         if (pred(star, lastStar))
00128         {
00129             firstStars.insert(star);
00130             firstStars.erase(--firstStars.end());
00131             lastStar = *--firstStars.end();
00132         }
00133     }
00134 
00135     // Move the best matching stars into the vector
00136     finalStars->reserve(nStars);
00137     for (typename StarSet::const_iterator iter = firstStars.begin();
00138          iter != firstStars.end(); iter++)
00139     {
00140         finalStars->insert(finalStars->end(), *iter);
00141     }
00142 
00143     return finalStars;
00144 }
00145 
00146 
00147 const Star* StarBrowser::nearestStar()
00148 {
00149     Universe* univ = appSim->getUniverse();
00150     CloserStarPredicate closerPred;
00151     closerPred.pos = pos;
00152     std::vector<const Star*>* stars = findStars(*(univ->getStarCatalog()), closerPred, 1);
00153     const Star *star = (*stars)[0];
00154     delete stars;
00155     return star;
00156 }
00157 
00158 
00159 std::vector<const Star*>*
00160 StarBrowser::listStars(unsigned int nStars)
00161 {
00162     Universe* univ = appSim->getUniverse();
00163     switch(predicate)
00164     {
00165     case BrighterStars:
00166         {
00167             BrighterStarPredicate brighterPred;
00168             brighterPred.pos = pos;
00169             brighterPred.ucPos = ucPos;
00170             return findStars(*(univ->getStarCatalog()), brighterPred, nStars);
00171         }
00172         break;
00173 
00174     case BrightestStars:
00175         {
00176             BrightestStarPredicate brightestPred;
00177             return findStars(*(univ->getStarCatalog()), brightestPred, nStars);
00178         }
00179         break;
00180 
00181     case StarsWithPlanets:
00182         {
00183             SolarSystemCatalog* solarSystems = univ->getSolarSystemCatalog();
00184             if (solarSystems == NULL)
00185                 return NULL;
00186             SolarSystemPredicate solarSysPred;
00187             solarSysPred.pos = pos;
00188             solarSysPred.solarSystems = solarSystems;
00189             return findStars(*(univ->getStarCatalog()), solarSysPred,
00190                              MIN(nStars, solarSystems->size()));
00191         }
00192         break;
00193 
00194     case NearestStars:
00195     default:
00196         {
00197             CloserStarPredicate closerPred;
00198             closerPred.pos = pos;
00199             return findStars(*(univ->getStarCatalog()), closerPred, nStars);
00200         }
00201         break;
00202     }
00203 
00204     return NULL;  // keep compiler happy
00205 }
00206 
00207 
00208 bool StarBrowser::setPredicate(int pred)
00209 {
00210     if ((pred < NearestStars) || (pred > StarsWithPlanets))
00211         return false;
00212     predicate = pred;
00213     return true;
00214 }
00215 
00216 
00217 void StarBrowser::refresh()
00218 {
00219     ucPos = appSim->getObserver().getPosition();
00220     pos = (Point3f) ucPos;
00221 }
00222 
00223 
00224 void StarBrowser::setSimulation(Simulation *_appSim)
00225 {
00226     appSim = _appSim;
00227     refresh();
00228 }
00229 
00230 
00231 StarBrowser::StarBrowser(Simulation* _appSim, int pred) :
00232     appSim(_appSim)
00233 {
00234     ucPos = appSim->getObserver().getPosition();
00235     pos = (Point3f) ucPos;
00236 
00237     predicate = pred;
00238 }
00239 
00240 
00241 StarBrowser::StarBrowser() :
00242     pos(0.0, 0.0, 0.0),
00243     ucPos(0.0, 0.0, 0.0),
00244     appSim(NULL),
00245     predicate(NearestStars)
00246 {
00247 }

Generated on Sat Jan 14 22:30:29 2006 for Celestia by  doxygen 1.4.1