3
// Copyright (C) 2008, Celestia Development Team
4
// Initial code by Dr. Fridger Schrempp <fridger.schrempp@desy.de>
6
// Simulation of globular clusters, theoretical framework by
7
// Ivan King, Astron. J. 67 (1962) 471; ibid. 71 (1966) 64
9
// This program is free software; you can redistribute it and/or
10
// modify it under the terms of the GNU General Public License
11
// as published by the Free Software Foundation; either version 2
12
// of the License, or (at your option) any later version.
17
#include <fmt/printf.h>
19
#include <celengine/hash.h>
20
#include <celengine/render.h>
21
#include <celmath/ellipsoid.h>
22
#include <celmath/intersect.h>
23
#include <celmath/randutils.h>
24
#include <celmath/ray.h>
25
#include <celutil/gettext.h>
28
namespace astro = celestia::astro;
29
namespace math = celestia::math;
34
constexpr float kRadiusCorrection = 0.025f;
36
unsigned int cSlot(float conc)
38
// map the physical range of c, minC <= c <= maxC,
39
// to 8 integers (bin numbers), 0 < cSlot <= 7:
40
conc = std::clamp(conc, Globular::MinC, Globular::MaxC);
41
return static_cast<unsigned int>(std::floor((conc - Globular::MinC) / Globular::BinWidth));
44
} // end unnamed namespace
48
recomputeTidalRadius();
51
const char* Globular::getType() const
56
void Globular::setType(const std::string& /*typeStr*/)
60
float Globular::getHalfMassRadius() const
62
// Aproximation to the half-mass radius r_h [ly]
65
return std::tan(math::degToRad(r_c / 60.0f)) * static_cast<float>(getPosition().norm()) * std::pow(10.0f, 0.6f * c - 0.4f);
68
std::string Globular::getDescription() const
70
return fmt::sprintf(_("Globular (core radius: %4.2f', King concentration: %4.2f)"), r_c, c);
73
DeepSkyObjectType Globular::getObjType() const
75
return DeepSkyObjectType::Globular;
78
bool Globular::pick(const Eigen::ParametrizedLine<double, 3>& ray,
79
double& distanceToPicker,
80
double& cosAngleToBoundCenter) const
85
* The selection sphere should be slightly larger to compensate for the fact
86
* that blobs are considered points when globulars are built, but have size
87
* when they are drawn.
89
Eigen::Vector3d p = getPosition();
90
return math::testIntersection(math::transformRay(Eigen::ParametrizedLine<double, 3>(ray.origin() - p, ray.direction()),
91
getOrientation().cast<double>().toRotationMatrix()),
92
math::Sphered(getRadius() * (1.0f + kRadiusCorrection)),
94
cosAngleToBoundCenter);
97
bool Globular::load(const AssociativeArray* params, const fs::path& resPath)
99
// Load the basic DSO parameters first
100
if (!DeepSkyObject::load(params, resPath))
103
if (auto detailVal = params->getNumber<float>("Detail"); detailVal.has_value())
106
if (auto coreRadius = params->getAngle<float>("CoreRadius", 1.0 / astro::MINUTES_PER_DEG);
107
coreRadius.has_value())
112
if (auto king = params->getNumber<float>("KingConcentration"); king.has_value())
115
formIndex = cSlot(c);
116
recomputeTidalRadius();
121
std::uint64_t Globular::getRenderMask() const
123
return Renderer::ShowGlobulars;
126
unsigned int Globular::getLabelMask() const
128
return Renderer::GlobularLabels;
131
void Globular::recomputeTidalRadius()
133
// Convert the core radius from arcminutes to light years
134
// Compute the tidal radius in light years
136
float coreRadiusLy = std::tan(math::degToRad(r_c / 60.0f)) * static_cast<float>(getPosition().norm());
137
tidalRadius = coreRadiusLy * std::pow(10.0f, c);
140
int Globular::getFormId() const
145
float Globular::getDetail() const
150
void Globular::setDetail(float _detail)