210 lines
7.3 KiB
Go
210 lines
7.3 KiB
Go
|
|
package basic
|
||
|
|
|
||
|
|
import (
|
||
|
|
"math"
|
||
|
|
|
||
|
|
. "b612.me/astro/tools"
|
||
|
|
)
|
||
|
|
|
||
|
|
func MoonPhase(jd float64) float64 {
|
||
|
|
moonBo := HMoonTrueBo(jd)
|
||
|
|
sunLo := HSunApparentLo(jd)
|
||
|
|
moonLo := HMoonApparentLo(jd)
|
||
|
|
tmp := Cos(moonBo) * Cos(sunLo-moonLo)
|
||
|
|
earthSunDistance := Distance(jd) * 149597870.691
|
||
|
|
i := earthSunDistance * Sin(ArcCos(tmp)) / (HMoonAway(jd) - earthSunDistance*tmp)
|
||
|
|
i = ArcTan(i)
|
||
|
|
if i < 0 {
|
||
|
|
i += 180
|
||
|
|
}
|
||
|
|
if i > 180 {
|
||
|
|
i -= 180
|
||
|
|
}
|
||
|
|
k := (1 + Cos(i)) / 2
|
||
|
|
return k
|
||
|
|
}
|
||
|
|
|
||
|
|
func SunMoonSeek(jde float64, degree float64) float64 {
|
||
|
|
p := HMoonApparentLo(jde) - (HSunApparentLo(jde)) - degree
|
||
|
|
for p < -180 {
|
||
|
|
p += 360
|
||
|
|
}
|
||
|
|
for p > 180 {
|
||
|
|
p -= 360
|
||
|
|
}
|
||
|
|
return p
|
||
|
|
}
|
||
|
|
|
||
|
|
func CalcMoonSHByJDE(jde float64, phaseType int) float64 {
|
||
|
|
phaseType = phaseType * 180
|
||
|
|
estimateJD := jde
|
||
|
|
for {
|
||
|
|
prevJD := estimateJD
|
||
|
|
stDegree := SunMoonSeek(prevJD, float64(phaseType))
|
||
|
|
stDegreep := (SunMoonSeek(prevJD+0.000005, float64(phaseType)) - SunMoonSeek(prevJD-0.000005, float64(phaseType))) / 0.00001
|
||
|
|
estimateJD = prevJD - stDegree/stDegreep
|
||
|
|
if math.Abs(estimateJD-prevJD) <= 0.00001 {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return estimateJD
|
||
|
|
}
|
||
|
|
|
||
|
|
func CalcMoonSH(year float64, phaseType int) float64 {
|
||
|
|
jde := CalcMoonS(year, phaseType)
|
||
|
|
phaseType = phaseType * 180
|
||
|
|
estimateJD := jde
|
||
|
|
for {
|
||
|
|
prevJD := estimateJD
|
||
|
|
stDegree := SunMoonSeek(prevJD, float64(phaseType))
|
||
|
|
stDegreep := (SunMoonSeek(prevJD+0.000005, float64(phaseType)) - SunMoonSeek(prevJD-0.000005, float64(phaseType))) / 0.00001
|
||
|
|
estimateJD = prevJD - stDegree/stDegreep
|
||
|
|
if math.Abs(estimateJD-prevJD) <= 0.00001 {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return estimateJD
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
* C=0朔月时刻 =1 望月
|
||
|
|
*/
|
||
|
|
func CalcMoonS(year float64, phaseType int) float64 {
|
||
|
|
k := math.Floor((year - 2000) * 12.36827)
|
||
|
|
if phaseType == 1 {
|
||
|
|
k += 0.5
|
||
|
|
}
|
||
|
|
T := k / 1236.85
|
||
|
|
jde := 2451550.09765 + 29.530588853*k + 0.0001337*T*T - 0.000000150*T*T*T + 0.00000000073*T*T*T*T
|
||
|
|
//太阳平近点角:
|
||
|
|
M := Limit360(2.5534 + 29.10535669*k - 0.0000218*T*T - 0.00000011*T*T*T)
|
||
|
|
//月亮的平近点角:
|
||
|
|
N := Limit360(201.5643 + 385.81693528*k + 0.0107438*T*T + 0.00001239*T*T*T - 0.000000058*T*T*T*T)
|
||
|
|
//月亮的纬度参数:
|
||
|
|
F := Limit360(160.7108 + 390.67050274*k - 0.0016341*T*T - 0.00000227*T*T*T + 0.000000011*T*T*T*T)
|
||
|
|
//月亮轨道升交点经度:
|
||
|
|
O := Limit360(124.7746 - 1.56375580*k + 0.0020691*T*T + 0.00000215*T*T*T)
|
||
|
|
E := 1 - 0.002516*T - 0.0000074*T*T
|
||
|
|
//die(E." ".M." ".N." ".F." ".O);
|
||
|
|
angles := []float64{N, M, 2 * N, 2 * F, N - M, N + M, 2 * M, N - 2*F, N + 2*F, 2*N + M, 3 * N, M + 2*F, M - 2*F, 2*N - M, O, N + 2*M, 2*N - 2*F, 3 * M, N + M - 2*F, 2*N + 2*F, N + M + 2*F, N - M + 2*F, N - M - 2*F, 3*N + M, 4 * N}
|
||
|
|
var coeffs []float64
|
||
|
|
if phaseType == 0 {
|
||
|
|
coeffs = []float64{-0.40720, 0.17241 * E, 0.01608, 0.01039, 0.00739 * E, -0.00514 * E, 0.00208 * E * E, -0.00111, -0.00057, 0.00056 * E, -0.00042, 0.00042 * E, 0.00038 * E, -0.00024 * E, -0.00017, -0.00007, 0.00004, 0.00004, 0.00003, 0.00003, -0.00003, 0.00003, -0.00002, -0.00002, 0.00002}
|
||
|
|
} else {
|
||
|
|
coeffs = []float64{-0.40614, 0.17302 * E, 0.01614, 0.01043, 0.00734 * E, -0.00515 * E, 0.00209 * E * E, -0.00111, -0.00057, 0.00056 * E, -0.00042, 0.00042 * E, 0.00038 * E, -0.00024 * E, -0.00017, -0.00007, 0.00004, 0.00004, 0.00003, 0.00003, -0.00003, 0.00003, -0.00002, -0.00002, 0.00002}
|
||
|
|
}
|
||
|
|
var correction float64
|
||
|
|
for idx, angle := range angles {
|
||
|
|
correction += Sin(angle) * coeffs[idx]
|
||
|
|
}
|
||
|
|
//die(tmp);
|
||
|
|
A1 := 299.77 + 0.107408*k - 0.009173*T*T
|
||
|
|
A2 := 251.88 + 0.016321*k
|
||
|
|
A3 := 251.83 + 26.651886*k
|
||
|
|
A4 := 349.42 + 36.412478*k
|
||
|
|
A5 := 84.66 + 18.206239*k
|
||
|
|
A6 := 141.74 + 53.303771*k
|
||
|
|
A7 := 207.14 + 2.453732*k
|
||
|
|
A8 := 154.84 + 7.306860*k
|
||
|
|
A9 := 34.52 + 27.261239*k
|
||
|
|
A10 := 207.19 + 0.121824*k
|
||
|
|
A11 := 291.34 + 1.844379*k
|
||
|
|
A12 := 161.72 + 24.198154*k
|
||
|
|
A13 := 239.56 + 25.513099*k
|
||
|
|
A14 := 331.55 + 3.592518*k
|
||
|
|
planetaryCorrection := 325*Sin(A1) + 165*Sin(A2) + 164*Sin(A3) + 126*Sin(A4) + 110*Sin(A5) + 62*Sin(A6) + 60*Sin(A7) + 56*Sin(A8) + 47*Sin(A9) + 42*Sin(A10) + 40*Sin(A11) + 37*Sin(A12) + 35*Sin(A13) + 23*Sin(A14)
|
||
|
|
planetaryCorrection /= 1000000
|
||
|
|
jde = jde + planetaryCorrection + correction
|
||
|
|
return jde
|
||
|
|
}
|
||
|
|
|
||
|
|
func CalcMoonXHByJDE(jde float64, quarterType int) float64 {
|
||
|
|
if quarterType == 0 {
|
||
|
|
quarterType = 90
|
||
|
|
} else {
|
||
|
|
quarterType = -90
|
||
|
|
}
|
||
|
|
estimateJD := jde
|
||
|
|
for {
|
||
|
|
prevJD := estimateJD
|
||
|
|
stDegree := SunMoonSeek(prevJD, float64(quarterType))
|
||
|
|
stDegreep := (SunMoonSeek(prevJD+0.000005, float64(quarterType)) - SunMoonSeek(prevJD-0.000005, float64(quarterType))) / 0.00001
|
||
|
|
estimateJD = prevJD - stDegree/stDegreep
|
||
|
|
if math.Abs(estimateJD-prevJD) <= 0.00001 {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return estimateJD
|
||
|
|
}
|
||
|
|
|
||
|
|
func CalcMoonXH(year float64, quarterType int) float64 {
|
||
|
|
jde := CalcMoonX(year, quarterType)
|
||
|
|
if quarterType == 0 {
|
||
|
|
quarterType = 90
|
||
|
|
} else {
|
||
|
|
quarterType = -90
|
||
|
|
}
|
||
|
|
estimateJD := jde
|
||
|
|
for {
|
||
|
|
prevJD := estimateJD
|
||
|
|
stDegree := SunMoonSeek(prevJD, float64(quarterType))
|
||
|
|
stDegreep := (SunMoonSeek(prevJD+0.000005, float64(quarterType)) - SunMoonSeek(prevJD-0.000005, float64(quarterType))) / 0.00001
|
||
|
|
estimateJD = prevJD - stDegree/stDegreep
|
||
|
|
if math.Abs(estimateJD-prevJD) <= 0.00001 {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return estimateJD
|
||
|
|
}
|
||
|
|
|
||
|
|
func CalcMoonX(year float64, quarterType int) float64 {
|
||
|
|
k := math.Floor((year-2000)*12.36827) + 0.25
|
||
|
|
if quarterType == 1 {
|
||
|
|
k += 0.5
|
||
|
|
}
|
||
|
|
T := k / 1236.85
|
||
|
|
jde := 2451550.09765 + 29.530588853*k + 0.0001337*T*T - 0.000000150*T*T*T + 0.00000000073*T*T*T*T
|
||
|
|
//太阳平近点角:
|
||
|
|
M := Limit360(2.5534 + 29.10535669*k - 0.0000218*T*T - 0.00000011*T*T*T)
|
||
|
|
//月亮的平近点角:
|
||
|
|
N := Limit360(201.5643 + 385.81693528*k + 0.0107438*T*T + 0.00001239*T*T*T - 0.000000058*T*T*T*T)
|
||
|
|
//月亮的纬度参数:
|
||
|
|
F := Limit360(160.7108 + 390.67050274*k - 0.0016341*T*T - 0.00000227*T*T*T + 0.000000011*T*T*T*T)
|
||
|
|
//月亮轨道升交点经度:
|
||
|
|
O := Limit360(124.7746 - 1.56375580*k + 0.0020691*T*T + 0.00000215*T*T*T)
|
||
|
|
E := 1 - 0.002516*T - 0.0000074*T*T
|
||
|
|
//die(E." ".M." ".N." ".F." ".O);
|
||
|
|
ZQ := []float64{N, M, N + M, 2 * N, 2 * F, N - M, 2 * M, N - 2*F, N + 2*F, 3 * N, 2*N - M, M + 2*F, M - 2*F, N + 2*M, 2*N + M, O, N - M - 2*F, 2*N + 2*F, N + M + 2*F, N - 2*F, N + M - 2*F, 3 * M, 2*N - 2*F, N - M + 2*F, M + 3*N}
|
||
|
|
MN := []float64{-0.62801, 0.17172 * E, -0.01183 * E, 0.00862, 0.00804, 0.00454 * E, 0.00204 * E * E, -0.00180, -0.00070, -0.00040, -0.00034 * E, 0.00032 * E, 0.00032 * E, -0.00028 * E * E, 0.00027 * E, -0.00017, -0.00005, 0.00004, -0.00004, 0.00004, 0.00003, 0.00003, 0.00002, 0.00002, -0.00002}
|
||
|
|
var correction float64
|
||
|
|
for idx, angle := range ZQ {
|
||
|
|
correction += Sin(angle) * MN[idx]
|
||
|
|
}
|
||
|
|
W := 0.00306 - 0.00038*E*Cos(M) + 0.00026*Cos(N) - 0.00002*Cos(N-M) + 0.00002*Cos(N+M) + 0.00002*Cos(2*F)
|
||
|
|
A1 := 299.77 + 0.107408*k - 0.009173*T*T
|
||
|
|
A2 := 251.88 + 0.016321*k
|
||
|
|
A3 := 251.83 + 26.651886*k
|
||
|
|
A4 := 349.42 + 36.412478*k
|
||
|
|
A5 := 84.66 + 18.206239*k
|
||
|
|
A6 := 141.74 + 53.303771*k
|
||
|
|
A7 := 207.14 + 2.453732*k
|
||
|
|
A8 := 154.84 + 7.306860*k
|
||
|
|
A9 := 34.52 + 27.261239*k
|
||
|
|
A10 := 207.19 + 0.121824*k
|
||
|
|
A11 := 291.34 + 1.844379*k
|
||
|
|
A12 := 161.72 + 24.198154*k
|
||
|
|
A13 := 239.56 + 25.513099*k
|
||
|
|
A14 := 331.55 + 3.592518*k
|
||
|
|
planetaryCorrection := 325*Sin(A1) + 165*Sin(A2) + 164*Sin(A3) + 126*Sin(A4) + 110*Sin(A5) + 62*Sin(A6) + 60*Sin(A7) + 56*Sin(A8) + 47*Sin(A9) + 42*Sin(A10) + 40*Sin(A11) + 37*Sin(A12) + 35*Sin(A13) + 23*Sin(A14)
|
||
|
|
planetaryCorrection /= 1000000
|
||
|
|
//die(tmp2);
|
||
|
|
//die(JDE." ".tmp." ".tmp2." ".W);
|
||
|
|
jde = jde + planetaryCorrection + correction
|
||
|
|
if quarterType == 0 {
|
||
|
|
jde += W
|
||
|
|
} else {
|
||
|
|
jde -= W
|
||
|
|
}
|
||
|
|
return jde
|
||
|
|
}
|