feat: 引入可切换星历模型并扩展天象观测链路

- 新增半解析、旧模型、自定义与多源堆叠星历实例,提供 Context、Instance、SPK 读取及状态与视位置计算
- 统一太阳、月球和行星实例接口,扩展黄经穿越、留、相位、最近角距、偕日可见、任意高度升落、轨道节点及凌日等天象查询
- 完善日月食、月掩与凌日的月缘剖面、有限盘面接触、站心修正、局地可见性、全球路径和地图输出
- 新增 SVG、GeoJSON、KML 天象输出及凌日、月掩和月缘地形相关缓存与几何求解
- 新增恒星星表导入与查询,支持 CSV、Hipparcos、BSC5、Stellarium 等格式及名称、交叉标识、锥面检索和星等过滤
- 补充 IAU 2006、地球定向、折射消光、大气观测、轨道传播及半解析行星/月球数据支持
- 将默认未来民用时标切换为 TimeScaleLeapHour,更新 2027–2400 农历速查表、中文日期解析和时区边界处理
- 增加事件基线、跨模型回归、几何边界、月缘地形和输出契约测试,完善中英文手册、示例资源、NOTICE 与忽略规则
This commit is contained in:
2026-10-15 23:54:15 +08:00
parent 16c62a97d5
commit 044f2f4381
674 changed files with 62983 additions and 8396 deletions
+258
View File
@@ -0,0 +1,258 @@
package mars
import (
"time"
)
// Altitude 站心视高度角,不含大气折射 / topocentric apparent altitude without refraction.
func Altitude(date time.Time, lon, lat float64) float64 {
return defaultModule.Altitude(date, lon, lat)
}
// AltitudeN 站心视高度角(n 变体) / n-parameterised topocentric apparent altitude.
func AltitudeN(date time.Time, lon, lat float64, n int) float64 {
return defaultModule.AltitudeN(date, lon, lat, n)
}
// ApparentBo 视黄纬 / apparent ecliptic latitude.
func ApparentBo(date time.Time) float64 { return defaultModule.ApparentBo(date) }
// ApparentBoN 视黄纬(n 变体) / n-parameterised apparent ecliptic latitude.
func ApparentBoN(date time.Time, n int) float64 { return defaultModule.ApparentBoN(date, n) }
// ApparentDec 视赤纬 / apparent declination.
func ApparentDec(date time.Time) float64 { return defaultModule.ApparentDec(date) }
// ApparentDecN 视赤纬(n 变体) / n-parameterised apparent declination.
func ApparentDecN(date time.Time, n int) float64 { return defaultModule.ApparentDecN(date, n) }
// ApparentLo 视黄经 / apparent ecliptic longitude.
func ApparentLo(date time.Time) float64 { return defaultModule.ApparentLo(date) }
// ApparentLoN 视黄经(n 变体) / n-parameterised apparent ecliptic longitude.
func ApparentLoN(date time.Time, n int) float64 { return defaultModule.ApparentLoN(date, n) }
// ApparentMagnitude 视星等 / apparent magnitude.
func ApparentMagnitude(date time.Time) float64 { return defaultModule.ApparentMagnitude(date) }
// ApparentMagnitudeN 视星等(n 变体) / n-parameterised apparent magnitude.
func ApparentMagnitudeN(date time.Time, n int) float64 {
return defaultModule.ApparentMagnitudeN(date, n)
}
// ApparentRa 视赤经 / apparent right ascension.
func ApparentRa(date time.Time) float64 { return defaultModule.ApparentRa(date) }
// ApparentRaDec 视赤经、视赤纬 / apparent right ascension and declination.
func ApparentRaDec(date time.Time) (float64, float64) { return defaultModule.ApparentRaDec(date) }
// ApparentRaDecN 视赤经赤纬(n 变体) / n-parameterised apparent right ascension and declination.
func ApparentRaDecN(date time.Time, n int) (float64, float64) {
return defaultModule.ApparentRaDecN(date, n)
}
// ApparentRaN 视赤经(n 变体) / n-parameterised apparent right ascension.
func ApparentRaN(date time.Time, n int) float64 { return defaultModule.ApparentRaN(date, n) }
// AscendingNode 火星升交点黄经 / ascending node longitude of Mars.
func AscendingNode(date time.Time) float64 { return defaultModule.AscendingNode(date) }
// AscendingNodeN 火星升交点黄经(n 变体) / n-parameterised ascending node longitude of Mars.
func AscendingNodeN(date time.Time, n int) float64 { return defaultModule.AscendingNodeN(date, n) }
// Azimuth 站心方位角,自正北向东量 / topocentric azimuth, measured from north through east.
func Azimuth(date time.Time, lon, lat float64) float64 { return defaultModule.Azimuth(date, lon, lat) }
// AzimuthN 站心方位角(n 变体) / n-parameterised topocentric azimuth.
func AzimuthN(date time.Time, lon, lat float64, n int) float64 {
return defaultModule.AzimuthN(date, lon, lat, n)
}
// BrightLimbPositionAngle 亮面中心位置角,单位度 / bright limb position angle in degrees.
func BrightLimbPositionAngle(date time.Time) float64 {
return defaultModule.BrightLimbPositionAngle(date)
}
// BrightLimbPositionAngleN 亮面中心位置角(n 变体),单位度 / n-parameterised bright limb position angle in degrees.
func BrightLimbPositionAngleN(date time.Time, n int) float64 {
return defaultModule.BrightLimbPositionAngleN(date, n)
}
// CulminationTime 中天时刻,取 date 所在当地民用日 / culmination time, on the local civil day of date.
func CulminationTime(date time.Time, lon float64) time.Time {
return defaultModule.CulminationTime(date, lon)
}
// CulminationTimeN 中天时间(n 变体) / n-parameterised culmination time.
func CulminationTimeN(date time.Time, lon float64, n int) time.Time {
return defaultModule.CulminationTimeN(date, lon, n)
}
// DescendingNode 火星降交点黄经 / descending node longitude of Mars.
func DescendingNode(date time.Time) float64 { return defaultModule.DescendingNode(date) }
// DescendingNodeN 火星降交点黄经(n 变体) / n-parameterised descending node longitude of Mars.
func DescendingNodeN(date time.Time, n int) float64 { return defaultModule.DescendingNodeN(date, n) }
// Diameter 火星视直径,单位角秒 / apparent Mars diameter in arcseconds.
func Diameter(date time.Time) float64 { return defaultModule.Diameter(date) }
// DiameterN 火星视直径(n 变体),单位角秒 / n-parameterised apparent Mars diameter in arcseconds.
func DiameterN(date time.Time, n int) float64 { return defaultModule.DiameterN(date, n) }
// DownTime 落下时间别名 / deprecated set-time alias.
//
// Deprecated: use SetTime instead.
func DownTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
return defaultModule.DownTime(date, lon, lat, height, aero)
}
// DownTimeN 落下时间别名(n 变体) / n-parameterised down-time alias.
func DownTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
return defaultModule.DownTimeN(date, lon, lat, height, aero, n)
}
// EarthDistance 地心距离 / Earth distance.
func EarthDistance(date time.Time) float64 { return defaultModule.EarthDistance(date) }
// EarthDistanceN 地球距离(n 变体) / n-parameterised Earth distance.
func EarthDistanceN(date time.Time, n int) float64 { return defaultModule.EarthDistanceN(date, n) }
// HourAngle 地心视时角,不含站心视差 / geocentric apparent hour angle without topocentric parallax.
func HourAngle(date time.Time, lon float64) float64 { return defaultModule.HourAngle(date, lon) }
// HourAngleN 时角(n 变体) / n-parameterised hour angle.
func HourAngleN(date time.Time, lon float64, n int) float64 {
return defaultModule.HourAngleN(date, lon, n)
}
// IlluminatedFraction 被照亮比例 / illuminated fraction.
func IlluminatedFraction(date time.Time) float64 { return defaultModule.IlluminatedFraction(date) }
// IlluminatedFractionN 被照亮比例(n 变体) / n-parameterised illuminated fraction.
func IlluminatedFractionN(date time.Time, n int) float64 {
return defaultModule.IlluminatedFractionN(date, n)
}
// LastConjunction 上一次合日,取 date 所在当地民用日 / previous conjunction with the Sun, on the local civil day of date.
func LastConjunction(date time.Time) time.Time { return defaultModule.LastConjunction(date) }
// LastEasternQuadrature 上一次东方照,取 date 所在当地民用日 / previous eastern quadrature, on the local civil day of date.
func LastEasternQuadrature(date time.Time) time.Time {
return defaultModule.LastEasternQuadrature(date)
}
// LastOpposition 上一次冲日,取 date 所在当地民用日 / previous opposition, on the local civil day of date.
func LastOpposition(date time.Time) time.Time { return defaultModule.LastOpposition(date) }
// LastProgradeToRetrograde 上一次顺行转逆行留,取 date 所在当地民用日 / previous station from prograde to retrograde, on the local civil day of date.
func LastProgradeToRetrograde(date time.Time) time.Time {
return defaultModule.LastProgradeToRetrograde(date)
}
// LastRetrogradeToPrograde 上一次逆行转顺行留,取 date 所在当地民用日 / previous station from retrograde to prograde, on the local civil day of date.
func LastRetrogradeToPrograde(date time.Time) time.Time {
return defaultModule.LastRetrogradeToPrograde(date)
}
// LastWesternQuadrature 上一次西方照,取 date 所在当地民用日 / previous western quadrature, on the local civil day of date.
func LastWesternQuadrature(date time.Time) time.Time {
return defaultModule.LastWesternQuadrature(date)
}
// NextConjunction 下一次合日,取 date 所在当地民用日 / next conjunction with the Sun, on the local civil day of date.
func NextConjunction(date time.Time) time.Time { return defaultModule.NextConjunction(date) }
// NextEasternQuadrature 下一次东方照,取 date 所在当地民用日 / next eastern quadrature, on the local civil day of date.
func NextEasternQuadrature(date time.Time) time.Time {
return defaultModule.NextEasternQuadrature(date)
}
// NextOpposition 下一次冲日,取 date 所在当地民用日 / next opposition, on the local civil day of date.
func NextOpposition(date time.Time) time.Time { return defaultModule.NextOpposition(date) }
// NextProgradeToRetrograde 下一次顺行转逆行留,取 date 所在当地民用日 / next station from prograde to retrograde, on the local civil day of date.
func NextProgradeToRetrograde(date time.Time) time.Time {
return defaultModule.NextProgradeToRetrograde(date)
}
// NextRetrogradeToPrograde 下一次逆行转顺行留,取 date 所在当地民用日 / next station from retrograde to prograde, on the local civil day of date.
func NextRetrogradeToPrograde(date time.Time) time.Time {
return defaultModule.NextRetrogradeToPrograde(date)
}
// NextWesternQuadrature 下一次西方照,取 date 所在当地民用日 / next western quadrature, on the local civil day of date.
func NextWesternQuadrature(date time.Time) time.Time {
return defaultModule.NextWesternQuadrature(date)
}
// ParallacticAngle 火星视差角(天顶方向角) / Mars parallactic angle.
func ParallacticAngle(date time.Time, lon, lat float64) float64 {
return defaultModule.ParallacticAngle(date, lon, lat)
}
// ParallacticAngleN 火星视差角(天顶方向角)(n 变体) / n-parameterised Mars parallactic angle.
func ParallacticAngleN(date time.Time, lon, lat float64, n int) float64 {
return defaultModule.ParallacticAngleN(date, lon, lat, n)
}
// Phase 相位,被照亮比例 / phase, illuminated fraction.
func Phase(date time.Time) float64 { return defaultModule.Phase(date) }
// PhaseAngle 相位角,单位度 / phase angle in degrees.
func PhaseAngle(date time.Time) float64 { return defaultModule.PhaseAngle(date) }
// PhaseAngleN 相位角(n 变体),单位度 / n-parameterised phase angle in degrees.
func PhaseAngleN(date time.Time, n int) float64 { return defaultModule.PhaseAngleN(date, n) }
// PhaseN 相位(n 变体),被照亮比例 / n-parameterised phase, illuminated fraction.
func PhaseN(date time.Time, n int) float64 { return defaultModule.PhaseN(date, n) }
// Physical 火星物理观测参数 / physical observing parameters of Mars.
func Physical(date time.Time) PhysicalInfo { return defaultModule.Physical(date) }
// PhysicalN 火星物理观测参数(n 变体) / n-parameterised physical observing parameters of Mars.
func PhysicalN(date time.Time, n int) PhysicalInfo { return defaultModule.PhysicalN(date, n) }
// RiseTime 升起时间,取 date 所在当地民用日 / rise time, on the local civil day of date.
func RiseTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
return defaultModule.RiseTime(date, lon, lat, height, aero)
}
// RiseTimeN 升起时间(n 变体) / n-parameterised rise time.
func RiseTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
return defaultModule.RiseTimeN(date, lon, lat, height, aero, n)
}
// Semidiameter 火星视半径,单位角秒 / apparent Mars semidiameter in arcseconds.
func Semidiameter(date time.Time) float64 { return defaultModule.Semidiameter(date) }
// SemidiameterN 火星视半径(n 变体),单位角秒 / n-parameterised apparent Mars semidiameter in arcseconds.
func SemidiameterN(date time.Time, n int) float64 { return defaultModule.SemidiameterN(date, n) }
// SetTime 落下时间,取 date 所在当地民用日 / set time, on the local civil day of date.
func SetTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
return defaultModule.SetTime(date, lon, lat, height, aero)
}
// SetTimeN 落下时间(n 变体) / n-parameterised set time.
func SetTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
return defaultModule.SetTimeN(date, lon, lat, height, aero, n)
}
// SunDistance 日心距离 / Sun distance.
func SunDistance(date time.Time) float64 { return defaultModule.SunDistance(date) }
// SunDistanceN 太阳距离(n 变体) / n-parameterised Sun distance.
func SunDistanceN(date time.Time, n int) float64 { return defaultModule.SunDistanceN(date, n) }
// Zenith 天顶距 / zenith distance.
func Zenith(date time.Time, lon, lat float64) float64 { return defaultModule.Zenith(date, lon, lat) }
// ZenithN 天顶距(n 变体) / n-parameterised zenith distance.
func ZenithN(date time.Time, lon, lat float64, n int) float64 {
return defaultModule.ZenithN(date, lon, lat, n)
}
// ApparentMagnitude2018 视星等(Mallama & Hilton 2018 模型)/ apparent magnitude, Mallama & Hilton 2018 model.
func ApparentMagnitude2018(date time.Time) float64 { return defaultModule.ApparentMagnitude2018(date) }
+13
View File
@@ -0,0 +1,13 @@
package mars
import (
"b612.me/astro/internal/ephem"
)
// Mars 指定星历实例的计算模块 / computation module bound to an ephemeris instance.
type Mars struct{ inst *ephem.Instance }
// NewWithInstance 创建指定星历实例的模块,nil 使用全局模型 / create a module; nil uses the global model.
func NewWithInstance(inst *ephem.Instance) *Mars { return &Mars{inst: inst} }
var defaultModule Mars
+92
View File
@@ -0,0 +1,92 @@
package mars
import (
"b612.me/astro/basic"
"b612.me/astro/internal/ephem"
"testing"
"time"
)
type contextAPI interface {
Altitude(date time.Time, lon, lat float64) float64
AltitudeN(date time.Time, lon, lat float64, n int) float64
ApparentBo(date time.Time) float64
ApparentBoN(date time.Time, n int) float64
ApparentDec(date time.Time) float64
ApparentDecN(date time.Time, n int) float64
ApparentLo(date time.Time) float64
ApparentLoN(date time.Time, n int) float64
ApparentMagnitude(date time.Time) float64
ApparentMagnitudeN(date time.Time, n int) float64
ApparentRa(date time.Time) float64
ApparentRaDec(date time.Time) (float64, float64)
ApparentRaDecN(date time.Time, n int) (float64, float64)
ApparentRaN(date time.Time, n int) float64
AscendingNode(date time.Time) float64
AscendingNodeN(date time.Time, n int) float64
Azimuth(date time.Time, lon, lat float64) float64
AzimuthN(date time.Time, lon, lat float64, n int) float64
BrightLimbPositionAngle(date time.Time) float64
BrightLimbPositionAngleN(date time.Time, n int) float64
CulminationTime(date time.Time, lon float64) time.Time
CulminationTimeN(date time.Time, lon float64, n int) time.Time
DescendingNode(date time.Time) float64
DescendingNodeN(date time.Time, n int) float64
Diameter(date time.Time) float64
DiameterN(date time.Time, n int) float64
DownTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error)
DownTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error)
EarthDistance(date time.Time) float64
EarthDistanceN(date time.Time, n int) float64
HourAngle(date time.Time, lon float64) float64
HourAngleN(date time.Time, lon float64, n int) float64
IlluminatedFraction(date time.Time) float64
IlluminatedFractionN(date time.Time, n int) float64
LastConjunction(date time.Time) time.Time
LastEasternQuadrature(date time.Time) time.Time
LastOpposition(date time.Time) time.Time
LastProgradeToRetrograde(date time.Time) time.Time
LastRetrogradeToPrograde(date time.Time) time.Time
LastWesternQuadrature(date time.Time) time.Time
NextConjunction(date time.Time) time.Time
NextEasternQuadrature(date time.Time) time.Time
NextOpposition(date time.Time) time.Time
NextProgradeToRetrograde(date time.Time) time.Time
NextRetrogradeToPrograde(date time.Time) time.Time
NextWesternQuadrature(date time.Time) time.Time
ParallacticAngle(date time.Time, lon, lat float64) float64
ParallacticAngleN(date time.Time, lon, lat float64, n int) float64
Phase(date time.Time) float64
PhaseAngle(date time.Time) float64
PhaseAngleN(date time.Time, n int) float64
PhaseN(date time.Time, n int) float64
Physical(date time.Time) PhysicalInfo
PhysicalN(date time.Time, n int) PhysicalInfo
RiseTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error)
RiseTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error)
Semidiameter(date time.Time) float64
SemidiameterN(date time.Time, n int) float64
SetTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error)
SetTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error)
SunDistance(date time.Time) float64
SunDistanceN(date time.Time, n int) float64
Zenith(date time.Time, lon, lat float64) float64
ZenithN(date time.Time, lon, lat float64, n int) float64
}
var _ contextAPI = (*Mars)(nil)
func TestContextModuleIsolation(t *testing.T) {
previous := basic.GetEphemerisModel()
t.Cleanup(func() { basic.SetEphemerisModel(previous) })
date := time.Date(2024, 10, 6, 12, 0, 0, 0, time.UTC)
for _, model := range []ephem.Model{ephem.Legacy, ephem.Semianalytic} {
basic.SetEphemerisModel(basic.EphemerisModel(model))
want := ApparentLo(date)
module := NewWithInstance(ephem.NewModelInstance(model))
basic.SetEphemerisModel(basic.EphemerisModel(1 - int(model)))
if got := module.ApparentLo(date); got != want {
t.Fatalf("model %d: longitude %.12f, want %.12f", model, got, want)
}
}
}
+10 -10
View File
@@ -8,23 +8,23 @@ import (
)
// Semidiameter 火星视半径,单位角秒 / apparent Mars semidiameter in arcseconds.
func Semidiameter(date time.Time) float64 {
return SemidiameterN(date, -1)
func (module *Mars) Semidiameter(date time.Time) float64 {
return module.SemidiameterN(date, -1)
}
// SemidiameterN 火星视半径(截断版),单位角秒 / truncated apparent Mars semidiameter in arcseconds.
func SemidiameterN(date time.Time, n int) float64 {
// SemidiameterN 火星视半径(n 变体),单位角秒 / n-parameterised apparent Mars semidiameter in arcseconds.
func (module *Mars) SemidiameterN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsSemidiameterN(basic.UTC2TT(jd), n)
return basic.MarsSemidiameterNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// Diameter 火星视直径,单位角秒 / apparent Mars diameter in arcseconds.
func Diameter(date time.Time) float64 {
return DiameterN(date, -1)
func (module *Mars) Diameter(date time.Time) float64 {
return module.DiameterN(date, -1)
}
// DiameterN 火星视直径(截断版),单位角秒 / truncated apparent Mars diameter in arcseconds.
func DiameterN(date time.Time, n int) float64 {
// DiameterN 火星视直径(n 变体),单位角秒 / n-parameterised apparent Mars diameter in arcseconds.
func (module *Mars) DiameterN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsDiameterN(basic.UTC2TT(jd), n)
return basic.MarsDiameterNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
+4
View File
@@ -1,3 +1,7 @@
// Package mars 火星位置、升落、合冲、留、方照、相位、视星等、视直径与物理星历,角度单位为度,距离单位为 AU。
// Package mars covers Mars position, rise/set, conjunction, opposition, station, quadrature, phase, magnitude, apparent diameter and physical ephemeris; angles are degrees, distances are AU.
// 求值接口的 N 后缀是 n 变体:n < 0 取完整级数;半解析模型下所有 n >= 0 使用同一张快速表;Legacy 按 n 截断。
// The N suffix marks an n-variant: n < 0 uses the full series, every n >= 0 uses one fast table under the semianalytic model, and Legacy truncates by n.
// 时间参数:位置、距离、星等与物理量接口的 date 是绝对时刻,其所在时区参与地方时换算;升落、中天、晨昏与 Next/Last 事件接口按 date 所在时区的当地民用日求解,返回时刻保持该时区。
// Time arguments: date is an absolute instant for position, distance, magnitude and physical-quantity entry points, and its zone takes part in local-time conversion; rise/set, culmination, twilight and Next/Last event entry points solve for the local civil day in date's zone and return instants keeping that zone.
package mars
+68 -148
View File
@@ -1,11 +1,11 @@
package mars
import (
"b612.me/astro/basic"
"b612.me/astro/calendar"
"b612.me/astro/planet"
"errors"
"time"
"b612.me/astro/basic"
"b612.me/astro/calendar"
)
var (
@@ -31,136 +31,94 @@ func riseSetResult(date time.Time, jd float64, err error) (time.Time, error) {
}
// ApparentLo 视黄经 / apparent ecliptic longitude.
//
// 返回火星在 date 对应绝对时刻的瞬时视黄经,单位度。
// Returns the apparent ecliptic longitude of Mars at the instant represented by date, in degrees.
func ApparentLo(date time.Time) float64 {
func (module *Mars) ApparentLo(date time.Time) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentLo(basic.UTC2TT(jd))
return basic.MarsApparentLoWithInstance(basic.UTC2TT(jd), module.inst)
}
// ApparentBo 视黄纬 / apparent ecliptic latitude.
//
// 返回火星在 date 对应绝对时刻的瞬时视黄纬,单位度。
// Returns the apparent ecliptic latitude of Mars at the instant represented by date, in degrees.
func ApparentBo(date time.Time) float64 {
func (module *Mars) ApparentBo(date time.Time) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentBo(basic.UTC2TT(jd))
return basic.MarsApparentBoWithInstance(basic.UTC2TT(jd), module.inst)
}
// ApparentRa 视赤经 / apparent right ascension.
//
// 返回火星在 date 对应绝对时刻的瞬时视赤经,单位度。
// Returns the apparent right ascension of Mars at the instant represented by date, in degrees.
func ApparentRa(date time.Time) float64 {
func (module *Mars) ApparentRa(date time.Time) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentRa(basic.UTC2TT(jd))
return basic.MarsApparentRaWithInstance(basic.UTC2TT(jd), module.inst)
}
// ApparentDec 视赤纬 / apparent declination.
//
// 返回火星在 date 对应绝对时刻的瞬时视赤纬,单位度。
// Returns the apparent declination of Mars at the instant represented by date, in degrees.
func ApparentDec(date time.Time) float64 {
func (module *Mars) ApparentDec(date time.Time) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentDec(basic.UTC2TT(jd))
return basic.MarsApparentDecWithInstance(basic.UTC2TT(jd), module.inst)
}
// ApparentRaDec 视赤经、视赤纬 / apparent right ascension and declination.
//
// 返回火星在 date 对应绝对时刻的瞬时视赤经与视赤纬,单位度。
// Returns the apparent right ascension and declination of Mars at the instant represented by date, in degrees.
func ApparentRaDec(date time.Time) (float64, float64) {
func (module *Mars) ApparentRaDec(date time.Time) (float64, float64) {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentRaDec(basic.UTC2TT(jd))
return basic.MarsApparentRaDecWithInstance(basic.UTC2TT(jd), module.inst)
}
// ApparentMagnitude 视星等 / apparent magnitude.
//
// 返回火星在 date 对应绝对时刻的视星等。
// Returns the apparent visual magnitude of Mars at the instant represented by date.
func ApparentMagnitude(date time.Time) float64 {
func (module *Mars) ApparentMagnitude(date time.Time) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsMag(basic.UTC2TT(jd))
return basic.MarsMagWithInstance(basic.UTC2TT(jd), module.inst)
}
// EarthDistance 地心距离 / Earth distance.
//
// 返回火星在 date 对应绝对时刻到地球的距离,单位 AU。
// Returns the distance from Mars to Earth at the instant represented by date, in astronomical units.
func EarthDistance(date time.Time) float64 {
func (module *Mars) EarthDistance(date time.Time) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.EarthMarsAway(basic.UTC2TT(jd))
return basic.EarthMarsAwayWithInstance(basic.UTC2TT(jd), module.inst)
}
// SunDistance 日心距离 / Sun distance.
//
// 返回火星在 date 对应绝对时刻到太阳的距离,单位 AU。
// Returns the distance from Mars to the Sun at the instant represented by date, in astronomical units.
func SunDistance(date time.Time) float64 {
func (module *Mars) SunDistance(date time.Time) float64 {
jd := calendar.Date2JD(date.UTC())
return planet.WherePlanet(3, 2, basic.UTC2TT(jd))
return basic.PlanetCoordinateWithInstance(3, 2, basic.UTC2TT(jd), module.inst)
}
// Altitude 高度角 / altitude.
//
// date 表示观测时刻,会读取其时区参与地方时计算;lon 为观测者经度,东正西负;lat 为观测者纬度,北正南负。返回值单位度。
// date is the observing instant and its zone offset participates in local-time calculations. lon is east-positive longitude, lat is north-positive latitude, and the result is in degrees.
func Altitude(date time.Time, lon, lat float64) float64 {
// Altitude 站心视高度角,不含大气折射 / topocentric apparent altitude without refraction.
func (module *Mars) Altitude(date time.Time, lon, lat float64) float64 {
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
return basic.MarsHeight(localJD, lon, lat, timezone)
return basic.MarsHeightWithInstance(localJD, lon, lat, timezone, module.inst)
}
// Zenith 天顶距 / zenith distance.
//
// 参数与 Altitude 相同,返回值为对应时刻的天顶距,单位度。
// Uses the same inputs as Altitude and returns the zenith distance in degrees.
func Zenith(date time.Time, lon, lat float64) float64 {
return 90 - Altitude(date, lon, lat)
func (module *Mars) Zenith(date time.Time, lon, lat float64) float64 {
return 90 - module.Altitude(date, lon, lat)
}
// Azimuth 方位角 / azimuth.
//
// date 表示观测时刻,会读取其时区参与地方时计算;lon 为观测者经度,东正西负;lat 为观测者纬度,北正南负。返回值按正北为 0°、向东增加。
// date is the observing instant and its zone offset participates in local-time calculations. lon is east-positive longitude, lat is north-positive latitude, and azimuth is measured from north toward east.
func Azimuth(date time.Time, lon, lat float64) float64 {
// Azimuth 站心方位角 / topocentric azimuth.
func (module *Mars) Azimuth(date time.Time, lon, lat float64) float64 {
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
return basic.MarsAzimuth(localJD, lon, lat, timezone)
return basic.MarsAzimuthWithInstance(localJD, lon, lat, timezone, module.inst)
}
// HourAngle 时角 / hour angle.
//
// date 表示观测时刻,会读取其时区参与地方时计算;lon 为观测者经度,东正西负。返回值单位度。
// date is the observing instant and its zone offset participates in local-time calculations. lon is east-positive longitude and the returned hour angle is in degrees.
func HourAngle(date time.Time, lon float64) float64 {
// HourAngle 地心视时角,不含站心视差 / geocentric apparent hour angle without topocentric parallax.
func (module *Mars) HourAngle(date time.Time, lon float64) float64 {
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
return basic.MarsHourAngle(localJD, lon, timezone)
return basic.MarsHourAngleWithInstance(localJD, lon, timezone, module.inst)
}
// CulminationTime 中天时刻 / culmination time.
//
// date 取其所在时区的当地日期,返回值保持相同时区;lon 为观测者经度,东正西负。
// date is interpreted on its local civil day and the result keeps the same time zone. lon is east-positive longitude.
func CulminationTime(date time.Time, lon float64) time.Time {
func (module *Mars) CulminationTime(date time.Time, lon float64) time.Time {
date = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
calcJD := basic.MarsCulminationTime(localJD, lon, timezone) - timezone/24.00
calcJD := basic.MarsCulminationTimeWithInstance(localJD, lon, timezone, module.inst) - timezone/24.00
return basic.JD2DateByZone(calcJD, date.Location(), false)
}
// RiseTime 升起时间 / rise time.
//
// date 取其所在时区的当地日期,返回值保持相同时区;lon 为东正西负经度,lat 为北正南负纬度;height 为观测点椭球高(大地高,米);aero 为 true 时加入标准大气折射。
// date is interpreted on its local civil day and the result keeps the same time zone. lon is east-positive longitude, lat is north-positive latitude, height is observer elevation in meters, and aero enables standard atmospheric refraction.
func RiseTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
func (module *Mars) RiseTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
var aeroFloat float64
if aero {
aeroFloat = 1
@@ -169,25 +127,17 @@ func RiseTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, e
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
riseJD, err := basic.MarsRiseTime(localJD, lon, lat, timezone, aeroFloat, height)
riseJD, err := basic.MarsRiseTimeWithInstance(localJD, lon, lat, timezone, aeroFloat, height, module.inst)
return riseSetResult(date, riseJD, err)
}
// DownTime 落下时间别名 / deprecated set-time alias.
//
// Deprecated: use SetTime instead.
//
// 参数与 SetTime 相同,仅为兼容旧接口保留。
// Same as SetTime and kept only for backward compatibility.
func DownTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
return SetTime(date, lon, lat, height, aero)
func (module *Mars) DownTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
return module.SetTime(date, lon, lat, height, aero)
}
// SetTime 落下时间 / set time.
//
// 参数与 RiseTime 相同,返回给定当地日期内的落下时刻。
// Uses the same inputs as RiseTime and returns the set time on the corresponding local civil day.
func SetTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
func (module *Mars) SetTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, error) {
var aeroFloat float64
if aero {
aeroFloat = 1
@@ -196,114 +146,84 @@ func SetTime(date time.Time, lon, lat, height float64, aero bool) (time.Time, er
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
riseJD, err := basic.MarsSetTime(localJD, lon, lat, timezone, aeroFloat, height)
riseJD, err := basic.MarsSetTimeWithInstance(localJD, lon, lat, timezone, aeroFloat, height, module.inst)
return riseSetResult(date, riseJD, err)
}
// LastConjunction 上一次合日 / previous conjunction with the Sun.
//
// 返回 date 当前或之前最近一次与太阳的合日时刻,结果保持 date 的时区。
// Returns the nearest conjunction with the Sun at or before date, keeping date's time zone.
func LastConjunction(date time.Time) time.Time {
func (module *Mars) LastConjunction(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.LastMarsConjunction(jde), date.Location(), false)
return basic.JD2DateByZone(basic.LastMarsConjunctionWithInstance(jde, module.inst), date.Location(), false)
}
// NextConjunction 下一次合日 / next conjunction with the Sun.
//
// 返回 date 当前或之后最近一次与太阳的合日时刻,结果保持 date 的时区。
// Returns the nearest conjunction with the Sun at or after date, keeping date's time zone.
func NextConjunction(date time.Time) time.Time {
func (module *Mars) NextConjunction(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.NextMarsConjunction(jde), date.Location(), false)
return basic.JD2DateByZone(basic.NextMarsConjunctionWithInstance(jde, module.inst), date.Location(), false)
}
// LastOpposition 上一次冲日 / previous opposition.
//
// 返回 date 当前或之前最近一次冲日时刻,结果保持 date 的时区。
// Returns the nearest opposition at or before date, keeping date's time zone.
func LastOpposition(date time.Time) time.Time {
func (module *Mars) LastOpposition(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.LastMarsOpposition(jde), date.Location(), false)
return basic.JD2DateByZone(basic.LastMarsOppositionWithInstance(jde, module.inst), date.Location(), false)
}
// NextOpposition 下一次冲日 / next opposition.
//
// 返回 date 当前或之后最近一次冲日时刻,结果保持 date 的时区。
// Returns the nearest opposition at or after date, keeping date's time zone.
func NextOpposition(date time.Time) time.Time {
func (module *Mars) NextOpposition(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.NextMarsOpposition(jde), date.Location(), false)
return basic.JD2DateByZone(basic.NextMarsOppositionWithInstance(jde, module.inst), date.Location(), false)
}
// LastProgradeToRetrograde 上一次顺行转逆行留 / previous station from prograde to retrograde.
//
// 返回 date 当前或之前最近一次由顺行转为逆行的留时刻,结果保持 date 的时区。
// Returns the nearest station at or before date where motion changes from prograde to retrograde, keeping date's time zone.
func LastProgradeToRetrograde(date time.Time) time.Time {
func (module *Mars) LastProgradeToRetrograde(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.LastMarsProgradeToRetrograde(jde), date.Location(), false)
return basic.JD2DateByZone(basic.LastMarsProgradeToRetrogradeWithInstance(jde, module.inst), date.Location(), false)
}
// NextProgradeToRetrograde 下一次顺行转逆行留 / next station from prograde to retrograde.
//
// 返回 date 当前或之后最近一次由顺行转为逆行的留时刻,结果保持 date 的时区。
// Returns the nearest station at or after date where motion changes from prograde to retrograde, keeping date's time zone.
func NextProgradeToRetrograde(date time.Time) time.Time {
func (module *Mars) NextProgradeToRetrograde(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.NextMarsProgradeToRetrograde(jde), date.Location(), false)
return basic.JD2DateByZone(basic.NextMarsProgradeToRetrogradeWithInstance(jde, module.inst), date.Location(), false)
}
// LastRetrogradeToPrograde 上一次逆行转顺行留 / previous station from retrograde to prograde.
//
// 返回 date 当前或之前最近一次由逆行转为顺行的留时刻,结果保持 date 的时区。
// Returns the nearest station at or before date where motion changes from retrograde to prograde, keeping date's time zone.
func LastRetrogradeToPrograde(date time.Time) time.Time {
func (module *Mars) LastRetrogradeToPrograde(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.LastMarsRetrogradeToPrograde(jde), date.Location(), false)
return basic.JD2DateByZone(basic.LastMarsRetrogradeToProgradeWithInstance(jde, module.inst), date.Location(), false)
}
// NextRetrogradeToPrograde 下一次逆行转顺行留 / next station from retrograde to prograde.
//
// 返回 date 当前或之后最近一次由逆行转为顺行的留时刻,结果保持 date 的时区。
// Returns the nearest station at or after date where motion changes from retrograde to prograde, keeping date's time zone.
func NextRetrogradeToPrograde(date time.Time) time.Time {
func (module *Mars) NextRetrogradeToPrograde(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.NextMarsRetrogradeToPrograde(jde), date.Location(), false)
return basic.JD2DateByZone(basic.NextMarsRetrogradeToProgradeWithInstance(jde, module.inst), date.Location(), false)
}
// LastEasternQuadrature 上一次东方照 / previous eastern quadrature.
//
// 返回 date 当前或之前最近一次东方照时刻,结果保持 date 的时区。
// Returns the nearest eastern quadrature at or before date, keeping date's time zone.
func LastEasternQuadrature(date time.Time) time.Time {
func (module *Mars) LastEasternQuadrature(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.LastMarsEasternQuadrature(jde), date.Location(), false)
return basic.JD2DateByZone(basic.LastMarsEasternQuadratureWithInstance(jde, module.inst), date.Location(), false)
}
// NextEasternQuadrature 下一次东方照 / next eastern quadrature.
//
// 返回 date 当前或之后最近一次东方照时刻,结果保持 date 的时区。
// Returns the nearest eastern quadrature at or after date, keeping date's time zone.
func NextEasternQuadrature(date time.Time) time.Time {
func (module *Mars) NextEasternQuadrature(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.NextMarsEasternQuadrature(jde), date.Location(), false)
return basic.JD2DateByZone(basic.NextMarsEasternQuadratureWithInstance(jde, module.inst), date.Location(), false)
}
// LastWesternQuadrature 上一次西方照 / previous western quadrature.
//
// 返回 date 当前或之前最近一次西方照时刻,结果保持 date 的时区。
// Returns the nearest western quadrature at or before date, keeping date's time zone.
func LastWesternQuadrature(date time.Time) time.Time {
func (module *Mars) LastWesternQuadrature(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.LastMarsWesternQuadrature(jde), date.Location(), false)
return basic.JD2DateByZone(basic.LastMarsWesternQuadratureWithInstance(jde, module.inst), date.Location(), false)
}
// NextWesternQuadrature 下一次西方照 / next western quadrature.
//
// 返回 date 当前或之后最近一次西方照时刻,结果保持 date 的时区。
// Returns the nearest western quadrature at or after date, keeping date's time zone.
func NextWesternQuadrature(date time.Time) time.Time {
func (module *Mars) NextWesternQuadrature(date time.Time) time.Time {
jde := basic.UTC2TT(basic.Date2JD(date.UTC()))
return basic.JD2DateByZone(basic.NextMarsWesternQuadrature(jde), date.Location(), false)
return basic.JD2DateByZone(basic.NextMarsWesternQuadratureWithInstance(jde, module.inst), date.Location(), false)
}
// ApparentMagnitude2018 视星等(Mallama & Hilton 2018 模型)/ apparent magnitude, Mallama & Hilton 2018 model.
func (module *Mars) ApparentMagnitude2018(date time.Time) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsMag2018WithInstance(basic.UTC2TT(jd), module.inst)
}
+10 -10
View File
@@ -8,23 +8,23 @@ import (
)
// AscendingNode 火星升交点黄经 / ascending node longitude of Mars.
func AscendingNode(date time.Time) float64 {
return AscendingNodeN(date, -1)
func (module *Mars) AscendingNode(date time.Time) float64 {
return module.AscendingNodeN(date, -1)
}
// AscendingNodeN 火星升交点黄经(截断版) / truncated ascending node longitude of Mars.
func AscendingNodeN(date time.Time, n int) float64 {
// AscendingNodeN 火星升交点黄经(n 变体) / n-parameterised ascending node longitude of Mars.
func (module *Mars) AscendingNodeN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsAscendingNodeN(basic.UTC2TT(jd), n)
return basic.MarsAscendingNodeNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// DescendingNode 火星降交点黄经 / descending node longitude of Mars.
func DescendingNode(date time.Time) float64 {
return DescendingNodeN(date, -1)
func (module *Mars) DescendingNode(date time.Time) float64 {
return module.DescendingNodeN(date, -1)
}
// DescendingNodeN 火星降交点黄经(截断版) / truncated descending node longitude of Mars.
func DescendingNodeN(date time.Time, n int) float64 {
// DescendingNodeN 火星降交点黄经(n 变体) / n-parameterised descending node longitude of Mars.
func (module *Mars) DescendingNodeN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsDescendingNodeN(basic.UTC2TT(jd), n)
return basic.MarsDescendingNodeNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
+5 -5
View File
@@ -7,11 +7,11 @@ import (
)
// ParallacticAngle 火星视差角(天顶方向角) / Mars parallactic angle.
func ParallacticAngle(date time.Time, lon, lat float64) float64 {
return basic.ParallacticAngleByHourAngle(HourAngle(date, lon), ApparentDec(date), lat)
func (module *Mars) ParallacticAngle(date time.Time, lon, lat float64) float64 {
return basic.ParallacticAngleByHourAngle(module.HourAngle(date, lon), module.ApparentDec(date), lat)
}
// ParallacticAngleN 截断项火星视差角(天顶方向角) / truncated Mars parallactic angle.
func ParallacticAngleN(date time.Time, lon, lat float64, n int) float64 {
return basic.ParallacticAngleByHourAngle(HourAngleN(date, lon, n), ApparentDecN(date, n), lat)
// ParallacticAngleN 火星视差角(天顶方向角)(n 变体) / n-parameterised Mars parallactic angle.
func (module *Mars) ParallacticAngleN(date time.Time, lon, lat float64, n int) float64 {
return basic.ParallacticAngleByHourAngle(module.HourAngleN(date, lon, n), module.ApparentDecN(date, n), lat)
}
+20 -20
View File
@@ -8,43 +8,43 @@ import (
)
// PhaseAngle 相位角,单位度 / phase angle in degrees.
func PhaseAngle(date time.Time) float64 {
return PhaseAngleN(date, -1)
func (module *Mars) PhaseAngle(date time.Time) float64 {
return module.PhaseAngleN(date, -1)
}
// PhaseAngleN 相位角(截断版),单位度 / truncated phase angle in degrees.
func PhaseAngleN(date time.Time, n int) float64 {
return basic.MarsPhaseAngleN(phaseJD(date), n)
// PhaseAngleN 相位角(n 变体),单位度 / n-parameterised phase angle in degrees.
func (module *Mars) PhaseAngleN(date time.Time, n int) float64 {
return basic.MarsPhaseAngleNWithInstance(phaseJD(date), n, module.inst)
}
// IlluminatedFraction 被照亮比例 / illuminated fraction.
func IlluminatedFraction(date time.Time) float64 {
return IlluminatedFractionN(date, -1)
func (module *Mars) IlluminatedFraction(date time.Time) float64 {
return module.IlluminatedFractionN(date, -1)
}
// IlluminatedFractionN 被照亮比例(截断版) / truncated illuminated fraction.
func IlluminatedFractionN(date time.Time, n int) float64 {
return basic.MarsIlluminatedFractionN(phaseJD(date), n)
// IlluminatedFractionN 被照亮比例(n 变体) / n-parameterised illuminated fraction.
func (module *Mars) IlluminatedFractionN(date time.Time, n int) float64 {
return basic.MarsIlluminatedFractionNWithInstance(phaseJD(date), n, module.inst)
}
// Phase 相位,被照亮比例 / phase, illuminated fraction.
func Phase(date time.Time) float64 {
return IlluminatedFraction(date)
func (module *Mars) Phase(date time.Time) float64 {
return module.IlluminatedFraction(date)
}
// PhaseN 相位(截断版),被照亮比例 / truncated phase, illuminated fraction.
func PhaseN(date time.Time, n int) float64 {
return IlluminatedFractionN(date, n)
// PhaseN 相位(n 变体),被照亮比例 / n-parameterised phase, illuminated fraction.
func (module *Mars) PhaseN(date time.Time, n int) float64 {
return module.IlluminatedFractionN(date, n)
}
// BrightLimbPositionAngle 亮面中心位置角,单位度 / bright limb position angle in degrees.
func BrightLimbPositionAngle(date time.Time) float64 {
return BrightLimbPositionAngleN(date, -1)
func (module *Mars) BrightLimbPositionAngle(date time.Time) float64 {
return module.BrightLimbPositionAngleN(date, -1)
}
// BrightLimbPositionAngleN 亮面中心位置角(截断版),单位度 / truncated bright limb position angle in degrees.
func BrightLimbPositionAngleN(date time.Time, n int) float64 {
return basic.MarsBrightLimbPositionAngleN(phaseJD(date), n)
// BrightLimbPositionAngleN 亮面中心位置角(n 变体),单位度 / n-parameterised bright limb position angle in degrees.
func (module *Mars) BrightLimbPositionAngleN(date time.Time, n int) float64 {
return basic.MarsBrightLimbPositionAngleNWithInstance(phaseJD(date), n, module.inst)
}
func phaseJD(date time.Time) float64 {
+5 -5
View File
@@ -21,14 +21,14 @@ type PhysicalInfo struct {
}
// Physical 火星物理观测参数 / physical observing parameters of Mars.
func Physical(date time.Time) PhysicalInfo {
return PhysicalN(date, -1)
func (module *Mars) Physical(date time.Time) PhysicalInfo {
return module.PhysicalN(date, -1)
}
// PhysicalN 火星物理观测参数(截断版) / truncated physical observing parameters of Mars.
func PhysicalN(date time.Time, n int) PhysicalInfo {
// PhysicalN 火星物理观测参数(n 变体) / n-parameterised physical observing parameters of Mars.
func (module *Mars) PhysicalN(date time.Time, n int) PhysicalInfo {
jd := basic.Date2JD(date.UTC())
info := basic.MarsPhysicalN(basic.UTC2TT(jd), n)
info := basic.MarsPhysicalNWithInstance(basic.UTC2TT(jd), n, module.inst)
return PhysicalInfo{
SubEarthLongitude: info.SubEarthLongitude,
SubEarthLatitude: info.SubEarthLatitude,
+33
View File
@@ -0,0 +1,33 @@
package mars
import (
"time"
"b612.me/astro/basic"
)
// RiseTimeWithAtmosphere 火星升起时刻,按给定气压(hPa)与气温(°C)计算大气折射 / rise time with explicit pressure and temperature.
func (module *Mars) RiseTimeWithAtmosphere(date time.Time, lon, lat, height, pressureHPa, temperatureC float64) (time.Time, error) {
date = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
_, loc := date.Zone()
jd, err := basic.MarsRiseTimeWithAtmosphere(basic.Date2JD(date), lon, lat, float64(loc)/3600.0, height, pressureHPa, temperatureC, module.inst)
return riseSetResult(date, jd, err)
}
// SetTimeWithAtmosphere 火星落下时刻,按给定气压(hPa)与气温(°C)计算大气折射 / set time with explicit pressure and temperature.
func (module *Mars) SetTimeWithAtmosphere(date time.Time, lon, lat, height, pressureHPa, temperatureC float64) (time.Time, error) {
date = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
_, loc := date.Zone()
jd, err := basic.MarsSetTimeWithAtmosphere(basic.Date2JD(date), lon, lat, float64(loc)/3600.0, height, pressureHPa, temperatureC, module.inst)
return riseSetResult(date, jd, err)
}
// RiseTimeWithAtmosphere 火星升起时刻,按给定气压(hPa)与气温(°C)计算大气折射 / rise time with explicit pressure and temperature.
func RiseTimeWithAtmosphere(date time.Time, lon, lat, height, pressureHPa, temperatureC float64) (time.Time, error) {
return defaultModule.RiseTimeWithAtmosphere(date, lon, lat, height, pressureHPa, temperatureC)
}
// SetTimeWithAtmosphere 火星落下时刻,按给定气压(hPa)与气温(°C)计算大气折射 / set time with explicit pressure and temperature.
func SetTimeWithAtmosphere(date time.Time, lon, lat, height, pressureHPa, temperatureC float64) (time.Time, error) {
return defaultModule.SetTimeWithAtmosphere(date, lon, lat, height, pressureHPa, temperatureC)
}
+33
View File
@@ -0,0 +1,33 @@
package mars
import (
"math"
"testing"
"time"
)
func TestRiseTimeWithAtmosphere(t *testing.T) {
loc := time.FixedZone("CST", 8*3600)
date := time.Date(2025, 1, 1, 0, 0, 0, 0, loc)
plain, err := RiseTime(date, 116.4, 39.9, 0, true)
if err != nil {
t.Fatal(err)
}
std, err := RiseTimeWithAtmosphere(date, 116.4, 39.9, 0, 1010, 10)
if err != nil {
t.Fatal(err)
}
dense, err := RiseTimeWithAtmosphere(date, 116.4, 39.9, 0, 1040, -30)
if err != nil {
t.Fatal(err)
}
if d := math.Abs(std.Sub(plain).Seconds()); d > 5 {
t.Errorf("standard weather differs by %.2f s", d)
}
if !dense.Before(std) {
t.Errorf("dense air must rise earlier: %v vs %v", dense, std)
}
if _, err := RiseTimeWithAtmosphere(date, 116.4, 39.9, 0, -1, 10); err == nil {
t.Error("invalid pressure must fail")
}
}
+48 -49
View File
@@ -5,100 +5,99 @@ import (
"b612.me/astro/basic"
"b612.me/astro/calendar"
"b612.me/astro/planet"
)
// N variants keep the same semantics as the non-N APIs; n < 0 means full series.
// ApparentLoN 视黄经(截断版) / truncated apparent ecliptic longitude.
func ApparentLoN(date time.Time, n int) float64 {
// ApparentLoN 视黄经(n 变体) / n-parameterised apparent ecliptic longitude.
func (module *Mars) ApparentLoN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentLoN(basic.UTC2TT(jd), n)
return basic.MarsApparentLoNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// ApparentBoN 视黄纬(截断版) / truncated apparent ecliptic latitude.
func ApparentBoN(date time.Time, n int) float64 {
// ApparentBoN 视黄纬(n 变体) / n-parameterised apparent ecliptic latitude.
func (module *Mars) ApparentBoN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentBoN(basic.UTC2TT(jd), n)
return basic.MarsApparentBoNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// ApparentRaN 视赤经(截断版) / truncated apparent right ascension.
func ApparentRaN(date time.Time, n int) float64 {
// ApparentRaN 视赤经(n 变体) / n-parameterised apparent right ascension.
func (module *Mars) ApparentRaN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentRaN(basic.UTC2TT(jd), n)
return basic.MarsApparentRaNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// ApparentDecN 视赤纬(截断版) / truncated apparent declination.
func ApparentDecN(date time.Time, n int) float64 {
// ApparentDecN 视赤纬(n 变体) / n-parameterised apparent declination.
func (module *Mars) ApparentDecN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentDecN(basic.UTC2TT(jd), n)
return basic.MarsApparentDecNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// ApparentRaDecN 视赤经赤纬(截断版) / truncated apparent right ascension and declination.
func ApparentRaDecN(date time.Time, n int) (float64, float64) {
// ApparentRaDecN 视赤经赤纬(n 变体) / n-parameterised apparent right ascension and declination.
func (module *Mars) ApparentRaDecN(date time.Time, n int) (float64, float64) {
jd := calendar.Date2JD(date.UTC())
return basic.MarsApparentRaDecN(basic.UTC2TT(jd), n)
return basic.MarsApparentRaDecNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// ApparentMagnitudeN 视星等(截断版) / truncated apparent magnitude.
func ApparentMagnitudeN(date time.Time, n int) float64 {
// ApparentMagnitudeN 视星等(n 变体) / n-parameterised apparent magnitude.
func (module *Mars) ApparentMagnitudeN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.MarsMagN(basic.UTC2TT(jd), n)
return basic.MarsMagNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// EarthDistanceN 地球距离(截断版) / truncated Earth distance.
func EarthDistanceN(date time.Time, n int) float64 {
// EarthDistanceN 地球距离(n 变体) / n-parameterised Earth distance.
func (module *Mars) EarthDistanceN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return basic.EarthMarsAwayN(basic.UTC2TT(jd), n)
return basic.EarthMarsAwayNWithInstance(basic.UTC2TT(jd), n, module.inst)
}
// SunDistanceN 太阳距离(截断版) / truncated Sun distance.
func SunDistanceN(date time.Time, n int) float64 {
// SunDistanceN 太阳距离(n 变体) / n-parameterised Sun distance.
func (module *Mars) SunDistanceN(date time.Time, n int) float64 {
jd := calendar.Date2JD(date.UTC())
return planet.WherePlanetN(3, 2, basic.UTC2TT(jd), n)
return basic.PlanetCoordinateNWithInstance(3, 2, basic.UTC2TT(jd), n, module.inst)
}
// AltitudeN 高度角(截断版) / truncated altitude angle.
func AltitudeN(date time.Time, lon, lat float64, n int) float64 {
// AltitudeN 站心视高度角(n 变体) / n-parameterised topocentric apparent altitude.
func (module *Mars) AltitudeN(date time.Time, lon, lat float64, n int) float64 {
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
return basic.MarsHeightN(localJD, lon, lat, timezone, n)
return basic.MarsHeightNWithInstance(localJD, lon, lat, timezone, n, module.inst)
}
// ZenithN 天顶距(截断版) / truncated zenith distance.
func ZenithN(date time.Time, lon, lat float64, n int) float64 {
return 90 - AltitudeN(date, lon, lat, n)
// ZenithN 天顶距(n 变体) / n-parameterised zenith distance.
func (module *Mars) ZenithN(date time.Time, lon, lat float64, n int) float64 {
return 90 - module.AltitudeN(date, lon, lat, n)
}
// AzimuthN 方位角(截断版) / truncated azimuth angle.
func AzimuthN(date time.Time, lon, lat float64, n int) float64 {
// AzimuthN 站心方位角(n 变体) / n-parameterised topocentric azimuth.
func (module *Mars) AzimuthN(date time.Time, lon, lat float64, n int) float64 {
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
return basic.MarsAzimuthN(localJD, lon, lat, timezone, n)
return basic.MarsAzimuthNWithInstance(localJD, lon, lat, timezone, n, module.inst)
}
// HourAngleN 时角(截断版) / truncated hour angle.
func HourAngleN(date time.Time, lon float64, n int) float64 {
// HourAngleN 时角(n 变体) / n-parameterised hour angle.
func (module *Mars) HourAngleN(date time.Time, lon float64, n int) float64 {
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
return basic.MarsHourAngleN(localJD, lon, timezone, n)
return basic.MarsHourAngleNWithInstance(localJD, lon, timezone, n, module.inst)
}
// CulminationTimeN 中天时间(截断版) / truncated culmination time.
func CulminationTimeN(date time.Time, lon float64, n int) time.Time {
// CulminationTimeN 中天时间(n 变体) / n-parameterised culmination time.
func (module *Mars) CulminationTimeN(date time.Time, lon float64, n int) time.Time {
date = time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location())
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
calcJD := basic.MarsCulminationTimeN(localJD, lon, timezone, n) - timezone/24.0
calcJD := basic.MarsCulminationTimeNWithInstance(localJD, lon, timezone, n, module.inst) - timezone/24.0
return basic.JD2DateByZone(calcJD, date.Location(), false)
}
// RiseTimeN 升起时间(截断版) / truncated rise time.
func RiseTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
// RiseTimeN 升起时间(n 变体) / n-parameterised rise time.
func (module *Mars) RiseTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
var aeroFloat float64
if aero {
aeroFloat = 1
@@ -107,17 +106,17 @@ func RiseTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
riseJD, err := basic.MarsRiseTimeN(localJD, lon, lat, timezone, aeroFloat, height, n)
riseJD, err := basic.MarsRiseTimeNWithInstance(localJD, lon, lat, timezone, aeroFloat, height, n, module.inst)
return riseSetResult(date, riseJD, err)
}
// DownTimeN 落下时间别名(截断版) / truncated down-time alias.
func DownTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
return SetTimeN(date, lon, lat, height, aero, n)
// DownTimeN 落下时间别名(n 变体) / n-parameterised down-time alias.
func (module *Mars) DownTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
return module.SetTimeN(date, lon, lat, height, aero, n)
}
// SetTimeN 落下时间(截断版) / truncated set time.
func SetTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
// SetTimeN 落下时间(n 变体) / n-parameterised set time.
func (module *Mars) SetTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.Time, error) {
var aeroFloat float64
if aero {
aeroFloat = 1
@@ -126,6 +125,6 @@ func SetTimeN(date time.Time, lon, lat, height float64, aero bool, n int) (time.
localJD := basic.Date2JD(date)
_, loc := date.Zone()
timezone := float64(loc) / 3600.0
riseJD, err := basic.MarsSetTimeN(localJD, lon, lat, timezone, aeroFloat, height, n)
riseJD, err := basic.MarsSetTimeNWithInstance(localJD, lon, lat, timezone, aeroFloat, height, n, module.inst)
return riseSetResult(date, riseJD, err)
}