Module: AstroChart::Pure::Pluto
- Defined in:
- lib/astro_chart/pure/pluto.rb
Overview
Pluto — MIT-safe 純 Ruby 冥王星視黃經(零外部依賴)。
只使用公開文獻公式,不參考 Swiss Ephemeris C 原始碼:
- 冥王星日心座標:Jean Meeus, "Astronomical Algorithms" 2nd ed., Ch. 37(冥王星專用週期項級數,Table 37.A,適用 1885–2099, 座標基準 = J2000.0 平春分點)
- 地球日心座標:Meeus Ch. 25(太陽幾何黃經 + 半徑向量, eq. 25.2–25.5,基準 = 當日平春分點;太陽精度 ~0.01°, 冥王星距離 ~31–50 AU,投影到地心方向後誤差稀釋 ~1/31, 對冥王星地心黃經貢獻 < 0.001°)
- 歲差(J2000 → 當日黃道座標):Meeus Ch. 21(eq. 21.5 的 η/Π/p 起始曆元 J2000 特化式 + eq. 21.7 球面旋轉)
- 光行時 + 光行差:Meeus Ch. 33 — 行星與地球都取 t−τ 時刻 的位置,一次同時涵蓋光行時與(一階)光行差
- 章動 Δψ:Core.nutation(Meeus Ch. 22)
時間尺度:apparent_longitude 吃 **JD(UT)**,內部自換 TT。
公開 API: Pluto.apparent_longitude(jd_ut) -> 視黃道經度(度,[0,360), 真春分點 of date,含光行時/光行差/章動) 超出 1885–2099 適用範圍 raise Core::DomainError(顯性失敗)。
Constant Summary collapse
- DEG2RAD =
Core::DEG2RAD
- RAD2DEG =
Core::RAD2DEG
- JD_TT_MIN =
Meeus Ch. 37 級數適用範圍 1885–2099(TT)。 JD 2409542.5 = 1885-01-01 00:00、JD 2488069.5 = 2100-01-01 00:00。
2409542.5- JD_TT_MAX =
2488069.5- LIGHT_TIME_PER_AU =
光行時常數:光走 1 AU 所需天數(Meeus Ch. 33)
0.0057755183- TERMS =
Meeus Table 37.A — 43 項週期級數。 每列:[j, s, p, lon_A, lon_B, lat_A, lat_B, rad_A, rad_B] 引數 α = j·J + s·S + p·P(J/S/P 為木星/土星/冥王星平黃經) longitude/latitude 單位 1e-6 度,radius 單位 1e-7 AU 各量 = Σ (A·sin α + B·cos α)
[ [0, 0, 1, -19_799_805, 19_850_055, -5_452_852, -14_974_862, 66_865_439, 68_951_812], [0, 0, 2, 897_144, -4_954_829, 3_527_812, 1_672_790, -11_827_535, -332_538], [0, 0, 3, 611_149, 1_211_027, -1_050_748, 327_647, 1_593_179, -1_438_890], [0, 0, 4, -341_243, -189_585, 178_690, -292_153, -18_444, 483_220], [0, 0, 5, 129_287, -34_992, 18_650, 100_340, -65_977, -85_431], [0, 0, 6, -38_164, 30_893, -30_697, -25_823, 31_174, -6_032], [0, 1, -1, 20_442, -9_987, 4_878, 11_248, -5_794, 22_161], [0, 1, 0, -4_063, -5_071, 226, -64, 4_601, 4_032], [0, 1, 1, -6_016, -3_336, 2_030, -836, -1_729, 234], [0, 1, 2, -3_956, 3_039, 69, -604, -415, 702], [0, 1, 3, -667, 3_572, -247, -567, 239, 723], [0, 2, -2, 1_276, 501, -57, 1, 67, -67], [0, 2, -1, 1_152, -917, -122, 175, 1_034, -451], [0, 2, 0, 630, -1_277, -49, -164, -129, 504], [1, -1, 0, 2_571, -459, -197, 199, 480, -231], [1, -1, 1, 899, -1_449, -25, 217, 2, -441], [1, 0, -3, -1_016, 1_043, 589, -248, -3_359, 265], [1, 0, -2, -2_343, -1_012, -269, 711, 7_856, -7_832], [1, 0, -1, 7_042, 788, 185, 193, 36, 45_763], [1, 0, 0, 1_199, -338, 315, 807, 8_663, 8_547], [1, 0, 1, 418, -67, -130, -43, -809, -769], [1, 0, 2, 120, -274, 5, 3, 263, -144], [1, 0, 3, -60, -159, 2, 17, -126, 32], [1, 0, 4, -82, -29, 2, 5, -35, -16], [1, 1, -3, -36, -29, 2, 3, -19, -4], [1, 1, -2, -40, 7, 3, 1, -15, 8], [1, 1, -1, -14, 22, 2, -1, -4, 12], [1, 1, 0, 4, 13, 1, -1, 5, 6], [1, 1, 1, 5, 2, 0, -1, 3, 1], [1, 1, 3, -1, 0, 0, 0, 6, -2], [2, 0, -6, 2, 0, 0, -2, 2, 2], [2, 0, -5, -4, 5, 2, 2, -2, -2], [2, 0, -4, 4, -7, -7, 0, 14, 13], [2, 0, -3, 14, 24, 10, -8, -63, 13], [2, 0, -2, -49, -34, -3, 20, 136, -236], [2, 0, -1, 163, -48, 6, 5, 273, 1_065], [2, 0, 0, 9, -24, 14, 17, 251, 149], [2, 0, 1, -4, 1, -2, 0, -25, -9], [2, 0, 2, -3, 1, 0, 0, 9, -2], [2, 0, 3, 1, 3, 0, 0, -8, 7], [3, 0, -2, -3, -1, 0, 1, 2, -10], [3, 0, -1, 5, -3, 0, 0, 19, 35], [3, 0, 0, 0, 0, 1, 0, 10, 3], ].map(&:freeze).freeze
Class Method Summary collapse
-
.apparent_longitude(jd_ut) ⇒ Object
冥王星視黃道經度(度,真春分點 of date)。 jd_ut: JD(UT)。超出 Meeus Ch.
-
.earth_helio_rect(jd_tt) ⇒ Object
--- 地球日心直角座標(AU,當日平春分點黃道座標) --- Meeus Ch.
-
.pluto_helio_rect(jd_tt, jd_frame_tt) ⇒ Object
--- 冥王星日心直角座標(AU,黃道座標,旋轉到 jd_frame_tt 的平春分點) --- Meeus Ch.
-
.precess_from_j2000(lon_deg, lat_deg, jd_tt) ⇒ Object
--- 黃道座標歲差:J2000.0 → jd_tt 的平春分點(Meeus Ch.
Class Method Details
.apparent_longitude(jd_ut) ⇒ Object
冥王星視黃道經度(度,真春分點 of date)。 jd_ut: JD(UT)。超出 Meeus Ch. 37 適用範圍(1885–2099)raise DomainError。
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/astro_chart/pure/pluto.rb', line 96 def apparent_longitude(jd_ut) jd_tt = Core.jd_tt(jd_ut) unless jd_tt >= JD_TT_MIN && jd_tt < JD_TT_MAX raise Core::DomainError, "Pluto series (Meeus Ch.37) valid only 1885-2099, got JD(TT)=#{jd_tt}" end # 光行時 + 光行差:行星與地球都取 t−τ 的位置(Meeus Ch. 33)。 # 地球在 τ 內的位移 = v·τ = v·Δ/c,換成方向偏移正是一階光行差 v/c。 gx = gy = gz = 0.0 tau = 0.0 10.times do |i| px, py, pz = pluto_helio_rect(jd_tt - tau, jd_tt) ex, ey, ez = earth_helio_rect(jd_tt - tau) gx = px - ex gy = py - ey gz = pz - ez delta = Math.sqrt(gx * gx + gy * gy + gz * gz) new_tau = LIGHT_TIME_PER_AU * delta if (new_tau - tau).abs < 1e-9 tau = new_tau break end raise Core::DomainError, "Pluto light-time iteration did not converge" if i == 9 tau = new_tau end lambda_mean = Math.atan2(gy, gx) * RAD2DEG # 平春分點 of date dpsi, = Core.nutation(jd_tt) Core.norm360(lambda_mean + dpsi) end |
.earth_helio_rect(jd_tt) ⇒ Object
--- 地球日心直角座標(AU,當日平春分點黃道座標) --- Meeus Ch. 25(eq. 25.2–25.5):太陽幾何黃經 ⊙ 與半徑向量 R, 地球日心黃經 = ⊙ + 180°、黃緯 ≈ 0、距離 = R。
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/astro_chart/pure/pluto.rb', line 167 def earth_helio_rect(jd_tt) t = (jd_tt - 2_451_545.0) / 36_525.0 l0 = 280.46646 + 36_000.76983 * t + 0.0003032 * t * t # 太陽幾何平黃經 m = 357.52911 + 35_999.05029 * t - 0.0001537 * t * t # 太陽平近點角 e = 0.016708634 - 0.000042037 * t - 0.0000001267 * t * t # 地球軌道離心率 m_rad = m * DEG2RAD c = (1.914602 - 0.004817 * t - 0.000014 * t * t) * Math.sin(m_rad) + (0.019993 - 0.000101 * t) * Math.sin(2.0 * m_rad) + 0.000289 * Math.sin(3.0 * m_rad) # 中心差 sun_lon = l0 + c # 太陽真幾何黃經(平春分點 of date) nu = m + c # 真近點角 r = 1.000001018 * (1.0 - e * e) / (1.0 + e * Math.cos(nu * DEG2RAD)) earth_lon_rad = (sun_lon + 180.0) * DEG2RAD [r * Math.cos(earth_lon_rad), r * Math.sin(earth_lon_rad), 0.0] end |
.pluto_helio_rect(jd_tt, jd_frame_tt) ⇒ Object
--- 冥王星日心直角座標(AU,黃道座標,旋轉到 jd_frame_tt 的平春分點) --- Meeus Ch. 37:級數給出 J2000.0 平春分點下的日心 l/b/r, 再用 precess_from_j2000 旋轉到目標曆元。
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/astro_chart/pure/pluto.rb', line 132 def pluto_helio_rect(jd_tt, jd_frame_tt) t = (jd_tt - 2_451_545.0) / 36_525.0 # 木星 / 土星 / 冥王星平黃經(度,Meeus Ch. 37) j = 34.35 + 3034.9057 * t s = 50.08 + 1222.1138 * t p = 238.96 + 144.9600 * t sum_l = 0.0 sum_b = 0.0 sum_r = 0.0 TERMS.each do |cj, cs, cp, la, lb, ba, bb, ra, rb| alpha = (cj * j + cs * s + cp * p) * DEG2RAD sin_a = Math.sin(alpha) cos_a = Math.cos(alpha) sum_l += la * sin_a + lb * cos_a sum_b += ba * sin_a + bb * cos_a sum_r += ra * sin_a + rb * cos_a end l = 238.958116 + 144.96 * t + sum_l * 1e-6 # 度,J2000 平春分點 b = -3.908239 + sum_b * 1e-6 # 度 r = 40.7241346 + sum_r * 1e-7 # AU l, b = precess_from_j2000(l, b, jd_frame_tt) l_rad = l * DEG2RAD b_rad = b * DEG2RAD cb = Math.cos(b_rad) [r * cb * Math.cos(l_rad), r * cb * Math.sin(l_rad), r * Math.sin(b_rad)] end |
.precess_from_j2000(lon_deg, lat_deg, jd_tt) ⇒ Object
--- 黃道座標歲差:J2000.0 → jd_tt 的平春分點(Meeus Ch. 21) --- 起始曆元 = J2000(eq. 21.5 取 T=0): η = 47.0029″t − 0.03302″t² + 0.000060″t³ Π = 174°.876384 − 869.8089″t + 0.03536″t² p = 5029.0966″t + 1.11113″t² − 0.000006″t³ 再套 eq. 21.7 球面旋轉。
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/astro_chart/pure/pluto.rb', line 193 def precess_from_j2000(lon_deg, lat_deg, jd_tt) t = (jd_tt - 2_451_545.0) / 36_525.0 return [lon_deg, lat_deg] if t.zero? arcsec = 1.0 / 3600.0 eta = (47.0029 * t - 0.03302 * t * t + 0.000060 * t * t * t) * arcsec pi_ = 174.876384 + (-869.8089 * t + 0.03536 * t * t) * arcsec pp = (5029.0966 * t + 1.11113 * t * t - 0.000006 * t * t * t) * arcsec eta_rad = eta * DEG2RAD lat_rad = lat_deg * DEG2RAD pi_lon = (pi_ - lon_deg) * DEG2RAD cos_lat = Math.cos(lat_rad) sin_lat = Math.sin(lat_rad) sin_pl = Math.sin(pi_lon) a = Math.cos(eta_rad) * cos_lat * sin_pl - Math.sin(eta_rad) * sin_lat b = cos_lat * Math.cos(pi_lon) c = Math.sin(eta_rad) * cos_lat * sin_pl + Math.cos(eta_rad) * sin_lat new_lon = pp + pi_ - Math.atan2(a, b) * RAD2DEG new_lat = Math.asin(c.clamp(-1.0, 1.0)) * RAD2DEG [Core.norm360(new_lon), new_lat] end |