Celestia

Форк
0
/
globular.cpp 
153 строки · 4.0 Кб
1
// qlobular.cpp
2
//
3
// Copyright (C) 2008, Celestia Development Team
4
// Initial code by Dr. Fridger Schrempp <fridger.schrempp@desy.de>
5
//
6
// Simulation of globular clusters, theoretical framework by
7
// Ivan King, Astron. J. 67 (1962) 471; ibid. 71 (1966) 64
8
//
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.
13

14
#include <algorithm>
15
#include <cmath>
16

17
#include <fmt/printf.h>
18

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>
26
#include "globular.h"
27

28
namespace astro = celestia::astro;
29
namespace math = celestia::math;
30

31
namespace
32
{
33

34
constexpr float kRadiusCorrection = 0.025f;
35

36
unsigned int cSlot(float conc)
37
{
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));
42
}
43

44
} // end unnamed namespace
45

46
Globular::Globular()
47
{
48
    recomputeTidalRadius();
49
}
50

51
const char* Globular::getType() const
52
{
53
    return "Globular";
54
}
55

56
void Globular::setType(const std::string& /*typeStr*/)
57
{
58
}
59

60
float Globular::getHalfMassRadius() const
61
{
62
    // Aproximation to the half-mass radius r_h [ly]
63
    // (~ 20% accuracy)
64

65
    return std::tan(math::degToRad(r_c / 60.0f)) * static_cast<float>(getPosition().norm()) * std::pow(10.0f, 0.6f * c - 0.4f);
66
}
67

68
std::string Globular::getDescription() const
69
{
70
   return fmt::sprintf(_("Globular (core radius: %4.2f', King concentration: %4.2f)"), r_c, c);
71
}
72

73
DeepSkyObjectType Globular::getObjType() const
74
{
75
    return DeepSkyObjectType::Globular;
76
}
77

78
bool Globular::pick(const Eigen::ParametrizedLine<double, 3>& ray,
79
                    double& distanceToPicker,
80
                    double& cosAngleToBoundCenter) const
81
{
82
    if (!isVisible())
83
        return false;
84
    /*
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.
88
     */
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)),
93
                                  distanceToPicker,
94
                                  cosAngleToBoundCenter);
95
}
96

97
bool Globular::load(const AssociativeArray* params, const fs::path& resPath)
98
{
99
    // Load the basic DSO parameters first
100
    if (!DeepSkyObject::load(params, resPath))
101
        return false;
102

103
    if (auto detailVal = params->getNumber<float>("Detail"); detailVal.has_value())
104
        detail = *detailVal;
105

106
    if (auto coreRadius = params->getAngle<float>("CoreRadius", 1.0 / astro::MINUTES_PER_DEG);
107
        coreRadius.has_value())
108
    {
109
        r_c = *coreRadius;
110
    }
111

112
    if (auto king = params->getNumber<float>("KingConcentration"); king.has_value())
113
        c = *king;
114

115
    formIndex = cSlot(c);
116
    recomputeTidalRadius();
117

118
    return true;
119
}
120

121
std::uint64_t Globular::getRenderMask() const
122
{
123
    return Renderer::ShowGlobulars;
124
}
125

126
unsigned int Globular::getLabelMask() const
127
{
128
    return Renderer::GlobularLabels;
129
}
130

131
void Globular::recomputeTidalRadius()
132
{
133
    // Convert the core radius from arcminutes to light years
134
    // Compute the tidal radius in light years
135

136
    float coreRadiusLy = std::tan(math::degToRad(r_c / 60.0f)) * static_cast<float>(getPosition().norm());
137
    tidalRadius = coreRadiusLy * std::pow(10.0f, c);
138
}
139

140
int Globular::getFormId() const
141
{
142
    return formIndex;
143
}
144

145
float Globular::getDetail() const
146
{
147
    return detail;
148
}
149

150
void Globular::setDetail(float _detail)
151
{
152
    detail = _detail;
153
}
154

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.