Module: AstroChart::SolarArc
- Defined in:
- lib/astro_chart/solar_arc.rb
Overview
Solar arc directions (太陽弧正向推運): advance every natal point by a single arc — the distance the secondary-progressed Sun has travelled since birth. Unlike secondary progressions (where each body moves at its own rate), solar arc moves the whole chart rigidly, so directed-to-natal aspects perfect at a rate of ~1° per year of life.
natal = AstroChart::Chart.new(...).generate
result = AstroChart::SolarArc.directions(natal, "2026-07-24")
result["arc"] # degrees the chart has been directed (~age)
result["planets"] # directed positions + natal-house placement
result["aspects_to_natal"] # directed→natal aspects, sorted by orb
Constant Summary collapse
- DAYS_PER_YEAR =
matches Progressions
365.2425- SUN =
"太陽"
Class Method Summary collapse
-
.directions(natal_chart, target_date, orb_limit: 1.0) ⇒ Object
natal_chart: a Chart#generate result hash (its input block gives birth date/time/timezone).
Class Method Details
.directions(natal_chart, target_date, orb_limit: 1.0) ⇒ Object
natal_chart: a Chart#generate result hash (its input block gives birth date/time/timezone). target_date: "YYYY-MM-DD". orb_limit: keep only directed-to-natal aspects within this orb (default 1.0 — solar arc is slow, only near-exact contacts matter).
27 28 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 |
# File 'lib/astro_chart/solar_arc.rb', line 27 def self.directions(natal_chart, target_date, orb_limit: 1.0) input = natal_chart&.dig("input") if input.nil? || input["birth_date"].nil? || input["birth_time"].nil? || input["timezone"].nil? raise ArgumentError, "chart has no input data (birth_date/birth_time/timezone required)" end jd_natal = TimeConversion.to_julian_day(input["birth_date"], input["birth_time"], input["timezone"]) jd_target = TimeConversion.to_julian_day(target_date, input["birth_time"], input["timezone"]) jd_prog = jd_natal + (jd_target - jd_natal) / DAYS_PER_YEAR # a day for a year natal_positions = Synastry.positions_from_chart(natal_chart) natal_cusps = Synastry.cusps_from_chart(natal_chart) natal_sun = natal_positions[SUN] || Planets.calculate_positions(jd_natal)[SUN] prog_sun = Planets.calculate_positions(jd_prog)[SUN] # The Sun only ever moves forward, so the forward arc is the plain # modular difference (< 360° for any human lifespan). arc = (prog_sun - natal_sun) % 360.0 directed_positions = natal_positions.transform_values { |lon| (lon + arc) % 360.0 } { "arc" => arc.round(4), "planets" => Transits.planet_details(directed_positions, natal_cusps), "aspects_to_natal" => Transits.aspects_to_natal( directed_positions, natal_positions, orb_limit: orb_limit, keys: %w[directed_planet natal_planet] ), } end |