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,110 @@
|
||||
package basic
|
||||
|
||||
import "math"
|
||||
|
||||
func GetMoonLoops(year float64, loop int) []float64 {
|
||||
var start float64
|
||||
var newMoon, lastNewMoon float64
|
||||
moonLoops := make([]float64, loop)
|
||||
if year < 6000 {
|
||||
start = year + 11.00/12.00 + 5.00/30.00/12.00
|
||||
} else {
|
||||
start = year + 9.00/12.00 + 5.00/30.00/12.00
|
||||
}
|
||||
i := 1
|
||||
for j := 0; j < loop; j++ {
|
||||
if year > 3000 {
|
||||
newMoon = TD2UT(CalcMoonSH(start+float64(i-1)/12.5, 0)+8.0/24.0, false)
|
||||
} else {
|
||||
newMoon = TD2UT(CalcMoonS(start+float64(i-1)/12.5, 0)+8.0/24.0, false)
|
||||
}
|
||||
if i != 1 {
|
||||
if newMoon == lastNewMoon {
|
||||
j--
|
||||
i++
|
||||
continue
|
||||
}
|
||||
}
|
||||
moonLoops[j] = newMoon
|
||||
lastNewMoon = moonLoops[j]
|
||||
i++
|
||||
}
|
||||
return moonLoops
|
||||
}
|
||||
|
||||
func GetJieqiLoops(year, loop int) []float64 {
|
||||
start := 270
|
||||
jq := make([]float64, loop)
|
||||
for i := 1; i <= loop; i++ {
|
||||
angle := start + 15*(i-1)
|
||||
if angle > 360 {
|
||||
angle -= 360
|
||||
}
|
||||
jq[i-1] = GetJQTime(year+int(math.Ceil(float64(i-1)/24.000)), angle) + 8.0/24.0
|
||||
}
|
||||
return jq
|
||||
}
|
||||
|
||||
func GetJQTime(year, angle int) float64 {
|
||||
// Calculate initial day based on angle parity
|
||||
var initialDay float64
|
||||
if angle%2 == 0 {
|
||||
initialDay = 18
|
||||
} else {
|
||||
initialDay = 3
|
||||
}
|
||||
|
||||
// Calculate temporary factor for month offset
|
||||
var tempFactor float64
|
||||
if angle%10 != 0 {
|
||||
tempFactor = float64(angle+15) / 30.0
|
||||
} else {
|
||||
tempFactor = float64(angle) / 30.0
|
||||
}
|
||||
|
||||
// Calculate initial month, adjusting if超过 12
|
||||
initialMonth := 3.0 + tempFactor
|
||||
if initialMonth > 12.0 {
|
||||
initialMonth -= 12.0
|
||||
}
|
||||
|
||||
// Calculate initial Julian date
|
||||
initialJD := JDECalc(year, int(initialMonth), initialDay)
|
||||
|
||||
// Set target angle for iteration; if angle is 0, use 360
|
||||
targetAngle := float64(angle)
|
||||
if angle == 0 {
|
||||
targetAngle = 360.0
|
||||
}
|
||||
|
||||
// Newton-Raphson iteration to find precise Julian date
|
||||
currentJD := initialJD
|
||||
for {
|
||||
previousJD := currentJD
|
||||
errorValue := JQLospec(previousJD, targetAngle) - targetAngle
|
||||
derivative := (JQLospec(previousJD+0.000005, targetAngle) - JQLospec(previousJD-0.000005, targetAngle)) / 0.00001
|
||||
currentJD = previousJD - errorValue/derivative
|
||||
|
||||
// Check for convergence
|
||||
if math.Abs(currentJD-previousJD) <= 0.00001 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to UT and return
|
||||
return TD2UT(currentJD, false)
|
||||
}
|
||||
|
||||
func JQLospec(jd float64, target float64) float64 {
|
||||
sunLo := HSunApparentLo(jd)
|
||||
if target >= 345 {
|
||||
if sunLo <= 12 {
|
||||
sunLo += 360
|
||||
}
|
||||
} else if target <= 15 {
|
||||
if sunLo >= 350 {
|
||||
sunLo -= 360
|
||||
}
|
||||
}
|
||||
return sunLo
|
||||
}
|
||||
Reference in New Issue
Block a user