Class: AstroChart::Chart
- Inherits:
-
Object
- Object
- AstroChart::Chart
- Defined in:
- lib/astro_chart/chart.rb
Constant Summary collapse
- HOUSE_SYSTEMS =
Supported house systems: "P" (Placidus) / "W" (Whole Sign) / "E" (Equal, from the ascendant) / "O" (Porphyry).
["P", "W", "E", "O"].freeze
- NEVER_RETROGRADE =
Bodies that can never be retrograde in geocentric longitude.
["太陽", "月亮"].freeze
Instance Attribute Summary collapse
-
#birth_date ⇒ Object
readonly
Returns the value of attribute birth_date.
-
#birth_time ⇒ Object
readonly
Returns the value of attribute birth_time.
-
#house_system ⇒ Object
readonly
Returns the value of attribute house_system.
-
#latitude ⇒ Object
readonly
Returns the value of attribute latitude.
-
#longitude ⇒ Object
readonly
Returns the value of attribute longitude.
-
#timezone ⇒ Object
readonly
Returns the value of attribute timezone.
Instance Method Summary collapse
-
#generate ⇒ Object
Generate complete chart data.
-
#initialize(birth_date:, birth_time:, latitude:, longitude:, timezone:, house_system: "P") ⇒ Chart
constructor
birth_date: "YYYY-MM-DD" birth_time: "HH:MM" latitude / longitude: Float timezone: IANA timezone string (e.g. "Asia/Taipei") house_system: "P" (Placidus, default), "W" (Whole Sign), "E" (Equal, from the ascendant) or "O" (Porphyry).
Constructor Details
#initialize(birth_date:, birth_time:, latitude:, longitude:, timezone:, house_system: "P") ⇒ Chart
birth_date: "YYYY-MM-DD" birth_time: "HH:MM" latitude / longitude: Float timezone: IANA timezone string (e.g. "Asia/Taipei") house_system: "P" (Placidus, default), "W" (Whole Sign), "E" (Equal, from the ascendant) or "O" (Porphyry)
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/astro_chart/chart.rb', line 19 def initialize(birth_date:, birth_time:, latitude:, longitude:, timezone:, house_system: "P") unless HOUSE_SYSTEMS.include?(house_system) raise ArgumentError, "unknown house system #{house_system.inspect} " \ "(expected \"P\", \"W\", \"E\" or \"O\")" end @birth_date = birth_date @birth_time = birth_time @latitude = latitude.to_f @longitude = longitude.to_f @timezone = timezone @house_system = house_system end |
Instance Attribute Details
#birth_date ⇒ Object (readonly)
Returns the value of attribute birth_date.
10 11 12 |
# File 'lib/astro_chart/chart.rb', line 10 def birth_date @birth_date end |
#birth_time ⇒ Object (readonly)
Returns the value of attribute birth_time.
10 11 12 |
# File 'lib/astro_chart/chart.rb', line 10 def birth_time @birth_time end |
#house_system ⇒ Object (readonly)
Returns the value of attribute house_system.
10 11 12 |
# File 'lib/astro_chart/chart.rb', line 10 def house_system @house_system end |
#latitude ⇒ Object (readonly)
Returns the value of attribute latitude.
10 11 12 |
# File 'lib/astro_chart/chart.rb', line 10 def latitude @latitude end |
#longitude ⇒ Object (readonly)
Returns the value of attribute longitude.
10 11 12 |
# File 'lib/astro_chart/chart.rb', line 10 def longitude @longitude end |
#timezone ⇒ Object (readonly)
Returns the value of attribute timezone.
10 11 12 |
# File 'lib/astro_chart/chart.rb', line 10 def timezone @timezone end |
Instance Method Details
#generate ⇒ Object
Generate complete chart data. Returns a Hash with string keys, compatible with the existing JSON API.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/astro_chart/chart.rb', line 37 def generate jd = TimeConversion.to_julian_day(birth_date, birth_time, timezone) cusps, ascendant = Houses.calculate(jd, latitude, longitude, system: house_system) asc_zodiac = Zodiac.sign_name(ascendant) positions = Planets.calculate_positions(jd) planet_details = Planets.build_details(positions, cusps) # Retrograde flags for the 12 physical bodies (太陽/月亮 hard-false, # 南交點 mirrors 北交點 — they share the same axis). retro = retrograde_flags(jd) planet_details.each { |p| p["retrograde"] = retro.fetch(p["planet"], false) } kp = Planets.key_points_data(positions, cusps, ascendant) # Merge aspects into planet details aspect_map = { "太陽" => "sun_aspects", "月亮" => "moon_aspects", "土星" => "saturn_aspects", "金星" => "venus_aspects", "北交點" => "north_node_aspects", "南交點" => "south_node_aspects", } planet_details.each do |planet| key = aspect_map[planet["planet"]] planet["aspects"] = kp[key] if key end # Derived points (福點 / 莉莉絲), placed before the ruler points planet_details.concat(derived_points(jd, positions, cusps, ascendant)) # Append ruler points (定位星 carry no retrograde motion of their own) ruler_points = kp["additional_points"].map { |p| p.merge("retrograde" => false) } planet_details.concat(ruler_points) houses_data = cusps.each_with_index.map do |deg, i| { "house_number" => i + 1, "degree" => deg.round(4), "zodiac" => Zodiac.sign_name(deg), } end # 12-body positions feed pattern detection; the 10 classical planets # (nodes excluded) feed the element/modality statistics. classical = positions.reject { |name, _| name == "北交點" || name == "南交點" } { "input" => { "birth_date" => birth_date, "birth_time" => birth_time, "coordinates" => { "latitude" => latitude, "longitude" => longitude, }, "timezone" => timezone, }, "chart" => { "ascendant" => { "zodiac" => asc_zodiac, "degree" => (ascendant % 30).round(4), "total_degree" => ascendant.round(4), }, "house_system" => house_system, "planets" => planet_details, "houses" => houses_data, "patterns" => Patterns.detect(positions), "element_stats" => Stats.elements(classical), }, } end |