106 lines
4.1 KiB
Go
106 lines
4.1 KiB
Go
|
|
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)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|