v6.1.10: Bhava Chalit+Sudarshana Chakra完整实现, Shadbala升级covered, matrix更新
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Bhava Chalit 宫位系统 v1.0
|
||||
MIT License — 基于 dashaflow (adarshj322) 的等宫制实现
|
||||
|
||||
Bhava Chalit = 等分宫制,从上升中点(Lagna - 15°)开始,每宫30度
|
||||
与整宫制(Whole Sign)的区别:靠近星座边界的行星可能跨宫
|
||||
"""
|
||||
from typing import Dict, List, Tuple
|
||||
|
||||
SIGNS = ['Aries','Taurus','Gemini','Cancer','Leo','Virgo',
|
||||
'Libra','Scorpio','Sagittarius','Capricorn','Aquarius','Pisces']
|
||||
|
||||
|
||||
def calculate_bhava_chalit(asc_lon: float, raw_planets: Dict) -> Dict:
|
||||
"""
|
||||
Bhava Chalit 计算(等宫制从上升中点划分)
|
||||
|
||||
规则:
|
||||
- 第1宫中点(Bhava Madhya) = Lagna 经度
|
||||
- 第1宫起点 = Lagna - 15°
|
||||
- 每宫跨度 = 30°
|
||||
- 行星的Bhava宫位可能与其Rashi(整宫)宫位不同
|
||||
|
||||
Args:
|
||||
asc_lon: 上升点黄道经度 (0-360)
|
||||
raw_planets: {planet_name: {"lon": float, ...}}
|
||||
每颗行星需要lon(黄道经度)和sign_idx(星座索引)
|
||||
|
||||
Returns:
|
||||
dict: {planet_name: {"bhava_house": int, "rashi_house": int, "shifted": bool}}
|
||||
"""
|
||||
cusp_start = (asc_lon - 15.0) % 360.0
|
||||
asc_sign_idx = int(asc_lon / 30) % 12
|
||||
|
||||
result = {}
|
||||
for name, rp in raw_planets.items():
|
||||
planet_lon = rp.get("lon", 0)
|
||||
|
||||
# 整宫制
|
||||
sign_idx = rp.get("sign_idx", int(planet_lon / 30) % 12)
|
||||
rashi_house = ((sign_idx - asc_sign_idx) % 12) + 1
|
||||
|
||||
# Bhava 宫位(等宫制)
|
||||
diff = (planet_lon - cusp_start) % 360.0
|
||||
bhava_house = int(diff / 30.0) + 1
|
||||
if bhava_house > 12:
|
||||
bhava_house = 12
|
||||
|
||||
result[name] = {
|
||||
"bhava_house": bhava_house,
|
||||
"rashi_house": rashi_house,
|
||||
"shifted": bhava_house != rashi_house,
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_bhava_cusps(asc_lon: float) -> List[float]:
|
||||
"""
|
||||
获取所有12宫的Bhava Cusp(宫头)经度
|
||||
|
||||
Returns:
|
||||
12个float,第1宫到第12宫的Cusp经度
|
||||
"""
|
||||
cusp_start = (asc_lon - 15.0) % 360.0
|
||||
return [(cusp_start + i * 30.0) % 360.0 for i in range(12)]
|
||||
|
||||
|
||||
def get_bhava_madhyas(asc_lon: float) -> List[float]:
|
||||
"""
|
||||
获取所有12宫的Bhava Madhya(宫中点)经度
|
||||
|
||||
Returns:
|
||||
12个float,第1宫到第12宫的中点经度
|
||||
"""
|
||||
return [(asc_lon + i * 30.0) % 360.0 for i in range(12)]
|
||||
|
||||
|
||||
def get_bhava_ranges(asc_lon: float) -> List[Tuple[float, float]]:
|
||||
"""
|
||||
获取每个宫位的起止范围
|
||||
|
||||
Returns:
|
||||
12个tuple (start, end),第1宫到第12宫的经度范围
|
||||
"""
|
||||
cusps = get_bhava_cusps(asc_lon)
|
||||
ranges = []
|
||||
for i in range(12):
|
||||
start = cusps[i]
|
||||
end = cusps[(i + 1) % 12]
|
||||
if end <= start:
|
||||
end += 360
|
||||
ranges.append((start, end))
|
||||
return ranges
|
||||
|
||||
|
||||
def planet_in_which_bhava(planet_lon: float, asc_lon: float) -> int:
|
||||
"""
|
||||
判断行星经度落在哪个Bhava宫(1-12)
|
||||
"""
|
||||
cusps = get_bhava_cusps(asc_lon)
|
||||
for i in range(12):
|
||||
start = cusps[i]
|
||||
end = cusps[(i + 1) % 12]
|
||||
if end <= start:
|
||||
end += 360
|
||||
plon = planet_lon if planet_lon >= start else planet_lon + 360
|
||||
if start <= plon < end:
|
||||
return i + 1
|
||||
return 12
|
||||
|
||||
|
||||
def cross_house_check(asc_lon: float, planet_name: str, planet_lon: float,
|
||||
planet_sign_idx: int) -> Dict:
|
||||
"""
|
||||
跨宫检查:判断行星是否因Bhava Chalit而换宫
|
||||
|
||||
Returns:
|
||||
{"planet": str, "rashi_house": int, "bhava_house": int,
|
||||
"shifted": bool, "delta_degrees": float}
|
||||
"""
|
||||
asc_sign_idx = int(asc_lon / 30) % 12
|
||||
rashi_house = ((planet_sign_idx - asc_sign_idx) % 12) + 1
|
||||
bhava_house = planet_in_which_bhava(planet_lon, asc_lon)
|
||||
|
||||
delta = abs(bhava_house - rashi_house)
|
||||
if delta > 6:
|
||||
delta = 12 - delta
|
||||
|
||||
return {
|
||||
"planet": planet_name,
|
||||
"rashi_house": rashi_house,
|
||||
"bhava_house": bhava_house,
|
||||
"shifted": bhava_house != rashi_house,
|
||||
"delta_houses": delta,
|
||||
}
|
||||
Reference in New Issue
Block a user