feat: 完善水星与金星全球凌日搜索及制图导出
- 基于平均下合周期与节点相位预筛候选,减少无效星历计算;跳过无法求解的单个会合周期,避免有限覆盖星历导致搜索提前终止 - 引入影轴 γ、半影半径及地球尺度几何判定,结合站心可见性识别地心无接触、仅部分地区可见的掠凌 - 添加金星 243 年、水星 46 年周期族编号,并明确编号适用范围及未分配时的零值语义 - 为 SVG、GeoJSON 和 KML 增加站心部分凌日可见区,适配接触等时线、几何元数据、图层样式及取景;为地心无接触凌日事件增加正射图,按可见区球面面积加权居中
This commit is contained in:
41 files changed
+1554
-307
No files matched your search
@@ -0,0 +1,69 @@
|
||||
package basic
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"b612.me/astro/internal/ephem"
|
||||
)
|
||||
|
||||
func planetTransitPredictedSeason(seedTT float64, cfg planetTransitConfig, inst *Instance) bool {
|
||||
centuries := (seedTT - 2451545) / 36525
|
||||
if inst != nil && inst.Model() == ephem.Custom || centuries < -40 || centuries > 20 {
|
||||
return true
|
||||
}
|
||||
node := 76.679920 + centuries*(0.9011206+centuries*(0.00040618-0.000000093*centuries))
|
||||
if cfg.planetIndex == 1 {
|
||||
node = 48.330893 + centuries*(1.1861883+centuries*(0.00017542+0.000000215*centuries))
|
||||
}
|
||||
solar := 280.46646 + centuries*(36000.76983+0.0003032*centuries)
|
||||
phase := math.Abs(math.Remainder(solar-node, 180))
|
||||
return phase <= 24
|
||||
}
|
||||
|
||||
func planetTransitCoarseConjunction(seedTT float64, cfg planetTransitConfig, inst *Instance) float64 {
|
||||
current := seedTT
|
||||
for iteration := 0; iteration < 5; iteration++ {
|
||||
value := planetTransitLongitudeDeltaN(current, cfg, planetTransitCoarseN, inst)
|
||||
slope := (planetTransitLongitudeDeltaN(current+0.02, cfg, planetTransitCoarseN, inst) -
|
||||
planetTransitLongitudeDeltaN(current-0.02, cfg, planetTransitCoarseN, inst)) / 0.04
|
||||
if !isFiniteFloat(slope) || slope == 0 {
|
||||
return math.NaN()
|
||||
}
|
||||
step := value / slope
|
||||
current -= step
|
||||
if math.Abs(step) < 0.0001 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return current
|
||||
}
|
||||
|
||||
// PlanetTransitSeries 凌日周期族,Number 为零表示超出编号适用范围 / transit family; a zero Number means unassigned.
|
||||
type PlanetTransitSeries struct {
|
||||
Number int
|
||||
PeriodYears int
|
||||
}
|
||||
|
||||
func planetTransitSeriesAt(greatestTT float64, cfg planetTransitConfig) PlanetTransitSeries {
|
||||
period, synodicCycles := 243, 152
|
||||
firstYear, lastYear := -2000, 4000
|
||||
anchors := [][4]int{{-1892, 5, 21, 1}, {-1998, 11, 18, 2}, {-1884, 5, 19, 3}, {-1763, 11, 20, 4}, {554, 5, 22, 5}, {1631, 12, 7, 6}}
|
||||
if cfg.planetIndex == 1 {
|
||||
period, synodicCycles = 46, 145
|
||||
firstYear, lastYear = 1601, 2300
|
||||
anchors = [][4]int{{1644, 11, 9, 1}, {1631, 11, 7, 2}, {1628, 5, 5, 3}, {1618, 11, 4, 4}, {1615, 5, 3, 5}, {1605, 11, 1, 6}, {1740, 5, 2, 7}, {1776, 11, 2, 8}, {1957, 5, 6, 9}, {1993, 11, 6, 10}, {2174, 5, 8, 11}, {2210, 11, 9, 12}}
|
||||
}
|
||||
result := PlanetTransitSeries{PeriodYears: period}
|
||||
if greatestTT < JDCalc(firstYear, 1, 1) || greatestTT >= JDCalc(lastYear+1, 1, 1) {
|
||||
return result
|
||||
}
|
||||
cycle := int(math.Round((greatestTT - cfg.anchorInferiorTT) / cfg.synodicPeriodDays))
|
||||
for _, anchor := range anchors {
|
||||
anchorCycle := int(math.Round((JDCalc(anchor[0], anchor[1], float64(anchor[2])) - cfg.anchorInferiorTT) / cfg.synodicPeriodDays))
|
||||
if (cycle-anchorCycle)%synodicCycles == 0 {
|
||||
result.Number = anchor[3]
|
||||
return result
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in new issue
Block a user