Files
Jyotisha/scripts/bhava_bala.py
732642856 a4f8620a71 v6.2.0: 全面技法宝库升级 — 16个新模块 + 12个文件优化
## 新增模块 (16个)
### P0 精度修复
- ashtakavarga: calc_prastara_av() + calc_sodhita_av()
- kakshya.py: Kakshya评分系统 (8区间×3.75°)
- shadbala.py: Sputa Drishti + Yuddha Bala

### P1 核心升级
- bhava_bala.py: 宫位三元力量 (jyotishganit MIT)
- pancha_mahapurusha.py: PMC完整检测含4层失效条件
- sade_sati.py: Sade Sati+Kantaka Shani
- sudarshana_chakra.py: 三参考点盘+收敛分析
- tajika.py: Sahams 7→36 + Tajika Yogas 10种
- birth_time_rectifier.py: 生时矫正

### P2 覆盖扩展
- kp_system.py: KP Sublord+ABCD Significator (diliprk/VedicAstro MIT)
- synastry.py: 16因子合盘36分制 (dashaflow MIT)
- muhurtha_election.py: 6活动选举 (dashaflow MIT)
- career_analysis.py: 结构化事业引擎
- relationship_analysis.py: 结构化感情引擎
- conditional_dashas.py: Dwisaptati+Shattrimsa+Dwadashottari
- divisional_charts_extended: D81/D108/D144
- remedies.py: 5类补救系统

## 修改文件
jaimini/dasha_calculator/shadbala/SKILL.md/COVERAGE_AUDIT等12个

## 开源复用: 4个MIT项目
2026-06-11 19:03:21 +08:00

247 lines
8.6 KiB
Python
Raw Permalink 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 -*-
"""
Bhava Bala(宫位力量)计算模块
基于jyotishganit (MIT License) 核心算法适配
三组件:
1. Bhava Adhipathi Bala - 宫位主星的Shadbala总分
2. Bhava Dig Bala - 基于星座性质的方向力量
3. Bhava Drik Bala - 基于Sputa Drishti的行星对宫位中点相位
"""
from typing import Dict, List
SIGNS = ['Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo',
'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces']
SIGN_LORDS = {
'Aries': 'Mars', 'Taurus': 'Venus', 'Gemini': 'Mercury', 'Cancer': 'Moon',
'Leo': 'Sun', 'Virgo': 'Mercury', 'Libra': 'Venus', 'Scorpio': 'Mars',
'Sagittarius': 'Jupiter', 'Capricorn': 'Saturn', 'Aquarius': 'Saturn', 'Pisces': 'Jupiter'
}
# 星座性质分类(BPHS标准)
# nara=人类, chatushpada=四足, jalachara=水栖, keeta=虫类, vanaspati=植物
SIGN_NATURE = {
'Aries': 'chatushpada', 'Taurus': 'chatushpada',
'Gemini': 'nara', 'Cancer': 'jalachara',
'Leo': 'chatushpada', 'Virgo': 'nara',
'Libra': 'nara', 'Scorpio': 'keeta',
'Sagittarius': 'nara', 'Capricorn': 'jalachara',
'Aquarius': 'nara', 'Pisces': 'jalachara',
}
# 宫位力量基于星座性质(BPHS标准,单位Virupas
# 索引0-11对应第1-12宫
BHAVA_STRENGTH_FROM_SIGN_NATURE = {
'nara': [30, 20, 10, 20, 10, 20, 30, 20, 10, 20, 10, 20],
'chatushpada': [30, 20, 10, 20, 10, 20, 30, 20, 10, 20, 10, 20],
'jalachara': [20, 30, 10, 30, 10, 30, 20, 30, 10, 30, 10, 30],
'keeta': [10, 20, 30, 20, 30, 20, 10, 20, 30, 20, 30, 20],
'vanaspati': [20, 10, 20, 10, 20, 30, 20, 10, 20, 10, 20, 30],
}
# Sputa Drishti值表(基于角距离的连续相位力量)
def _get_sputa_drishti(angle_diff: float) -> float:
"""基于jxotishganit MIT算法,将精确角距离转换为Sputa Drishti值(0-60)"""
ad = angle_diff % 360
if ad > 180:
ad = 360 - ad
if ad <= 1.0: return 60.0
if ad <= 3.0: return 57.0
if ad <= 7.0: return 51.0
if ad <= 10.0: return 45.0
if ad <= 15.0: return 40.5
if ad <= 20.0: return 30.0
if ad <= 25.0: return 22.5
if ad <= 30.0: return 15.0
if ad <= 40.0: return 12.0
if ad <= 50.0: return 9.0
if ad <= 60.0: return 6.0
if ad <= 75.0: return 4.5
if ad <= 90.0: return 3.0
if ad <= 120.0: return 2.25
if ad <= 150.0: return 1.5
return 0.0
def calc_bhava_adhipathi_bala(house_signs: List[str], planet_shadbala: Dict) -> List[float]:
"""
Bhava Adhipathi Bala:宫位主星的Shadbala总分作为宫位力量基础。
Args:
house_signs: 12宫位的星座名称列表
planet_shadbala: 行星Shadbala总分 dictVirupas
Returns:
12个宫位的adhipathi bala值
"""
bala = []
for sign_name in house_signs:
lord = SIGN_LORDS.get(sign_name, '')
bala.append(planet_shadbala.get(lord, 0))
return bala
def calc_bhava_dig_bala(house_signs: List[str], house_degrees: List[float]) -> List[float]:
"""
Bhava Dig Bala:基于星座性质的宫位方向力量。
Args:
house_signs: 12宫位的星座名称列表
house_degrees: 12宫位的宫头度数列表
Returns:
12个宫位的dig bala值
"""
bala = []
for hno, sign_name in enumerate(house_signs):
nature_key = sign_name
deg = house_degrees[hno] if hno < len(house_degrees) else 15.0
# Sagittarius和Capricorn的双重性质处理
if sign_name == 'Sagittarius':
nature_key = 'Sagittarius_first_half' if deg < 15.0 else 'Sagittarius_second_half'
elif sign_name == 'Capricorn':
nature_key = 'Capricorn_first_half' if deg < 15.0 else 'Capricorn_second_half'
# 处理双性星座
if 'first_half' in nature_key:
# Sagittarius前半=nara, Capricorn前半=jalachara
real_nature = 'nara' if 'Sagittarius' in nature_key else 'jalachara'
elif 'second_half' in nature_key:
real_nature = 'chatushpada' if 'Sagittarius' in nature_key else 'jalachara'
else:
real_nature = SIGN_NATURE.get(sign_name, 'nara')
# 查找对应值
strengths = BHAVA_STRENGTH_FROM_SIGN_NATURE.get(real_nature, BHAVA_STRENGTH_FROM_SIGN_NATURE['nara'])
bala.append(float(strengths[hno] if hno < len(strengths) else 20))
return bala
def calc_bhava_drik_bala(house_signs: List[str], house_degrees: List[float],
asc_sign: str, asc_degree: float,
planet_positions: Dict, planet_shadbala: Dict) -> List[float]:
"""
Bhava Drik Bala:所有行星对宫位中点(Bhava Madhya)的Sputa Drishti相位。
基于jyotishganit MIT算法:计算行星到宫位中点的精确角距离,
使用Sputa Drishti将吉星相位减凶星相位后除以4。
Args:
house_signs: 12宫位的星座名称
house_degrees: 12宫位的宫头度数
asc_sign: 上升星座名称
asc_degree: 上升度数(0-30)
planet_positions: 行星位置 dict {planet: {'sign': str, 'degree': float}}
planet_shadbala: 行星Shadbala dict
Returns:
12个宫位的drik bala值
"""
BENEFICS = ['Jupiter', 'Venus', 'Mercury']
MALEFICS = ['Saturn', 'Mars', 'Sun']
asc_sign_idx = SIGNS.index(asc_sign) if asc_sign in SIGNS else 0
asc_long = asc_sign_idx * 30 + asc_degree
bala = []
for house_idx in range(12):
# 计算宫位中点(Equal House系统中,宫头 + 15°)
house_cusp = (asc_long + house_idx * 30) % 360
house_midpoint = (house_cusp + 15) % 360
benefic_sputa = 0.0
malefic_sputa = 0.0
for planet_name, planet_data in planet_positions.items():
if planet_name not in ['Sun', 'Moon', 'Mars', 'Mercury', 'Jupiter', 'Venus', 'Saturn']:
continue
p_sign = planet_data.get('sign', '')
p_deg = planet_data.get('degree', 0)
if p_sign not in SIGNS:
continue
p_sign_idx = SIGNS.index(p_sign)
p_long = p_sign_idx * 30 + (p_deg % 30)
# 角距离
diff = (p_long - house_midpoint + 180) % 360 - 180 # -180 to +180
dist_deg = abs(diff)
# Sputa Drishti值
sputa = _get_sputa_drishti(dist_deg)
if planet_name in BENEFICS:
benefic_sputa += sputa
elif planet_name in MALEFICS:
malefic_sputa += sputa
drishtipinda = benefic_sputa - malefic_sputa
house_drikbala = min(drishtipinda / 4.0, 20.0)
bala.append(round(house_drikbala, 3))
return bala
def calc_bhava_bala(house_signs: List[str], house_degrees: List[float],
asc_sign: str, asc_degree: float,
planet_positions: Dict, planet_shadbala: Dict) -> Dict:
"""
计算完整Bhava Bala(宫位三元力量)。
Args:
house_signs: 12宫位的星座名称
house_degrees: 12宫位的宫头度数
asc_sign: 上升星座名称
asc_degree: 上升度数
planet_positions: 行星位置
planet_shadbala: 行星Shadbala总分
Returns:
完整的Bhava Bala计算结果
"""
adhipathi = calc_bhava_adhipathi_bala(house_signs, planet_shadbala)
dig_bala = calc_bhava_dig_bala(house_signs, house_degrees)
drik_bala = calc_bhava_drik_bala(house_signs, house_degrees, asc_sign, asc_degree,
planet_positions, planet_shadbala)
houses = []
for i in range(12):
total = adhipathi[i] + dig_bala[i] + drik_bala[i]
if total >= 60:
level = "极强"
elif total >= 50:
level = ""
elif total >= 40:
level = "中强"
elif total >= 30:
level = "中等"
elif total >= 20:
level = ""
else:
level = "极弱"
houses.append({
'house': i + 1,
'sign': house_signs[i] if i < len(house_signs) else SIGNS[i],
'adhipathi_bala': round(adhipathi[i], 2),
'dig_bala': round(dig_bala[i], 2),
'drik_bala': round(drik_bala[i], 2),
'total': round(total, 2),
'level': level,
})
return {
'method': 'Bhava Bala三元力量(基于jyotishganit MIT算法)',
'version': '1.0',
'houses': houses,
'strongest_house': max(houses, key=lambda h: h['total'])['house'],
'weakest_house': min(houses, key=lambda h: h['total'])['house'],
}