Files
Jyotisha/scripts/sudarshana_chakra.py
T

270 lines
9.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Sudarshana Chakra(三轮盘同参) v1.0
参考:PyJHora sudharsana_chakra.py 算法思路 + BPHS标准
License: MIT
Sudarshana Chakra 是结合三个""的综合分析:
内圈 = 本命盘(以Lagna为第1宫)
中圈 = 月亮盘(以Moon星座为第1宫)
外圈 = 太阳盘(以Sun星座为第1宫)
核心分析:三环汇聚 — 同一宫位编号在三圈中有相同行星或主题
"""
from typing import Dict, List, Tuple
def build_rotated_chart(raw_planets: Dict, anchor_sign_idx: int) -> Dict:
"""
以指定星座为第1宫,构建旋转后的12宫宫位映射
Args:
raw_planets: {planet_name: {"sign_idx": int, "degree": float, ...}}
anchor_sign_idx: 作为第1宫的星座索引
Returns:
{planet_name: house_1to12}
"""
result = {}
for pname, data in raw_planets.items():
sign_idx = data.get("sign_idx", 0)
house = ((sign_idx - anchor_sign_idx) % 12) + 1
result[pname] = house
return result
def calculate_sudarshana_chakra(raw_planets: Dict, lagna_sign_idx: int,
moon_sign_idx: int, sun_sign_idx: int) -> Dict:
"""
Sudarshana Chakra 三轮盘同参计算
Args:
raw_planets: 行星数据 {name: {sign_idx, degree, ...}}
lagna_sign_idx: Lagna所在星座索引
moon_sign_idx: 月亮所在星座索引
sun_sign_idx: 太阳所在星座索引
Returns:
{
"charts": {
"lagna_chart": {planet: house}, # 内圈
"moon_chart": {planet: house}, # 中圈
"sun_chart": {planet: house}, # 外圈
},
"convergences": {house_index: {"planets": [names], "circles": int}},
"triple_convergences": [house_indices], # 三环汇聚
"dual_convergences": [house_indices], # 双环汇聚
}
"""
# 构建三个圈
lagna_chart = build_rotated_chart(raw_planets, lagna_sign_idx)
moon_chart = build_rotated_chart(raw_planets, moon_sign_idx)
sun_chart = build_rotated_chart(raw_planets, sun_sign_idx)
# 分析每宫的汇聚情况
convergences = {}
for house_num in range(1, 13):
# 找出三个圈中落入该宫的行星
planets_in = {}
for pname in raw_planets:
if pname in ('Rahu', 'Ketu'):
continue
houses = (
lagna_chart.get(pname, 0),
moon_chart.get(pname, 0),
sun_chart.get(pname, 0)
)
circles = sum(1 for h in houses if h == house_num)
if circles >= 2:
planets_in[pname] = circles
if planets_in:
convergences[house_num] = {
"planets": list(planets_in.keys()),
"max_circles": max(planets_in.values()),
"details": planets_in,
}
# 三环汇聚(最强)
triple = [h for h, data in convergences.items()
if data["max_circles"] == 3]
# 双环汇聚
dual = [h for h, data in convergences.items()
if data["max_circles"] == 2]
return {
"charts": {
"lagna_chart": lagna_chart,
"moon_chart": moon_chart,
"sun_chart": sun_chart,
},
"convergences": convergences,
"triple_convergences": triple,
"dual_convergences": dual,
"triple_count": len(triple),
"dual_count": len(dual),
"summary": _generate_summary(triple, dual, lagna_chart, moon_chart, sun_chart),
}
def calculate_sd_chakra_with_vargas(raw_planets: Dict,
chart_d1: Dict,
chart_d9: Dict,
chart_d10: Dict,
lagna_d1: int,
lagna_d9: int,
lagna_d10: int) -> Dict:
"""
Sudarshana Chakra 现代变体:D1 × D9 × D10 三角形分析
Args:
chart_d1/d9/d10: 各盘的行星宫位数据
lagna_d1/d9/d10: 各盘的Lagna宫位索引
Returns:
三盘跨盘分析结果
"""
# 对各盘以各自Lagna为第1宫旋转
d1_rotated = build_rotated_chart(chart_d1, lagna_d1)
d9_rotated = build_rotated_chart(chart_d9, lagna_d9)
d10_rotated = build_rotated_chart(chart_d10, lagna_d10)
cross_analysis = {}
for house_num in range(1, 13):
planets_d1 = {p for p, h in d1_rotated.items() if h == house_num and p not in ('Rahu','Ketu')}
planets_d9 = {p for p, h in d9_rotated.items() if h == house_num and p not in ('Rahu','Ketu')}
planets_d10 = {p for p, h in d10_rotated.items() if h == house_num and p not in ('Rahu','Ketu')}
# 跨盘一致的行星
cross_all = planets_d1 & planets_d9 & planets_d10
cross_any = planets_d1 | planets_d9 | planets_d10
cross_analysis[house_num] = {
"d1": sorted(planets_d1),
"d9": sorted(planets_d9),
"d10": sorted(planets_d10),
"triple_cross": sorted(cross_all),
"total_planets": len(cross_any),
"unique_planets": len(planets_d1) + len(planets_d9) + len(planets_d10),
}
return {
"method": "Sudarshana Chakra (D1×D9×D10 三角形分析)",
"cross_analysis": cross_analysis,
"strongest_houses": sorted(
[h for h, data in cross_analysis.items() if data["triple_cross"]],
key=lambda h: len(cross_analysis[h]["triple_cross"]),
reverse=True,
),
}
def calculate_sd_chakra_dasha(lagna_sign_idx: int, moon_sign_idx: int,
sun_sign_idx: int, years: int = 108) -> List[Dict]:
"""
Sudarshana Chakra 12年周期大运(SD Cakra Dasha
每年 = 三个圈同时向前推进1宫
第1年 = (L+0, M+0, S+0)
第2年 = (L+1, M+1, S+1)
...
通常推9周期 = 108年
Args:
lagna_sign_idx: Lagna星座索引
moon_sign_idx: 月亮星座索引
sun_sign_idx: 太阳星座索引
years: 预测年数(默认108年,9个周期)
Returns:
[{year: int, period: int, lagna_house, moon_house, sun_house, description}]
"""
result = []
for year in range(1, years + 1):
period = (year - 1) // 12 + 1 # 1-9
offset = (year - 1) % 12
lh = ((lagna_sign_idx + offset) % 12) + 1
mh = ((moon_sign_idx + offset) % 12) + 1
sh = ((sun_sign_idx + offset) % 12) + 1
# 判断该年的主要主题
circles = len({lh, mh, sh})
same_house = lh == mh == sh
desc = f"{period}周期·第{year}"
if same_house:
desc += f"三圈同聚第{lh}宫 ★"
elif circles == 2:
desc += f"内圈{lh}/中圈{mh}/外圈{sh}(双圈一致)"
else:
desc += f"内圈{lh}/中圈{mh}/外圈{sh}"
result.append({
"year": year,
"period": period,
"year_in_period": offset + 1,
"lagna_house": lh,
"moon_house": mh,
"sun_house": sh,
"circles": circles,
"all_same": same_house,
"description": desc,
})
return result
def _generate_summary(triple: List, dual: List,
lagna_chart: Dict, moon_chart: Dict,
sun_chart: Dict) -> str:
"""生成文本摘要"""
lines = []
if triple:
lines.append(f"三环汇聚(最强): 第{'/'.join(map(str, triple))}")
if dual:
lines.append(f"双环汇聚: 第{'/'.join(map(str, dual))}")
if not triple and not dual:
lines.append("本次无三环或双环汇聚")
return " | ".join(lines) if lines else "无汇聚"
def sudarshana_full_analysis(raw_planets: Dict, lagna_sign_idx: int,
moon_sign_idx: int, sun_sign_idx: int,
chart_d1: Dict = None, chart_d9: Dict = None,
chart_d10: Dict = None,
lagna_d9: int = None, lagna_d10: int = None) -> Dict:
"""
完整Sudarshana Chakra分析:三轮盘 + D1×D9×D10三角分析 + 12年周期大运
Returns: 综合报告
"""
# 三轮盘分析
three_ring = calculate_sudarshana_chakra(
raw_planets, lagna_sign_idx, moon_sign_idx, sun_sign_idx
)
# 12年周期大运
dasha = calculate_sd_chakra_dasha(lagna_sign_idx, moon_sign_idx, sun_sign_idx)
# D1×D9×D10 三角分析(如果有数据)
triangle = None
if chart_d1 and chart_d9 and chart_d10 and lagna_d9 is not None and lagna_d10 is not None:
triangle = calculate_sd_chakra_with_vargas(
raw_planets, chart_d1, chart_d9, chart_d10,
lagna_sign_idx, lagna_d9, lagna_d10
)
return {
"method": "Sudarshana Chakra 完整分析(三轮盘 + 三角盘 + 12年周期大运)",
"three_ring_convergences": three_ring,
"d1_d9_d10_triangle": triangle,
"chakra_dasha_12_year_cycle": {
"total_years": len(dasha),
"cycles": 9,
"current_period": dasha[0:12], # 最近12年
},
}