00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <string>
00013 #include <algorithm>
00014 #include <set>
00015 #include "starbrowser.h"
00016
00017 using namespace std;
00018
00019
00020
00021
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
00097
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
00115
00116 int i = 0;
00117 for (i = 0; i < nStars; i++)
00118 firstStars.insert(stardb.getStar(i));
00119
00120
00121
00122
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
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;
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 }