feat: 扩展天文计算能力
- 新增日食、月食、本地可见性、中心线、半影区域、SVG 图示与沙罗周期信息 - 新增行星冲合、留、方照、物理星历、视直径、相位、亮肢角、轨道节点等计算 - 新增木星伽利略卫星位置、现象与接触事件计算 - 新增恒星星表、星座判定、自行修正与观测辅助能力 - 新增 coord、formula、orbit、sundial、lite/sun、lite/moon 等扩展包 - 完善农历年号、月相英文别名、视差角、大气质量、折射、日晷与双星计算 - 增加 NASA、JPL Horizons、IMCCE 等回归测试数据与基线测试 - 重构基础算法文件组织,补充大量公开 API 注释和语义回归测试 - 更新中文和英文 README,补充示例、精度说明、SVG 配图
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
package coord
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestObliquityDrivenCoordinateConversions(t *testing.T) {
|
||||
date := time.Date(2026, 4, 27, 10, 30, 45, 0, time.FixedZone("CST", 8*3600))
|
||||
lon := 139.686111
|
||||
lat := 4.875278
|
||||
obliquity := EclipticObliquity(date, true)
|
||||
|
||||
got := EclipticToEquatorialByObliquity(lon, lat, obliquity)
|
||||
want := EclipticToEquatorial(date, lon, lat)
|
||||
assertClose(t, "manual obliquity ra", got.RA, want.RA, 1e-12)
|
||||
assertClose(t, "manual obliquity dec", got.Dec, want.Dec, 1e-12)
|
||||
|
||||
back := EquatorialToEclipticByObliquity(got.RA, got.Dec, obliquity)
|
||||
assertClose(t, "manual obliquity lon", back.Lon, lon, 1e-10)
|
||||
assertClose(t, "manual obliquity lat", back.Lat, lat, 1e-10)
|
||||
}
|
||||
|
||||
func TestHourAngleDrivenHorizontalConversions(t *testing.T) {
|
||||
date := time.Date(2026, 4, 27, 2, 30, 45, 0, time.UTC)
|
||||
ra := 101.28715533
|
||||
dec := -16.71611586
|
||||
observerLon := 115.0
|
||||
observerLat := 40.0
|
||||
hourAngle := HourAngle(date, ra, observerLon)
|
||||
|
||||
got := HourAngleDeclinationToHorizontal(hourAngle, dec, observerLat)
|
||||
want := EquatorialToHorizontal(date, ra, dec, observerLon, observerLat)
|
||||
assertClose(t, "manual hour angle azimuth", got.Azimuth, want.Azimuth, 1e-12)
|
||||
assertClose(t, "manual hour angle altitude", got.Altitude, want.Altitude, 1e-12)
|
||||
assertClose(t, "manual hour angle zenith", got.Zenith, want.Zenith, 1e-12)
|
||||
assertClose(t, "manual hour angle value", got.HourAngle, want.HourAngle, 1e-12)
|
||||
|
||||
roundTripHourAngle, roundTripDeclination := HorizontalToHourAngleDeclination(got.Azimuth, got.Altitude, observerLat)
|
||||
assertClose(t, "round trip hour angle", roundTripHourAngle, normalize360(hourAngle), 1e-10)
|
||||
assertClose(t, "round trip declination", roundTripDeclination, dec, 1e-10)
|
||||
}
|
||||
|
||||
func TestLocalSiderealTimeDrivenHorizontalConversions(t *testing.T) {
|
||||
date := time.Date(2026, 4, 27, 2, 30, 45, 0, time.UTC)
|
||||
ra := 101.28715533
|
||||
dec := -16.71611586
|
||||
observerLon := 115.0
|
||||
observerLat := 40.0
|
||||
localSiderealTimeHours := math.Mod(ApparentSiderealTime(date)+observerLon/15, 24)
|
||||
if localSiderealTimeHours < 0 {
|
||||
localSiderealTimeHours += 24
|
||||
}
|
||||
|
||||
got := EquatorialToHorizontalByLocalSiderealTime(localSiderealTimeHours, ra, dec, observerLat)
|
||||
want := EquatorialToHorizontal(date, ra, dec, observerLon, observerLat)
|
||||
assertClose(t, "LST azimuth", got.Azimuth, want.Azimuth, 1e-12)
|
||||
assertClose(t, "LST altitude", got.Altitude, want.Altitude, 1e-12)
|
||||
assertClose(t, "LST zenith", got.Zenith, want.Zenith, 1e-12)
|
||||
assertClose(t, "LST hour angle", got.HourAngle, want.HourAngle, 1e-12)
|
||||
|
||||
back := HorizontalToEquatorialByLocalSiderealTime(localSiderealTimeHours, got.Azimuth, got.Altitude, observerLat)
|
||||
assertClose(t, "LST round trip ra", back.RA, ra, 1e-10)
|
||||
assertClose(t, "LST round trip dec", back.Dec, dec, 1e-10)
|
||||
}
|
||||
|
||||
func TestGalacticCoordinateConversions(t *testing.T) {
|
||||
galacticCenter := EquatorialToGalactic(266.4051, -28.936175)
|
||||
assertClose(t, "galactic center lon", galacticCenter.Lon, 0, 5e-4)
|
||||
assertClose(t, "galactic center lat", galacticCenter.Lat, 0, 5e-4)
|
||||
|
||||
pole := GalacticToEquatorial(0, 90)
|
||||
assertClose(t, "north galactic pole ra", pole.RA, 192.85948, 1e-5)
|
||||
assertClose(t, "north galactic pole dec", pole.Dec, 27.12825, 1e-5)
|
||||
|
||||
sample := EquatorialToGalactic(83.6331, 22.0145)
|
||||
back := GalacticToEquatorial(sample.Lon, sample.Lat)
|
||||
assertClose(t, "galactic round trip ra", back.RA, 83.6331, 1e-10)
|
||||
assertClose(t, "galactic round trip dec", back.Dec, 22.0145, 1e-10)
|
||||
}
|
||||
|
||||
func TestHorizontalRoundTripAcrossQuadrants(t *testing.T) {
|
||||
samples := []struct {
|
||||
hourAngle float64
|
||||
declination float64
|
||||
latitude float64
|
||||
}{
|
||||
{15, 20, 35},
|
||||
{95, -10, 52},
|
||||
{210, 45, -20},
|
||||
{315, -35, 10},
|
||||
}
|
||||
|
||||
for _, sample := range samples {
|
||||
hz := HourAngleDeclinationToHorizontal(sample.hourAngle, sample.declination, sample.latitude)
|
||||
hourAngle, declination := HorizontalToHourAngleDeclination(hz.Azimuth, hz.Altitude, sample.latitude)
|
||||
if math.Abs(hourAngle-normalize360(sample.hourAngle)) > 1e-10 {
|
||||
t.Fatalf("hour angle round trip mismatch: got %.15f want %.15f", hourAngle, normalize360(sample.hourAngle))
|
||||
}
|
||||
if math.Abs(declination-sample.declination) > 1e-10 {
|
||||
t.Fatalf("declination round trip mismatch: got %.15f want %.15f", declination, sample.declination)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user