Vulcan
Aerospace Engineering Utilities Built on Janus
Loading...
Searching...
No Matches
Eclipse.hpp
Go to the documentation of this file.
1// Eclipse Detection Models
2// Cylindrical and conical shadow models for satellite eclipse detection
3#pragma once
4
5#include <janus/janus.hpp>
8
10
11namespace constants {
13inline constexpr double R_sun = 696340000.0;
14
16inline constexpr double AU = 149597870700.0;
17} // namespace constants
18
31template <typename Scalar>
32Scalar shadow_cylindrical(const Vec3<Scalar> &r_sat, const Vec3<Scalar> &r_sun,
33 double R_body = vulcan::constants::earth::R_eq) {
34 // Sun direction (unit vector from Earth to Sun)
35 const Scalar r_sun_mag = janus::norm(r_sun);
36 const Vec3<Scalar> s_hat = r_sun / r_sun_mag;
37
38 // Projection of satellite onto sun direction
39 const Scalar proj = r_sat.dot(s_hat);
40
41 // Perpendicular distance from shadow axis
42 const Vec3<Scalar> r_perp = r_sat - proj * s_hat;
43 const Scalar d_perp = janus::norm(r_perp);
44
45 // In shadow if:
46 // 1. Behind Earth (projection < 0)
47 // 2. Within shadow cylinder (perpendicular distance < R_body)
48 const Scalar behind_earth =
49 janus::where(proj < 0.0, Scalar(1.0), Scalar(0.0));
50 const Scalar in_cylinder =
51 janus::where(d_perp < R_body, Scalar(1.0), Scalar(0.0));
52
53 const Scalar in_shadow = behind_earth * in_cylinder;
54
55 // Return 1 for sunlit, 0 for shadow
56 return 1.0 - in_shadow;
57}
58
73template <typename Scalar>
74Scalar shadow_conical(const Vec3<Scalar> &r_sat, const Vec3<Scalar> &r_sun,
75 double R_body = vulcan::constants::earth::R_eq,
76 double R_sun = constants::R_sun) {
77 // Vector from satellite to Sun
78 const Vec3<Scalar> r_sat_to_sun = r_sun - r_sat;
79 const Scalar s = janus::norm(r_sat_to_sun);
80
81 // Satellite distance from Earth center
82 const Scalar r_sat_mag = janus::norm(r_sat);
83
84 // Apparent angular radii as seen from satellite
85 const Scalar theta_body = janus::asin(R_body / r_sat_mag);
86 const Scalar theta_sun = janus::asin(R_sun / s);
87
88 // Angle between Earth center and Sun as seen from satellite
89 const Scalar cos_theta = -r_sat.dot(r_sat_to_sun) / (r_sat_mag * s);
90 // Clamp for numerical stability
91 const Scalar cos_theta_clamped =
92 janus::where(cos_theta > 1.0, Scalar(1.0),
93 janus::where(cos_theta < -1.0, Scalar(-1.0), cos_theta));
94 const Scalar theta = janus::acos(cos_theta_clamped);
95
96 // Shadow geometry boundaries
97 const Scalar sum_angles = theta_body + theta_sun;
98 const Scalar diff_angles = janus::abs(theta_body - theta_sun);
99
100 // Fully sunlit: θ > θ_body + θ_sun
101 const Scalar full_sun =
102 janus::where(theta >= sum_angles, Scalar(1.0), Scalar(0.0));
103
104 // Penumbra transition: linear interpolation
105 const Scalar in_penumbra_region =
106 janus::where(theta > diff_angles, Scalar(1.0), Scalar(0.0)) *
107 janus::where(theta < sum_angles, Scalar(1.0), Scalar(0.0));
108
109 const Scalar penumbra_frac =
110 (theta - diff_angles) / (sum_angles - diff_angles + 1e-12);
111
112 // Full umbra: θ < |θ_body - θ_sun| when body appears larger
113 const Scalar full_umbra =
114 janus::where(theta <= diff_angles, Scalar(0.0), penumbra_frac);
115
116 // Combine: sunlit OR (in penumbra region * penumbra fraction)
117 return full_sun + (1.0 - full_sun) * in_penumbra_region * full_umbra;
118}
119
124template <typename Scalar>
125Scalar is_in_shadow(const Vec3<Scalar> &r_sat, const Vec3<Scalar> &r_sun,
126 double R_body = vulcan::constants::earth::R_eq) {
127 const Scalar nu = shadow_cylindrical(r_sat, r_sun, R_body);
128 return janus::where(nu < 0.5, Scalar(1.0), Scalar(0.0));
129}
130
135template <typename Scalar>
136Scalar is_sunlit(const Vec3<Scalar> &r_sat, const Vec3<Scalar> &r_sun,
137 double R_body = vulcan::constants::earth::R_eq) {
138 return shadow_cylindrical(r_sat, r_sun, R_body);
139}
140
141} // namespace vulcan::environment::eclipse
constexpr double R_eq
Equatorial radius [m] (WGS84).
Definition Constants.hpp:16
constexpr double R_sun
Solar radius [m].
Definition Eclipse.hpp:13
constexpr double AU
Mean Earth-Sun distance [m] (1 AU).
Definition Eclipse.hpp:16
Definition Eclipse.hpp:9
Scalar shadow_cylindrical(const Vec3< Scalar > &r_sat, const Vec3< Scalar > &r_sun, double R_body=vulcan::constants::earth::R_eq)
Cylindrical shadow function.
Definition Eclipse.hpp:32
Scalar is_sunlit(const Vec3< Scalar > &r_sat, const Vec3< Scalar > &r_sun, double R_body=vulcan::constants::earth::R_eq)
Check if satellite is in sunlight.
Definition Eclipse.hpp:136
Scalar shadow_conical(const Vec3< Scalar > &r_sat, const Vec3< Scalar > &r_sun, double R_body=vulcan::constants::earth::R_eq, double R_sun=constants::R_sun)
Conical shadow function with penumbra.
Definition Eclipse.hpp:74
Scalar is_in_shadow(const Vec3< Scalar > &r_sat, const Vec3< Scalar > &r_sun, double R_body=vulcan::constants::earth::R_eq)
Simple binary eclipse check using cylindrical model.
Definition Eclipse.hpp:125