starbrowser.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:6k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // starbrowser.cpp
  2. // 
  3. // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
  4. //
  5. // Star browser tool for Celestia.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. #include <string>
  12. #include <algorithm>
  13. #include <set>
  14. #include "starbrowser.h"
  15. using namespace std;
  16. // TODO: More of the functions in this module should be converted to
  17. // methods of the StarBrowser class.
  18. struct CloserStarPredicate
  19. {
  20.     Point3f pos;
  21.     bool operator()(const Star* star0, const Star* star1) const
  22.     {
  23.         Point3f p0 = star0->getPosition();
  24.         Point3f p1 = star1->getPosition();
  25.         Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
  26.         Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
  27.         
  28.         return (v0.lengthSquared() < v1.lengthSquared());                               
  29.     }
  30. };
  31. struct BrighterStarPredicate
  32. {
  33.     Point3f pos;
  34.     UniversalCoord ucPos;
  35.     bool operator()(const Star* star0, const Star* star1) const
  36.     {
  37.         Point3f p0 = star0->getPosition();
  38.         Point3f p1 = star1->getPosition();
  39.         Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
  40.         Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
  41.         float d0 = v0.length();
  42.         float d1 = v1.length();
  43.         return (star0->getApparentMagnitude(d0) <
  44.                 star1->getApparentMagnitude(d1));
  45.     }
  46. };
  47. struct BrightestStarPredicate
  48. {
  49.     bool operator()(const Star* star0, const Star* star1) const
  50.     {
  51.         return (star0->getAbsoluteMagnitude() <
  52.                 star1->getAbsoluteMagnitude());
  53.     }
  54. };
  55. struct SolarSystemPredicate
  56. {
  57.     Point3f pos;
  58.     SolarSystemCatalog* solarSystems;
  59.     bool operator()(const Star* star0, const Star* star1) const
  60.     {
  61.         SolarSystemCatalog::iterator iter;
  62.         iter = solarSystems->find(star0->getCatalogNumber());
  63.         bool hasPlanets0 = (iter != solarSystems->end());
  64.         iter = solarSystems->find(star1->getCatalogNumber());
  65.         bool hasPlanets1 = (iter != solarSystems->end());
  66.         if (hasPlanets1 == hasPlanets0)
  67.         {
  68.             Point3f p0 = star0->getPosition();
  69.             Point3f p1 = star1->getPosition();
  70.             Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
  71.             Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
  72.             return (v0.lengthSquared() < v1.lengthSquared());
  73.         }
  74.         else
  75.         {
  76.             return hasPlanets0;
  77.         }
  78.     }
  79. };
  80. // Find the nearest/brightest/X-est N stars in a database.  The
  81. // supplied predicate determines which of two stars is a better match.
  82. template<class Pred> static std::vector<const Star*>*
  83. findStars(const StarDatabase& stardb, Pred pred, int nStars)
  84. {
  85.     std::vector<const Star*>* finalStars = new std::vector<const Star*>();
  86.     if (nStars == 0)
  87.         return finalStars;
  88.     if(nStars > 500)
  89.         nStars = 500;
  90.     typedef std::multiset<const Star*, Pred> StarSet;
  91.     StarSet firstStars(pred);
  92.     int totalStars = stardb.size();
  93.     if (totalStars < nStars)
  94.         nStars = totalStars;
  95.     // We'll need at least nStars in the set, so first fill
  96.     // up the list indiscriminately.
  97.     int i = 0;
  98.     for (i = 0; i < nStars; i++)
  99.         firstStars.insert(stardb.getStar(i));
  100.     // From here on, only add a star to the set if it's
  101.     // a better match than the worst matching star already
  102.     // in the set.
  103.     const Star* lastStar = *--firstStars.end();
  104.     for (; i < totalStars; i++)
  105.     {
  106.         Star* star = stardb.getStar(i);
  107.         if (pred(star, lastStar))
  108.         {
  109.             firstStars.insert(star);
  110.             firstStars.erase(--firstStars.end());
  111.             lastStar = *--firstStars.end();
  112.         }
  113.     }
  114.     // Move the best matching stars into the vector
  115.     finalStars->reserve(nStars);
  116.     for (typename StarSet::const_iterator iter = firstStars.begin();
  117.          iter != firstStars.end(); iter++)
  118.     {
  119.         finalStars->insert(finalStars->end(), *iter);
  120.     }
  121.     return finalStars;
  122. }
  123. const Star* StarBrowser::nearestStar()
  124. {
  125.     Universe* univ = appSim->getUniverse();
  126.     CloserStarPredicate closerPred;
  127.     closerPred.pos = pos;
  128.     std::vector<const Star*>* stars = findStars(*(univ->getStarCatalog()), closerPred, 1);
  129.     const Star *star = (*stars)[0];
  130.     delete stars;
  131.     return star;
  132. }
  133. std::vector<const Star*>*
  134. StarBrowser::listStars(unsigned int nStars)
  135. {
  136.     Universe* univ = appSim->getUniverse();
  137.     switch(predicate)
  138.     {
  139.     case BrighterStars:
  140.         {
  141.             BrighterStarPredicate brighterPred;
  142.             brighterPred.pos = pos;
  143.             brighterPred.ucPos = ucPos;
  144.             return findStars(*(univ->getStarCatalog()), brighterPred, nStars);
  145.         }
  146.         break;
  147.     case BrightestStars:
  148.         {
  149.             BrightestStarPredicate brightestPred;
  150.             return findStars(*(univ->getStarCatalog()), brightestPred, nStars);
  151.         }
  152.         break;
  153.     case StarsWithPlanets:
  154.         {
  155.             SolarSystemCatalog* solarSystems = univ->getSolarSystemCatalog();
  156.             if (solarSystems == NULL)
  157.                 return NULL;
  158.             SolarSystemPredicate solarSysPred;
  159.             solarSysPred.pos = pos;
  160.             solarSysPred.solarSystems = solarSystems;
  161.             return findStars(*(univ->getStarCatalog()), solarSysPred,
  162.                              MIN(nStars, solarSystems->size()));
  163.         }
  164.         break;
  165.     case NearestStars:
  166.     default:
  167.         {
  168.             CloserStarPredicate closerPred;
  169.             closerPred.pos = pos;
  170.             return findStars(*(univ->getStarCatalog()), closerPred, nStars);
  171.         }
  172.         break;
  173.     }
  174.     return NULL;  // keep compiler happy
  175. }
  176. bool StarBrowser::setPredicate(int pred)
  177. {
  178.     if ((pred < NearestStars) || (pred > StarsWithPlanets))
  179.         return false;
  180.     predicate = pred;
  181.     return true;
  182. }
  183. void StarBrowser::refresh()
  184. {
  185.     ucPos = appSim->getObserver().getPosition();
  186.     pos = (Point3f) ucPos;
  187. }
  188. void StarBrowser::setSimulation(Simulation *_appSim)
  189. {
  190.     appSim = _appSim;
  191.     refresh();
  192. }
  193. StarBrowser::StarBrowser(Simulation* _appSim, int pred) :
  194.     appSim(_appSim)
  195. {
  196.     ucPos = appSim->getObserver().getPosition();
  197.     pos = (Point3f) ucPos;
  198.     predicate = pred;
  199. }
  200. StarBrowser::StarBrowser() :
  201.     pos(0.0, 0.0, 0.0),
  202.     ucPos(0.0, 0.0, 0.0),
  203.     appSim(NULL),
  204.     predicate(NearestStars)
  205. {
  206. }