feat: 完善日月食与月掩几何链路并扩展历法接口
- 新增日月食中心带、偏食带、阴影足迹、等时线、食分线及升落边界计算,支持极区与混合食拓扑 - 新增日食单时刻阴影求解器、站心状态查询、批量采样和 ΔT 覆盖接口 - 重构恒星与行星月掩路径,补充有限盘面接触、站心修正、掩带宽度、极区投影及升落边界 - 扩展 SVG 与 GeoJSON 输出,支持详细面板、全球/极区/地球投影、边界闭合、时间标记和拓扑签名 - 扩展日月食候选搜索、局地搜索、沙罗序列预计算与范围外推,补充系列锚点和成员一致性校验 - 补齐古历纪年、儒略历独有闰日、多公历候选、历法改革跨日及精确日期运算接口 - 优化 ΔT、章动、恒星时、月球地平线、事件根搜索和本地星历缓存,降低重复计算开销并提升边界稳定
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
package svg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"b612.me/astro/basic"
|
||||
eclipsecore "b612.me/astro/eclipse"
|
||||
"b612.me/astro/internal/svgmap"
|
||||
)
|
||||
|
||||
// TestLunarEclipseMapSVGPolarWitnessStaysOutsideEquirectangularVisibility 固定全球月食地图在
|
||||
// 极区的可见性契约。等距圆柱投影在高纬把经度拉伸:1° 的球面地平弧在极点附近可以横跨近
|
||||
// 180° 经度,只连端点就会把地平线以外画进可见区。1904-09-24 的 P1 在南极点附近有一个
|
||||
// 月心高度约 −0.05° 的见证点,曾经被画进 visible-at-p1 多边形。
|
||||
// TestLunarEclipseMapSVGPolarWitnessStaysOutsideEquirectangularVisibility pins the polar
|
||||
// visibility contract of the global lunar-eclipse map. Equirectangular projection stretches
|
||||
// longitude near a pole: a 1-degree spherical horizon arc can span almost 180 degrees there, so
|
||||
// joining endpoints alone paints sky below the horizon as visible. At P1 of 1904-09-24 a witness
|
||||
// near the south pole sits about 0.05 degrees below the Moon's horizon and used to be painted
|
||||
// inside the visible-at-p1 polygon.
|
||||
func TestLunarEclipseMapSVGPolarWitnessStaysOutsideEquirectangularVisibility(t *testing.T) {
|
||||
date := time.Date(1904, 9, 24, 0, 0, 0, 0, time.UTC)
|
||||
info, ok := eclipsecore.LunarEclipseOnDate(date)
|
||||
if !ok {
|
||||
t.Fatal("missing lunar eclipse")
|
||||
}
|
||||
frame := eclipseMapFrame(lunarEclipseMapDefaultWidth, lunarEclipseMapDefaultHeight,
|
||||
svgmap.ProjectionEquirectangular, 142, 92)
|
||||
path, boundary := lunarEclipseVisibilityPath(info.PenumbralStart, frame)
|
||||
if len(boundary) == 0 {
|
||||
t.Fatal("visibility path has no boundary")
|
||||
}
|
||||
rings := svgClosedPathRings(t, `<path d="`+path+`"/>`)
|
||||
if len(rings) == 0 {
|
||||
t.Fatal("visibility path has no rings")
|
||||
}
|
||||
jd := basic.Date2JDE(info.PenumbralStart)
|
||||
// 只取足够深入地平线以下的见证点:−89.9° 处月心高度约 −0.054°,而更靠近极点的
|
||||
// −89.99° 只有约 −0.004°,落在可见性判定本身的数值容差里,不能作为回归依据。
|
||||
// Only a witness clearly below the horizon is used: at -89.9 degrees the Moon centre sits
|
||||
// about 0.054 degrees down, while -89.99 degrees is only about 0.004 degrees down and lies
|
||||
// inside the numerical tolerance of the visibility test itself.
|
||||
witnesses := []struct {
|
||||
longitude float64
|
||||
latitude float64
|
||||
}{
|
||||
{-115, -89.9},
|
||||
}
|
||||
for _, witness := range witnesses {
|
||||
altitude := basic.HMoonHeight(jd, witness.longitude, witness.latitude, 0)
|
||||
if altitude >= -0.01 {
|
||||
// 见证点必须先确实是地平线以下,否则这个回归就失去意义。
|
||||
t.Fatalf("witness (%g,%g) altitude=%g, want below the horizon",
|
||||
witness.longitude, witness.latitude, altitude)
|
||||
}
|
||||
x, y, projectable := frame.Project(witness.longitude, witness.latitude)
|
||||
if !projectable {
|
||||
continue
|
||||
}
|
||||
inside := false
|
||||
for _, ring := range rings {
|
||||
inside = inside || pointInLunarVisibilityPolygon(x, y, ring)
|
||||
}
|
||||
if inside {
|
||||
t.Fatalf("below-horizon witness (%g,%g) altitude=%g is painted inside the visible region",
|
||||
witness.longitude, witness.latitude, altitude)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user