""" Trimshamsa D30 分盘计算模块 v7.0 Jyotish Vedic Astrology Skill D30 (Trimsamsa,三十分盘): - 基于Parashara经典规则(非简单线性循环) - 奇数星座和偶数星座有不同的度数分配表 - 用于分析灾难、苦难、重大危机事件 来源:Parashara Hora Shastra + jyotishganit divisional_charts.py (MIT) v7.0 修正: - 修正D30计算:使用Parashara奇偶星座规则(而非简单30等分循环) - 添加完整行星状态分析(入庙/落陷/友宫/敌宫) - 添加D30宫位推算 - 添加D30凶星集中度分析 """ from typing import Dict, List, Optional SIGN_CN = ['白羊座','金牛座','双子座','巨蟹座','狮子座','处女座', '天秤座','天蝎座','射手座','摩羯座','水瓶座','双鱼座'] SIGN_NAMES = ['Aries','Taurus','Gemini','Cancer','Leo','Virgo', 'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces'] SIGN_LORDS = ['Mars','Venus','Mercury','Moon','Sun','Mercury', 'Venus','Mars','Jupiter','Saturn','Saturn','Jupiter'] # D30 Parashara 规则(参考jyotishganit trimsamsa_from_long) # 奇数星座(Odd signs: Aries,Gemini,Leo,Libra,Sagittarius,Aquarius): # 0-5° → Aries(0), 5-10° → Aquarius(10), 10-18° → Sagittarius(8), # 18-25° → Gemini(2), 25-30° → Libra(6) # 偶数星座(Even signs: Taurus,Cancer,Virgo,Scorpio,Capricorn,Pisces): # 0-5° → Taurus(1), 5-12° → Virgo(5), 12-19° → Capricorn(9), # 19-24° → Pisces(11), 24-30° → Scorpio(7) D30_ODD_RANGES = [ (0, 5, 0), # 0-5° → Aries (5, 10, 10), # 5-10° → Aquarius (10, 18, 8), # 10-18° → Sagittarius (18, 25, 2), # 18-25° → Gemini (25, 30, 6), # 25-30° → Libra ] D30_EVEN_RANGES = [ (0, 5, 1), # 0-5° → Taurus (5, 12, 5), # 5-12° → Virgo (12, 19, 9), # 12-19° → Capricorn (19, 24, 11), # 19-24° → Pisces (24, 30, 7), # 24-30° → Scorpio ] def calc_d30_sign(longitude: float) -> int: """ 计算 D30 分盘中的星座 v7.0(Parashara 规则) 参数: longitude: 行星黄道经度 (0-360) 返回: D30 中的星座序号 (0-11) """ sign = int(longitude // 30) # 本命星座 0-11 deg_in_sign = longitude % 30 # 在星座内的度数 0-29.999 is_odd = (sign % 2 == 0) # 0-based: Aries(0)=odd, Taurus(1)=even... if is_odd: # 奇数星座规则 for start, end, target in D30_ODD_RANGES: if start <= deg_in_sign < end: return target else: # 偶数星座规则 for start, end, target in D30_EVEN_RANGES: if start <= deg_in_sign < end: return target # 回退(不应到达) return sign def calc_d30_chart(planet_lons: Dict[str, float], asc_lon: float = None) -> Dict: """ 计算完整 D30 分盘 v7.0 参数: planet_lons: 本命行星经度字典 {'Sun': lon, 'Moon': lon, ...} asc_lon: D1上升经度(可选,用于推算D30宫位) 返回: dict: 完整D30数据(含宫位推算和行星状态分析) """ d30_planets = {} for pname, lon in planet_lons.items(): d30_s = calc_d30_sign(lon) # 计算D30中的经度(保留原始度数在D30星座内的映射) deg_in_d1_sign = lon % 30 d30_planets[pname] = { 'd30_sign': d30_s, 'd30_sign_name': SIGN_NAMES[d30_s], 'd30_sign_cn': SIGN_CN[d30_s], 'd30_lord': SIGN_LORDS[d30_s], 'd1_degree_in_sign': round(deg_in_d1_sign, 2), } # 推算D30上升和宫位 d30_asc = None d30_houses = {} if asc_lon is not None: d30_asc = calc_d30_sign(asc_lon) d30_asc_name = SIGN_NAMES[d30_asc] for h in range(1, 13): sign_idx = (d30_asc + h - 1) % 12 d30_houses[h] = { 'sign': SIGN_NAMES[sign_idx], 'sign_cn': SIGN_CN[sign_idx], 'lord': SIGN_LORDS[sign_idx], } # 映射行星到D30宫位 for pname, pdata in d30_planets.items(): p_sign = pdata['d30_sign'] house = ((p_sign - d30_asc) % 12) + 1 pdata['d30_house'] = house # 行星状态分析 planet_states = _analyze_d30_planet_states(d30_planets) # 凶星集中度分析 malefic_concentration = _analyze_malefic_concentration(d30_planets, d30_houses) return { 'chart': 'D30_Trimshamsa', 'meaning': '灾难、苦难、重大危机、深层业力', 'method': 'Parashara经典规则(奇偶星座分区法)', 'planets': d30_planets, 'd30_ascendant': { 'sign': SIGN_NAMES[d30_asc] if d30_asc is not None else None, 'sign_cn': SIGN_CN[d30_asc] if d30_asc is not None else None, } if d30_asc is not None else None, 'd30_houses': d30_houses if d30_houses else None, 'planet_states': planet_states, 'malefic_concentration': malefic_concentration, } def analyze_d30_marriage_crisis(d30_planets: Dict, d30_houses: Dict = None) -> Dict: """ D30 婚姻危机分析 v7.0 D30 中第7宫(伴侣)/第8宫(危机)/第12宫(损失)的行星状态 用于判断婚姻中的深层危机模式 """ crisis_factors = [] crisis_score = 0 # Venus在D30的状态 venus_d30 = d30_planets.get('Venus', {}) if venus_d30: v_sign = venus_d30.get('d30_sign') v_house = venus_d30.get('d30_house') crisis_factors.append(f"D30 Venus在{SIGN_CN[v_sign]}") if v_house and v_house in [6, 8, 12]: crisis_score += 2 crisis_factors.append(f" Venus在D30第{v_house}宫 → 婚姻受克") elif v_house and v_house in [1, 4, 7, 10]: crisis_score -= 1 crisis_factors.append(f" Venus在D30第{v_house}宫(角宫) → 婚姻较稳") # Mars在D30的状态 mars_d30 = d30_planets.get('Mars', {}) if mars_d30: m_sign = mars_d30.get('d30_sign') m_house = mars_d30.get('d30_house') if m_house and m_house == 7: crisis_score += 2 crisis_factors.append(f" Mars在D30第7宫 → 伴侣冲突/暴力风险") elif m_house and m_house == 8: crisis_score += 1 crisis_factors.append(f" Mars在D30第8宫 → 婚姻中突发危机") # Saturn在D30的状态 sat_d30 = d30_planets.get('Saturn', {}) if sat_d30: s_house = sat_d30.get('d30_house') if s_house and s_house == 7: crisis_score += 1 crisis_factors.append(f" Saturn在D30第7宫 → 婚姻延迟/冷漠") # D30 8宫检查 if d30_houses: h8_lord = d30_houses.get(8, {}).get('lord') if h8_lord: crisis_factors.append(f"D30 第8宫主:{h8_lord}") # 综合评估 if crisis_score >= 4: severity = "严重(婚姻危机风险高,需专业咨询)" elif crisis_score >= 2: severity = "中等(婚姻中有挑战,需主动经营)" elif crisis_score >= 0: severity = "轻微(婚姻危机风险低)" else: severity = "极低(婚姻较稳定)" return { 'd30_marriage_crisis': crisis_factors, 'crisis_score': crisis_score, 'severity': severity, } def _analyze_d30_planet_states(d30_planets: Dict) -> Dict: """D30 行星状态分析""" states = {} # 擢升/落陷星座表 EXALTATION = {'Sun': 0, 'Moon': 1, 'Mars': 9, 'Mercury': 5, 'Jupiter': 3, 'Venus': 11, 'Saturn': 6} DEBILITATION = {'Sun': 6, 'Moon': 7, 'Mars': 3, 'Mercury': 11, 'Jupiter': 9, 'Venus': 5, 'Saturn': 0} OWN = {'Sun': [4], 'Moon': [3], 'Mars': [0, 7], 'Mercury': [2, 5], 'Jupiter': [8, 11], 'Venus': [1, 6], 'Saturn': [9, 10]} for pname, pdata in d30_planets.items(): d30_sign = pdata.get('d30_sign') if d30_sign is None or pname not in EXALTATION: continue state = 'neutral' if d30_sign == EXALTATION.get(pname, -1): state = 'exalted' elif d30_sign == DEBILITATION.get(pname, -1): state = 'debilitated' elif d30_sign in OWN.get(pname, []): state = 'own' states[pname] = { 'd30_sign': SIGN_NAMES[d30_sign], 'state': state, 'significance': _d30_state_significance(pname, state), } return states def _d30_state_significance(planet: str, state: str) -> str: """D30中行星状态的解读""" if state == 'exalted': return f'{planet}在D30擢升 → 该行星能量在危机中表现为正面转化力' elif state == 'debilitated': return f'{planet}在D30落陷 → 该行星能量在危机中表现为负面放大' elif state == 'own': return f'{planet}在D30入庙 → 该行星能量在危机中表现稳定' return f'{planet}在D30中性 → 危机中表现取决于其他因素' def _analyze_malefic_concentration(d30_planets: Dict, d30_houses: Dict) -> Dict: """D30 凶星集中度分析""" MALEFICS = {'Mars', 'Saturn', 'Rahu', 'Ketu', 'Sun'} concentration = {} # 按星座统计凶星 sign_malefics = {} for pname in MALEFICS: pdata = d30_planets.get(pname) if pdata: s = pdata.get('d30_sign') if s is not None: sign_malefics.setdefault(s, []).append(pname) # 找出凶星集中度最高的星座 for sign_idx, planets in sign_malefics.items(): if len(planets) >= 2: concentration[SIGN_NAMES[sign_idx]] = { 'malefics': planets, 'count': len(planets), 'severity': 'high' if len(planets) >= 3 else 'moderate', } # 按宫位统计(如果有宫位数据) if d30_houses: house_malefics = {} for pname in MALEFICS: pdata = d30_planets.get(pname) if pdata: h = pdata.get('d30_house') if h: house_malefics.setdefault(h, []).append(pname) for house, planets in house_malefics.items(): if len(planets) >= 2: concentration[f'House_{house}'] = { 'malefics': planets, 'count': len(planets), 'severity': 'high' if house in [6, 8, 12] else 'moderate', } return concentration def d30_full_report(birth_planet_lons: Dict[str, float], asc_lon: float = None) -> Dict: """ D30 完整报告 v7.0 """ d30 = calc_d30_chart(birth_planet_lons, asc_lon) crisis = analyze_d30_marriage_crisis( d30['planets'], d30.get('d30_houses') ) return { 'd30_chart': d30, 'marriage_crisis': crisis, 'interpretation': _d30_full_interpretation(d30, crisis), 'method': 'D30 Trimshamsa (Parashara经典规则)', } def _d30_full_interpretation(d30_data: Dict, crisis_data: Dict) -> str: """D30 完整解读 v7.0""" lines = ["【D30 Trimshamsa 三十分盘分析】", ""] lines.append("D30 用于分析灾难、苦难、重大危机和深层业力模式。") lines.append(f"计算方法:Parashara经典规则(奇偶星座分区法)") lines.append("") # 上升信息 asc = d30_data.get('d30_ascendant') if asc and asc.get('sign_cn'): lines.append(f"D30 上升:{asc['sign_cn']} ({asc['sign']})") lines.append("") # 行星状态 states = d30_data.get('planet_states', {}) lines.append("#### 行星在D30中的状态") for pname, sdata in states.items(): state_cn = {'exalted': '擢升', 'debilitated': '落陷', 'own': '入庙', 'neutral': '中性'} lines.append(f" {pname}: {sdata['d30_sign']} ({state_cn.get(sdata['state'], sdata['state'])})") lines.append("") # 凶星集中度 concentration = d30_data.get('malefic_concentration', {}) if concentration: lines.append("#### 凶星集中度") for area, data in concentration.items(): lines.append(f" {area}: {data['malefics']} (集中度={data['severity']})") lines.append("") # 婚姻危机 if crisis_data.get('crisis_factors'): lines.append(f"#### 婚姻危机评估: {crisis_data.get('severity', '未知')}") for f in crisis_data['crisis_factors']: lines.append(f" {f}") lines.append("") lines.append("注意:") lines.append(" 1. D30中凶星集中 = 危机高发领域") lines.append(" 2. 与D1/D9交叉验证危机事件的时间线") lines.append(" 3. 使用Vimshottari Dasha定位具体危机发生时期") return "\n".join(lines) # 便捷函数 def get_d30_sign(lon: float) -> int: """便捷函数:获取 D30 星座""" return calc_d30_sign(lon) if __name__ == '__main__': # 测试 test_lons = {'Sun': 28.5, 'Moon': 65.2, 'Mars': 120.8, 'Mercury': 29.9, 'Jupiter': 185.3, 'Venus': 210.7, 'Saturn': 300.1, 'Rahu': 88.4, 'Ketu': 268.4} report = d30_full_report(test_lons) print(report['interpretation'])