starbrowser.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:6k
- // starbrowser.cpp
- //
- // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
- //
- // Star browser tool for Celestia.
- //
- // This program is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public License
- // as published by the Free Software Foundation; either version 2
- // of the License, or (at your option) any later version.
- #include <string>
- #include <algorithm>
- #include <set>
- #include "starbrowser.h"
- using namespace std;
- // TODO: More of the functions in this module should be converted to
- // methods of the StarBrowser class.
- struct CloserStarPredicate
- {
- Point3f pos;
- bool operator()(const Star* star0, const Star* star1) const
- {
- Point3f p0 = star0->getPosition();
- Point3f p1 = star1->getPosition();
- Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
- Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
-
- return (v0.lengthSquared() < v1.lengthSquared());
- }
- };
- struct BrighterStarPredicate
- {
- Point3f pos;
- UniversalCoord ucPos;
- bool operator()(const Star* star0, const Star* star1) const
- {
- Point3f p0 = star0->getPosition();
- Point3f p1 = star1->getPosition();
- Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
- Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
- float d0 = v0.length();
- float d1 = v1.length();
- return (star0->getApparentMagnitude(d0) <
- star1->getApparentMagnitude(d1));
- }
- };
- struct BrightestStarPredicate
- {
- bool operator()(const Star* star0, const Star* star1) const
- {
- return (star0->getAbsoluteMagnitude() <
- star1->getAbsoluteMagnitude());
- }
- };
- struct SolarSystemPredicate
- {
- Point3f pos;
- SolarSystemCatalog* solarSystems;
- bool operator()(const Star* star0, const Star* star1) const
- {
- SolarSystemCatalog::iterator iter;
- iter = solarSystems->find(star0->getCatalogNumber());
- bool hasPlanets0 = (iter != solarSystems->end());
- iter = solarSystems->find(star1->getCatalogNumber());
- bool hasPlanets1 = (iter != solarSystems->end());
- if (hasPlanets1 == hasPlanets0)
- {
- Point3f p0 = star0->getPosition();
- Point3f p1 = star1->getPosition();
- Vec3f v0(p0.x * 1e6 - pos.x, p0.y * 1e6 - pos.y, p0.z * 1e6 - pos.z);
- Vec3f v1(p1.x * 1e6 - pos.x, p1.y * 1e6 - pos.y, p1.z * 1e6 - pos.z);
- return (v0.lengthSquared() < v1.lengthSquared());
- }
- else
- {
- return hasPlanets0;
- }
- }
- };
- // Find the nearest/brightest/X-est N stars in a database. The
- // supplied predicate determines which of two stars is a better match.
- template<class Pred> static std::vector<const Star*>*
- findStars(const StarDatabase& stardb, Pred pred, int nStars)
- {
- std::vector<const Star*>* finalStars = new std::vector<const Star*>();
- if (nStars == 0)
- return finalStars;
- if(nStars > 500)
- nStars = 500;
- typedef std::multiset<const Star*, Pred> StarSet;
- StarSet firstStars(pred);
- int totalStars = stardb.size();
- if (totalStars < nStars)
- nStars = totalStars;
- // We'll need at least nStars in the set, so first fill
- // up the list indiscriminately.
- int i = 0;
- for (i = 0; i < nStars; i++)
- firstStars.insert(stardb.getStar(i));
- // From here on, only add a star to the set if it's
- // a better match than the worst matching star already
- // in the set.
- const Star* lastStar = *--firstStars.end();
- for (; i < totalStars; i++)
- {
- Star* star = stardb.getStar(i);
- if (pred(star, lastStar))
- {
- firstStars.insert(star);
- firstStars.erase(--firstStars.end());
- lastStar = *--firstStars.end();
- }
- }
- // Move the best matching stars into the vector
- finalStars->reserve(nStars);
- for (typename StarSet::const_iterator iter = firstStars.begin();
- iter != firstStars.end(); iter++)
- {
- finalStars->insert(finalStars->end(), *iter);
- }
- return finalStars;
- }
- const Star* StarBrowser::nearestStar()
- {
- Universe* univ = appSim->getUniverse();
- CloserStarPredicate closerPred;
- closerPred.pos = pos;
- std::vector<const Star*>* stars = findStars(*(univ->getStarCatalog()), closerPred, 1);
- const Star *star = (*stars)[0];
- delete stars;
- return star;
- }
- std::vector<const Star*>*
- StarBrowser::listStars(unsigned int nStars)
- {
- Universe* univ = appSim->getUniverse();
- switch(predicate)
- {
- case BrighterStars:
- {
- BrighterStarPredicate brighterPred;
- brighterPred.pos = pos;
- brighterPred.ucPos = ucPos;
- return findStars(*(univ->getStarCatalog()), brighterPred, nStars);
- }
- break;
- case BrightestStars:
- {
- BrightestStarPredicate brightestPred;
- return findStars(*(univ->getStarCatalog()), brightestPred, nStars);
- }
- break;
- case StarsWithPlanets:
- {
- SolarSystemCatalog* solarSystems = univ->getSolarSystemCatalog();
- if (solarSystems == NULL)
- return NULL;
- SolarSystemPredicate solarSysPred;
- solarSysPred.pos = pos;
- solarSysPred.solarSystems = solarSystems;
- return findStars(*(univ->getStarCatalog()), solarSysPred,
- MIN(nStars, solarSystems->size()));
- }
- break;
- case NearestStars:
- default:
- {
- CloserStarPredicate closerPred;
- closerPred.pos = pos;
- return findStars(*(univ->getStarCatalog()), closerPred, nStars);
- }
- break;
- }
- return NULL; // keep compiler happy
- }
- bool StarBrowser::setPredicate(int pred)
- {
- if ((pred < NearestStars) || (pred > StarsWithPlanets))
- return false;
- predicate = pred;
- return true;
- }
- void StarBrowser::refresh()
- {
- ucPos = appSim->getObserver().getPosition();
- pos = (Point3f) ucPos;
- }
- void StarBrowser::setSimulation(Simulation *_appSim)
- {
- appSim = _appSim;
- refresh();
- }
- StarBrowser::StarBrowser(Simulation* _appSim, int pred) :
- appSim(_appSim)
- {
- ucPos = appSim->getObserver().getPosition();
- pos = (Point3f) ucPos;
- predicate = pred;
- }
- StarBrowser::StarBrowser() :
- pos(0.0, 0.0, 0.0),
- ucPos(0.0, 0.0, 0.0),
- appSim(NULL),
- predicate(NearestStars)
- {
- }