Module: AstroChart::Pure::Houses
- Defined in:
- lib/astro_chart/pure/houses.rb
Overview
Houses — MIT-safe 純 Ruby Placidus 宮位(ASC / MC / 12 宮頭)。
零外部依賴、不參考 Swiss Ephemeris C 原始碼,僅使用公開文獻公式:
- 視恆星時 / 章動 / 黃赤交角:見 Core(Meeus Ch. 12 / 22)
- ASC / MC:標準球面天文公式(Meeus Ch. 13 座標轉換推得)
- Placidus 宮頭:古典半弧迭代法(半日弧 SA = arccos(-tanφ·tanδ), 宮頭 11/12 位於 RAMC 東側 1/3、2/3 半日弧處;宮頭 2/3 以半夜弧對應)
公開 API: Houses.calc(jd_ut, lat, lon) -> { "cusps" => [12 floats], "ascendant" => Float, "mc" => Float } 欄位與 AstroChart::Ext.houses(jd, lat, lon, "P".ord) 相同。
適用範圍:|lat| < ~66°(Placidus 在極圈內無定義)。 超出範圍或迭代未收斂時 raise Core::DomainError(顯性失敗,不靜默 clamp)。
Constant Summary collapse
Class Method Summary collapse
-
.asc_longitude(armc_deg, eps, phi) ⇒ Object
--- ASC:標準公式 --- λ_ASC = atan2( cos ARMC, -(sin ARMC · cos ε + tan φ · sin ε) ).
-
.calc(jd_ut, lat, lon) ⇒ Object
jd_ut: UT 儒略日;lat: 地理緯度(北正);lon: 地理經度(東正).
-
.mc_longitude(armc_deg, eps) ⇒ Object
--- MC:天頂赤經 → 黃道經度 --- tan λ_MC = tan(ARMC) / cos ε,以 atan2 處理象限.
-
.placidus_cusp(armc_deg, eps, phi, offset_deg, frac, mode) ⇒ Object
--- Placidus 宮頭半弧迭代 --- 定義:黃道上一點 (α, δ),半日弧 SA_d = arccos(-tanφ·tanδ)、半夜弧 SA_n = arccos(tanφ·tanδ)。 宮頭 11:α = RAMC + (1/3)·SA_d 宮頭 12:α = RAMC + (2/3)·SA_d 宮頭 2 :α = RAMC + 180 - (2/3)·SA_n 宮頭 3 :α = RAMC + 180 - (1/3)·SA_n 黃道點的赤緯由 tan δ = tan ε · sin α 得出,固定點迭代至收斂。 offset_deg:初值偏移(赤道情形的精確解);frac:半弧比例;mode:地平上/下。.
Class Method Details
.asc_longitude(armc_deg, eps, phi) ⇒ Object
--- ASC:標準公式 --- λ_ASC = atan2( cos ARMC, -(sin ARMC · cos ε + tan φ · sin ε) )
71 72 73 74 75 76 77 78 79 |
# File 'lib/astro_chart/pure/houses.rb', line 71 def asc_longitude(armc_deg, eps, phi) ra = armc_deg * DEG2RAD Core.norm360( Math.atan2( Math.cos(ra), -(Math.sin(ra) * Math.cos(eps) + Math.tan(phi) * Math.sin(eps)) ) * RAD2DEG ) end |
.calc(jd_ut, lat, lon) ⇒ Object
jd_ut: UT 儒略日;lat: 地理緯度(北正);lon: 地理經度(東正)
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/astro_chart/pure/houses.rb', line 29 def calc(jd_ut, lat, lon) tt = Core.jd_tt(jd_ut) eps = Core.true_obliquity(tt) * DEG2RAD # 真黃赤交角(弧度) ast_deg = Core.apparent_sidereal_deg(jd_ut) # 視恆星時(度) armc = Core.norm360(ast_deg + lon) # 天頂赤經 RAMC phi = lat * DEG2RAD mc = mc_longitude(armc, eps) asc = asc_longitude(armc, eps, phi) # Placidus 半弧迭代:宮頭 11、12(地平上,RAMC 東側)與 2、3(地平下) c11 = placidus_cusp(armc, eps, phi, 30.0, 1.0 / 3.0, :diurnal) c12 = placidus_cusp(armc, eps, phi, 60.0, 2.0 / 3.0, :diurnal) c2 = placidus_cusp(armc, eps, phi, 120.0, 2.0 / 3.0, :nocturnal) c3 = placidus_cusp(armc, eps, phi, 150.0, 1.0 / 3.0, :nocturnal) cusps = Array.new(12) cusps[0] = asc # 第 1 宮 = ASC cusps[1] = c2 cusps[2] = c3 cusps[3] = Core.norm360(mc + 180.0) # 第 4 宮 = MC 對沖 cusps[4] = Core.norm360(c11 + 180.0) cusps[5] = Core.norm360(c12 + 180.0) cusps[6] = Core.norm360(asc + 180.0) # 第 7 宮 = ASC 對沖 cusps[7] = Core.norm360(c2 + 180.0) cusps[8] = Core.norm360(c3 + 180.0) cusps[9] = mc # 第 10 宮 = MC cusps[10] = c11 cusps[11] = c12 { "cusps" => cusps, "ascendant" => asc, "mc" => mc } end |
.mc_longitude(armc_deg, eps) ⇒ Object
--- MC:天頂赤經 → 黃道經度 --- tan λ_MC = tan(ARMC) / cos ε,以 atan2 處理象限
64 65 66 67 |
# File 'lib/astro_chart/pure/houses.rb', line 64 def mc_longitude(armc_deg, eps) ra = armc_deg * DEG2RAD Core.norm360(Math.atan2(Math.sin(ra), Math.cos(ra) * Math.cos(eps)) * RAD2DEG) end |
.placidus_cusp(armc_deg, eps, phi, offset_deg, frac, mode) ⇒ Object
--- Placidus 宮頭半弧迭代 --- 定義:黃道上一點 (α, δ),半日弧 SA_d = arccos(-tanφ·tanδ)、半夜弧 SA_n = arccos(tanφ·tanδ)。 宮頭 11:α = RAMC + (1/3)·SA_d 宮頭 12:α = RAMC + (2/3)·SA_d 宮頭 2 :α = RAMC + 180 - (2/3)·SA_n 宮頭 3 :α = RAMC + 180 - (1/3)·SA_n 黃道點的赤緯由 tan δ = tan ε · sin α 得出,固定點迭代至收斂。 offset_deg:初值偏移(赤道情形的精確解);frac:半弧比例;mode:地平上/下。
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/astro_chart/pure/houses.rb', line 87 def placidus_cusp(armc_deg, eps, phi, offset_deg, frac, mode) tan_phi = Math.tan(phi) tan_eps = Math.tan(eps) ra = (armc_deg + offset_deg) * DEG2RAD armc_rad = armc_deg * DEG2RAD converged = false 60.times do dec = Math.atan(tan_eps * Math.sin(ra)) # 黃道點赤緯 x = tan_phi * Math.tan(dec) if x.abs > 1.0 # 極圈內該點無升落,Placidus 無定義。顯性失敗,不靜默 clamp。 raise Core::DomainError, "Placidus 在此緯度無定義(|tanφ·tanδ| = #{x.abs.round(4)} > 1,lat=#{(phi * RAD2DEG).round(4)}°)" end new_ra = if mode == :diurnal armc_rad + frac * Math.acos(-x) else armc_rad + Math::PI - frac * Math.acos(x) end step = (new_ra - ra).abs ra = new_ra # 先採納本次結果,收斂時回傳的才是最終值 if step < 1e-9 * DEG2RAD converged = true break end end raise Core::DomainError, "Placidus 宮頭迭代 60 次未收斂" unless converged # 赤經 → 黃道經度:tan λ = tan α / cos ε Core.norm360(Math.atan2(Math.sin(ra), Math.cos(ra) * Math.cos(eps)) * RAD2DEG) end |