0178dfb3e8
- varga.py: D2-D60 BPHS十六分盘完整计算 - aspects.py: 度数精确相位系统(tight/moderate/loose) - jaimini.py: Chara Karaka 7/8 + Chara Dasha + Karakamsha - nakshatra_advanced.py: Tara Bala + Sub-Lord KP系统 - argala.py: Argala门闩 + Virodha反干预 - tajika.py: Muntha/YearLord/Mudda Dasha/Tri-Pataka - synastry.py: Ashta Koota 36分制 + Mangal Dosha + Papasamya 引擎升级至v3.7.0, 21个子命令全链路验证通过
233 lines
8.7 KiB
Python
233 lines
8.7 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
高级星宿分析模块 v1.0
|
||
Nakshatra深度分析系统
|
||
|
||
支持:
|
||
- Tara Bala(星宿力量匹配)
|
||
- Sub-Lord体系(KP占星)
|
||
- 精确Vimshottari起始点计算
|
||
- Nakshatra兼容性分析
|
||
- Navatara(9星宿组)分类
|
||
"""
|
||
from typing import Dict, List, Tuple
|
||
import math
|
||
|
||
NAK_LIST = [
|
||
("Ashwini","Ketu",7),("Bharani","Venus",20),("Krittika","Sun",6),
|
||
("Rohini","Moon",10),("Mrigashira","Mars",7),("Ardra","Rahu",18),
|
||
("Punarvasu","Jupiter",16),("Pushya","Saturn",19),("Ashlesha","Mercury",17),
|
||
("Magha","Ketu",7),("Purva Phalguni","Venus",20),("Uttara Phalguni","Sun",6),
|
||
("Hasta","Moon",10),("Chitra","Mars",7),("Swati","Rahu",18),
|
||
("Vishakha","Jupiter",16),("Anuradha","Saturn",19),("Jyeshtha","Mercury",17),
|
||
("Mula","Ketu",7),("Purva Ashadha","Venus",20),("Uttara Ashadha","Sun",6),
|
||
("Shravana","Moon",10),("Dhanishta","Mars",7),("Shatabhisha","Rahu",18),
|
||
("Purva Bhadrapada","Jupiter",16),("Uttara Bhadrapada","Saturn",19),("Revati","Mercury",17),
|
||
]
|
||
NAK_NAMES = [n[0] for n in NAK_LIST]
|
||
NAK_LORDS = [n[1] for n in NAK_LIST]
|
||
NAK_YEARS = [n[2] for n in NAK_LIST]
|
||
|
||
# Navatara分组(从月亮星宿开始的9个星宿循环)
|
||
TARA_NAMES = ['Janma(生命)','Sampat(财富)','Vipat(危险)','Kshema(安全)',
|
||
'Pratyak(障碍)','Sadhana(成就)','Vadha(毁灭)','Mitra(友好)','ParamaMitra(至友)']
|
||
TARA_CN = {0:'生命Tara',1:'财富Tara',2:'危险Tara',3:'安全Tara',
|
||
4:'障碍Tara',5:'成就Tara',6:'毁灭Tara',7:'友好Tara',8:'至友Tara'}
|
||
|
||
# Nakshatra元素和属性
|
||
NAK_GANA = { # 气质类型
|
||
0:'Dev(神圣)',1:'Manushya(人类)',2:'Rakshasa(罗刹)',
|
||
3:'Dev',4:'Dev',5:'Manushya',6:'Dev',7:'Dev',8:'Rakshasa',
|
||
9:'Rakshasa',10:'Manushya',11:'Manushya',12:'Dev',13:'Rakshasa',14:'Dev',
|
||
15:'Rakshasa',16:'Dev',17:'Rakshasa',18:'Rakshasa',19:'Manushya',20:'Manushya',
|
||
21:'Dev',22:'Rakshasa',23:'Rakshasa',24:'Manushya',25:'Manushya',26:'Dev',
|
||
}
|
||
NAK_ELEMENT = {
|
||
0:'火',1:'土',2:'火',3:'土',4:'土',5:'风',6:'风',7:'水',8:'水',
|
||
9:'火',10:'土',11:'火',12:'土',13:'火',14:'风',15:'火',16:'水',17:'风',
|
||
18:'火',19:'水',20:'土',21:'土',22:'风',23:'风',24:'水',25:'火',26:'水',
|
||
}
|
||
|
||
|
||
def find_nakshatra(longitude: float) -> Dict:
|
||
"""从恒星黄道经度精确计算Nakshatra"""
|
||
nak_span = 360.0 / 27 # 每个星宿13.333...°
|
||
nak_idx = int(longitude / nak_span) % 27
|
||
nak_start = nak_idx * nak_span
|
||
deg_in_nak = longitude - nak_start
|
||
pada_span = nak_span / 4 # 每个Pada 3.333...°
|
||
pada = int(deg_in_nak / pada_span) + 1
|
||
deg_in_pada = deg_in_nak - (pada - 1) * pada_span
|
||
|
||
return {
|
||
'nakshatra': NAK_NAMES[nak_idx],
|
||
'nakshatra_idx': nak_idx,
|
||
'nakshatra_lord': NAK_LORDS[nak_idx],
|
||
'dasha_years': NAK_YEARS[nak_idx],
|
||
'pada': pada,
|
||
'degree_in_nakshatra': round(deg_in_nak, 4),
|
||
'degree_in_pada': round(deg_in_pada, 4),
|
||
'gana': NAK_GANA.get(nak_idx, ''),
|
||
'element': NAK_ELEMENT.get(nak_idx, ''),
|
||
}
|
||
|
||
|
||
def calc_tara_bala(moon_nak_idx: int, target_nak_idx: int) -> Dict:
|
||
"""
|
||
Tara Bala计算:月亮星宿到目标星宿的9星宿循环关系
|
||
|
||
用于判断某个行星/事件星宿与月亮星宿的关系
|
||
0=Janma(中性), 1=Sampat(吉), 2=Vipat(凶), 3=Kshema(吉),
|
||
4=Pratyak(凶), 5=Sadhana(吉), 6=Vadha(凶), 7=Mitra(吉), 8=ParamaMitra(大吉)
|
||
"""
|
||
distance = (target_nak_idx - moon_nak_idx) % 9
|
||
tara_name = TARA_NAMES[distance]
|
||
tara_cn = TARA_CN[distance]
|
||
|
||
is_auspicious = distance in (1, 3, 5, 7, 8)
|
||
is_dangerous = distance in (2, 4, 6)
|
||
|
||
return {
|
||
'tara_index': distance,
|
||
'tara_name': tara_name,
|
||
'tara_cn': tara_cn,
|
||
'is_auspicious': is_auspicious,
|
||
'is_dangerous': is_dangerous,
|
||
'quality': 'auspicious' if is_auspicious else 'dangerous' if is_dangerous else 'neutral',
|
||
'interpretation': _tara_interp(distance),
|
||
}
|
||
|
||
|
||
def calc_all_tara_balas(moon_nak_idx: int, planet_lons: Dict[str, float]) -> Dict:
|
||
"""计算所有行星相对于月亮的Tara Bala"""
|
||
results = {}
|
||
for pname, lon in planet_lons.items():
|
||
p_nak = find_nakshatra(lon)
|
||
tara = calc_tara_bala(moon_nak_idx, p_nak['nakshatra_idx'])
|
||
results[pname] = {
|
||
'nakshatra': p_nak['nakshatra'],
|
||
'tara': tara,
|
||
}
|
||
return results
|
||
|
||
|
||
def calc_vimshottari_start(moon_longitude: float) -> Dict:
|
||
"""
|
||
精确计算Vimshottari Dasha的起始点
|
||
|
||
返回月亮所在星宿的守护星、已用度数比例、剩余年数
|
||
"""
|
||
nak = find_nakshatra(moon_longitude)
|
||
nak_idx = nak['nakshatra_idx']
|
||
nak_lord = NAK_LORDS[nak_idx]
|
||
total_years = NAK_YEARS[nak_idx]
|
||
|
||
# 已用比例
|
||
nak_span = 360.0 / 27
|
||
nak_start = nak_idx * nak_span
|
||
deg_in_nak = moon_longitude - nak_start
|
||
used_ratio = deg_in_nak / nak_span
|
||
remaining_ratio = 1 - used_ratio
|
||
|
||
# 第一个Mahadasha的剩余年数
|
||
first_mahadasha_remaining = total_years * remaining_ratio
|
||
first_mahadasha_elapsed = total_years * used_ratio
|
||
|
||
return {
|
||
'moon_nakshatra': nak['nakshatra'],
|
||
'moon_nakshatra_lord': nak_lord,
|
||
'moon_pada': nak['pada'],
|
||
'total_dasha_years': total_years,
|
||
'used_ratio': round(used_ratio, 6),
|
||
'remaining_ratio': round(remaining_ratio, 6),
|
||
'first_mahadasha_remaining_years': round(first_mahadasha_remaining, 4),
|
||
'first_mahadasha_elapsed_years': round(first_mahadasha_elapsed, 4),
|
||
'first_mahadasha_lord': nak_lord,
|
||
}
|
||
|
||
|
||
def calc_sub_lord(longitude: float, division: int = 9) -> Dict:
|
||
"""
|
||
Sub-Lord计算(KP占星体系)
|
||
将星宿进一步细分为Sub-Lord和Sub-Sub-Lord
|
||
|
||
参数:
|
||
longitude: 恒星黄道经度
|
||
division: 细分层级(9=Sub-Lord, 81=Sub-Sub-Lord)
|
||
"""
|
||
# 主星宿
|
||
nak = find_nakshatra(longitude)
|
||
nak_span = 360.0 / 27
|
||
|
||
# Sub-Lord: 将星宿按守护星的大运年数比例细分
|
||
total_dasha_years = sum(NAK_YEARS) # 120年
|
||
nak_lord = NAK_NAMES[nak['nakshatra_idx']]
|
||
|
||
# 计算Sub-Lord
|
||
deg_in_nak = nak['degree_in_nakshatra']
|
||
sub_lord_span = nak_span * (NAK_YEARS[NAK_LORDS.index(NAK_LORDS[nak['nakshatra_idx']])]) / total_dasha_years
|
||
|
||
# 简化版:直接按9等分
|
||
sub_span = nak_span / 9
|
||
sub_idx = int(deg_in_nak / sub_span) % 9
|
||
|
||
# Sub-Lord是第sub_idx个行星(从星宿守护星开始的大运顺序)
|
||
DASHA_ORDER = ["Ketu","Venus","Sun","Moon","Mars","Rahu","Jupiter","Saturn","Mercury"]
|
||
nak_lord_idx = DASHA_ORDER.index(NAK_LORDS[nak['nakshatra_idx']])
|
||
sub_lord = DASHA_ORDER[(nak_lord_idx + sub_idx) % 9]
|
||
|
||
return {
|
||
'nakshatra': nak['nakshatra'],
|
||
'nakshatra_lord': nak_lord,
|
||
'sub_lord': sub_lord,
|
||
'sub_index': sub_idx,
|
||
'pada': nak['pada'],
|
||
'degree_in_nakshatra': round(deg_in_nak, 4),
|
||
}
|
||
|
||
|
||
def nakshatra_compatibility(nak1_idx: int, nak2_idx: int) -> Dict:
|
||
"""
|
||
Nakshatra兼容性分析(Koota系统中的星宿匹配部分)
|
||
基于Tara Bala和Nakshatra元素匹配
|
||
"""
|
||
# Tara匹配
|
||
tara = calc_tara_bala(nak1_idx, nak2_idx)
|
||
tara_score = 3 if tara['is_auspicious'] else 0 if tara['is_dangerous'] else 1.5
|
||
|
||
# 元素匹配
|
||
el1 = NAK_ELEMENT.get(nak1_idx, '')
|
||
el2 = NAK_ELEMENT.get(nak2_idx, '')
|
||
el_compatible = el1 == el2 or (el1 in ('火','风') and el2 in ('火','风')) or (el1 in ('土','水') and el2 in ('土','水'))
|
||
|
||
# Gana匹配
|
||
g1 = NAK_GANA.get(nak1_idx, '')
|
||
g2 = NAK_GANA.get(nak2_idx, '')
|
||
gana_score = 6 if g1 == g2 else 3 if ('Dev' in g1 and 'Manushya' in g2) or ('Manushya' in g1 and 'Dev' in g2) else 0
|
||
|
||
return {
|
||
'nak1': NAK_NAMES[nak1_idx],
|
||
'nak2': NAK_NAMES[nak2_idx],
|
||
'tara_bala': tara,
|
||
'tara_score': tara_score,
|
||
'element_match': {'e1': el1, 'e2': el2, 'compatible': el_compatible},
|
||
'gana_match': {'g1': g1, 'g2': g2, 'score': gana_score},
|
||
'overall': 'compatible' if tara_score >= 1.5 and el_compatible else 'challenging' if tara['is_dangerous'] else 'moderate',
|
||
}
|
||
|
||
|
||
def _tara_interp(idx):
|
||
interps = {
|
||
0: '生命Tara—中性,代表自我,不吉不凶',
|
||
1: '财富Tara—吉,带来物质和精神增长',
|
||
2: '危险Tara—凶,需要谨慎,可能带来损失',
|
||
3: '安全Tara—吉,提供保护和稳定',
|
||
4: '障碍Tara—凶,可能面临困难和延误',
|
||
5: '成就Tara—吉,有利于实现目标',
|
||
6: '毁灭Tara—凶,最大凶Tara,需特别注意',
|
||
7: '友好Tara—吉,提供支持和帮助',
|
||
8: '至友Tara—大吉,最强吉Tara',
|
||
}
|
||
return interps.get(idx, '')
|