Files
astro/basic/lunar_eclipse_geometry.go
T
b612 2bf8478639 feat: 完善日月食与月掩几何链路并扩展历法接口
- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑
- 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口
- 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界
- 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名
- 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验
- 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口
- 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
2026-09-17 12:27:40 +08:00

66 lines
3.6 KiB
Go

package basic
import "math"
// LunarEclipseShadowGeometry 是食甚时刻的地影几何。
// 注意单位口径:Gamma 用地球赤道半径,而两个影半径用度——后者是 NASA 月食图上 P./U. Radius 的口径,
// 换成地球赤道半径要乘以月球处的地球视差(弧度)。
// LunarEclipseShadowGeometry is the terrestrial-shadow geometry at maximum eclipse. Gamma is in Earth
// equatorial radii while the two shadow radii are in degrees, matching the P./U. Radius convention of
// NASA lunar-eclipse charts; multiply a radius by the Earth's parallax at the Moon to get Earth radii.
type LunarEclipseShadowGeometry struct {
// Gamma 是月心到地影轴的最小距离,单位地球赤道半径。
Gamma float64
// PenumbralRadiusDegrees 与 UmbralRadiusDegrees 是半影、本影在地影轴垂直面上的角半径,单位度。
PenumbralRadiusDegrees float64
UmbralRadiusDegrees float64
// MoonDistanceEarthRadii 是食甚时的地心月距。
MoonDistanceEarthRadii float64
// AxisDegrees 是食甚时月心到地影轴的角距,即 NASA 月食图上那列 Axis。
// 它与 Gamma 是同一个量的两种刻度:Gamma 除以月球处的地球视差就是它。
// AxisDegrees is the angular distance from the Moon's centre to the shadow axis at greatest eclipse,
// the column NASA lunar-eclipse charts print as Axis. It is the same quantity as Gamma on a different
// scale: divide Gamma by the Earth's parallax at the Moon.
AxisDegrees float64
}
// LunarEclipseShadowGeometryAt 用 Danjon 影半径模型计算食甚时刻的地影几何。
// LunarEclipseShadowGeometryAt computes the shadow geometry at maximum eclipse with the Danjon shadow model.
func LunarEclipseShadowGeometryAt(maximumJDE float64) LunarEclipseShadowGeometry {
return lunarEclipseShadowGeometryAt(maximumJDE, lunarEclipseShadowDanjon)
}
// LunarEclipseShadowGeometryChauvenetAt 用 Chauvenet 影半径模型计算食甚时刻的地影几何。
// LunarEclipseShadowGeometryChauvenetAt computes the shadow geometry with the Chauvenet shadow model.
func LunarEclipseShadowGeometryChauvenetAt(maximumJDE float64) LunarEclipseShadowGeometry {
return lunarEclipseShadowGeometryAt(maximumJDE, lunarEclipseShadowChauvenet)
}
// LunarEclipseShadowGeometryAtModel 按结果里记录的影半径模型取地影几何。
// LunarEclipseShadowGeometryAtModel picks the shadow geometry by the model recorded in a result.
func LunarEclipseShadowGeometryAtModel(maximumJDE float64, model LunarEclipseShadowModel) LunarEclipseShadowGeometry {
if model == LunarEclipseShadowModelChauvenet {
return LunarEclipseShadowGeometryChauvenetAt(maximumJDE)
}
return LunarEclipseShadowGeometryAt(maximumJDE)
}
func lunarEclipseShadowGeometryAt(maximumJDE float64, shadowModel lunarEclipseShadowModel) LunarEclipseShadowGeometry {
state := computeLunarShadowState(maximumJDE, shadowModel)
moonDistanceKM := HMoonAway(maximumJDE)
// 影半径是以地心为顶点的角量,除以月球处的地球视差就换成地球赤道半径。
earthParallax := lunarEarthEquatorialRadiusKM / moonDistanceKM
_, _, _, _, minimumDistance := refineLunarEclipseMaximum(maximumJDE, shadowModel)
if earthParallax <= 0 {
return LunarEclipseShadowGeometry{}
}
return LunarEclipseShadowGeometry{
Gamma: minimumDistance / earthParallax,
PenumbralRadiusDegrees: state.penumbraRadiusRad * 180 / math.Pi,
UmbralRadiusDegrees: state.umbraRadiusRad * 180 / math.Pi,
MoonDistanceEarthRadii: moonDistanceKM / lunarEarthEquatorialRadiusKM,
// 平面 x 向东(黄经差)、y 向北(黄纬和),方位角自北向东量。
AxisDegrees: minimumDistance * 180 / math.Pi,
}
}