diff --git a/SKILL.md b/SKILL.md index c3eea411..b6053612 100644 --- a/SKILL.md +++ b/SKILL.md @@ -83,7 +83,7 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力 ### 2.1 Jaimini系统 - **Chara Karakas**:七大可变象征星(Atmakaraka、Amatyakaraka、Bhratrukaraka、Matrukaraka、Putrakaraka、Gnatikaraka、Darakaraka) - **Chara Dasha**:星座大运系统(基于太阳和地球,反映实际事件) -- **Karakamsha**:灵魂上升点(Atmakaraka所在Navamsha的星座,即AK的D9星座) +- **Karakamsha**:灵魂上升点(Navamsha盘中的AK位置) - **Jaimini Drishti**:星座相位系统 - **应用场景**:婚姻时机预测、事业突破预测、灵魂课题解读 - → 详见 `references/jaimini-complete-system.md` @@ -224,96 +224,14 @@ description: 印度占星(Jyotish)专业解盘与推运系统。核心能力 - → 详见 `references/common-misconceptions.md` - **高级技法与全球方法论**:→ 详见 `references/advanced-techniques.md`、`references/global-astrologer-practical-methodology.md`、`references/global-astrologer-reflections.md`、`references/qin_ruisheng_system.md` -### 13. 深度分析方法论 ⭐ v3.8.0 新增 +### 12.5 深度分析方法论 ⭐ v3.8.0 新增 - **Shadbala实战解读**:五力量组合模式库(全面型/位置依赖型/关系依赖型/时间敏感型/运动受限型)+Avastha联合诊断矩阵(外强内壮/外强内伤/外弱内壮/外弱内伤)+Bhava Bala实战解读+Vimsopaka解读+行星力量综合排名法 → 详见 `references/shadbala-interpretation-methodology.md` - **多Dasha六系统收敛**:Vimshottari+Ashtottari+Yogini+Moola+Narayana+Kalachakra六系统交叉验证(Level 0-4量化)+收敛冲突三种场景处理+PDF数据源提取指南+实战输出模板 → 详见 `references/multi-dasha-convergence-protocol.md` - **Navamsa婚姻深度分析**:D9婚姻五维分析法(上升/DK/Venus/7宫/合相)+Vargottama婚姻意义+19分盘频率分析+Pushkara Navamsa婚姻解读+D9婚姻8步旗标算法实操版+D1与D9矛盾处理原则 → 详见 `references/navamsa-marriage-deep-analysis.md` - **分盘深度阅读**:19分盘系统化三级方法论(Level 1-3)+行星频率分析核心技法(≥40%=核心主题)+Vargottama检测矩阵+分盘组合阅读模式(三角/生命线/财富链/关系链)+Swiss Ephemeris交叉验证 → 详见 `references/divisional-chart-deep-reading.md` - **综合深度分析工作流**:12模块完整工作流(D1→特殊Lagna→Karaka→Shadbala→Avastha→Bhava Bala→Vimsopaka→19分盘→AV→Dasha收敛→D9婚姻→综合结论)+PDF 11页提取最佳实践+引擎调用流程+报告生成+质量检查清单 → 详见 `references/deep-analysis-complete-workflow.md` -### 14. 计算引擎集成(Swiss Ephemeris + 数据库)⭐ v3.4.0 - -**统一引擎入口**:`scripts/jyotish_engine.py` v3.7.1(基于 Swiss Ephemeris 天文计算库) - -**调用方式**:AI 通过 `execute_command` 调用以下子命令(所有输出为 JSON): - -```bash -# 使用 Python 3.11+(请替换为您系统中的 Python 3.11+ 路径) -PYTHON=python3 -SCRIPT=~/.workbuddy/skills/jyotish-vedic-astrology/scripts/jyotish_engine.py -$PYTHON $SCRIPT <子命令> [参数] -``` - -**13大子命令** → **27大子命令**(v3.9 升级): - -| 子命令 | 功能 | 典型用法 | -|--------|------|----------| -| **`full-reading`** | **⭐ v3.7.1 全自动综合解盘(一条命令串起13个模块)** | `full-reading --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | -| `chart` | 完整星盘计算(含Ayanamsa修正)+ `--validate` 附加R1-R10验证 | `chart --validate --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | -| `dasha` | Vimshottari大运时间线+小运展开 | `dasha --moon-lon 326.5 --birthdate REDACTED_DATE --today 2026-04-24` | -| `yoga` | Yoga格局识别(5种Yoga) | `yoga --ascendant Leo --planets 'Sun:Aries:9,Moon:Aquarius:7,...'` | -| `predict` | 三层验证法事件预测(EventPredictionModel规则引擎)+ `--past-verify` 验前事模式 | `predict --chart '' --event-type marriage` | -| `varga` | 分盘计算(D9 Navamsa/D10 Dasamsa) | `varga --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --d9 --d10` | -| `celebrity` | 名人案例查询(SQLite + 15,807条CSV) | `celebrity --name Einstein` | -| `db-stats` | 验证数据库统计(15,840条+10种技法) | `db-stats` | -| `transit` | 行星过境查询(2026-2028) | `transit --year 2026 --month 7` | -| `shadbala` | 六重力量计算(Sthana/Dig/Kala/Chesta/Naisargika/Drik Bala) | `shadbala --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | -| `ashtakavarga` | 八分法计算(BPHS完整8×8矩阵,SAV=337) | `ashtakavarga --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | -| `memory` | Hermes记忆系统(store/search/context/stats) | `memory --action store --content "..." --tags "chart" --importance 8` | -| `validate` | R1-R10数学验证(SAV/BAV/延伸角/Rahu-Ketu/逆行/Dasha/完整性/度数/宫位) | `validate --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | -| `audit` | P1-P12行星审计管线(Identity/Health/Resource/SAV/Dignity/Shadbala/Aspects/Nakshatra/Yogas) | `audit --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | -| `varga-full` | v3.7 BPHS十六分盘精确计算(D2-D60全部16分盘,精确度数输出) | `varga-full --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --divisions D9,D60` | -| `aspects` | v3.7 度数精确相位系统(tight/moderate/loose + 入相位/出相位) | `aspects --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | -| `jaimini` | v3.7 Jaimini完整系统(Chara Karaka 7/8 + Chara Dasha + Karakamsha)+ `--antardasha` Antardasha子周期 | `jaimini --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --mode all --antardasha` | -| `nakshatra-adv` | v3.7 高级Nakshatra(Tara Bala + Sub-Lord KP + 兼容性) | `nakshatra-adv --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --mode all` | -| `argala` | v3.7 Argala门闩系统(主/副Argala + Virodha反干预 + 净评分) | `argala --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | -| `tajika` | v3.7 Tajika年运盘(Muntha + YearLord + Mudda Dasha + Tri-Pataka) | `tajika --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --age 33` | -| `synastry` | v3.7 合盘分析(Ashta Koota 36分 + Mangal Dosha + Papasamya) | `synastry --moon1 310.89 --moon2 45.5 --mars1 90.43 --mars2 120.3` | -| `report` | MD→HTML报告生成(羊皮纸主题) | `report ./report_folder --name 一楠 --lagna Leo` | -| **`prashna`** | **⭐ v3.9 Prashna问事占星(提问时刻星盘+Arudha Lagna+Sphuta组合+Sahams+失物查询)** | `prashna --datetime "2026-04-25 14:30" --lat 39.9 --lon 116.4 --mode chart` | -| **`double-transit-pac`** | **⭐ v3.9 KN Rao Double Transit PAC + D9层(D1/D9双层PAC检查+跨层确认)** | `double-transit-pac --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --date 2026-07-01 --house 7` | -| **`transit-ll7l`** | **⭐ v3.9 Transit LL/7L连接+互换(P5 PAC 98%命中率 + P8过宫 + Parivartana互换)** | `transit-ll7l --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --date 2026-07-01` | -| **`planetary-congregation`** | **⭐ v3.9 行星聚集检测(本命Lagna/7H聚集 + Transit慢行星聚集)** | `planetary-congregation --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --house 7 --transit-date 2026-07-01` | -| **`vivah-saham`** | **⭐ v3.9 Vivah Saham婚姻敏感点(度数级计算 + Transit Jupiter/Saturn PAC激活)** | `vivah-saham --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --transit-date 2026-07-01` | - -**外部数据源**(引擎自动读取): -- 验证数据库:`~/WorkBuddy/Claw/vedic_astrology_validation.db`(15,840条案例,10种技法准确率) -- 名人CSV:`~/WorkBuddy/Claw/vedastro_data/PersonList-15k.csv`(15,807条AA级数据) -- 过境配置:`~/WorkBuddy/Claw/月运过境配置-2026-2028.json`(36个月行星位置) - -**典型工作流**(v3.7.1 升级): - -### 🟢 路径A:精准出生信息(推荐,一条命令搞定) -```bash -# 一键全链路计算(13模块自动串行) -$PYTHON $SCRIPT full-reading --year YYYY --month MM --day DD --hour HH --minute MM --lat XX.XX --lon XX.XX --tz X -# 输出:chart + dasha + yoga + varga_full + aspects + jaimini + nakshatra_adv + argala + tajika + shadbala + ashtakavarga + validation + audit -# 完成后直接进入阶段二(意图识别) -``` - -### 📄 路径B:PDF/文字星盘(用文档数据直接推算) -1. 提取PDF/文字中的所有星象数据(行星落宫、度数、Dasha、Shadbala等) -2. 数据完整性门 → Pass/Limited/Fail -3. 如有出生时间+地点,额外调用 `full-reading` 补充计算v3.7新增模块 -4. 进入阶段二(意图识别) - -### 🔧 路径C:时间不明确(互动式矫正) -1. 收集外表体质+生活事件(3-5轮互动) -2. 多候选时间对比验证(Dasha吻合率+Transit吻合率) -3. D9/D10精确校正 -4. 矫正完成后走路径A -8. `jaimini --mode all` 计算Chara Karaka + Dasha + Karakamsha ⭐ v3.7 -9. `nakshatra-adv --mode all` 计算Tara Bala + Sub-Lord ⭐ v3.7 -10. `argala` 计算门闩干预分析 ⭐ v3.7 -11. `transit` 查询当月过境 → 配合 dasha 做推运分析 -12. `tajika --age 33` 计算年运盘(Muntha+Tri-Pataka) ⭐ v3.7 -13. `predict` 事件预测(EventPredictionModel规则引擎) ⭐ v3.4 -14. `celebrity` 查找相似案例做对比验证 -15. 合盘场景:`synastry --moon1 ... --moon2 ...` 计算Ashta Koota 36分制 ⭐ v3.7 -16. `memory --action store` 保存分析结论供后续引用 ⭐ v3.4 - - -### 15. Prashna 问事占星系统 ⭐ v3.9.0 +### 14. Prashna 问事占星系统 ⭐ v3.9.0 **核心原理:** 基于提问时刻铸造即时星盘,通过共时性原则(Synchronicity)回答具体问题。不需要出生数据。 @@ -359,7 +277,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 **适用场景:** 是非判断、时机选择、失物寻人、婚姻结果、事业方向、健康预后、旅行安全、诉讼胜负、财务投资、单个具体问题快判 -### 16. BCP自然周期法 ⭐ v3.10.0 +### 15. BCP自然周期法 ⭐ v3.10.0 **核心原理:** Bhrigu Chakra Paddhati (BCP) 是Nadi体系下的生命自然周期系统,将人生按月亮起始分为9个固定12年周期,每个周期由不同行星统治。 @@ -391,9 +309,9 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 **应用场景:** 年度运势速判、人生阶段主题分析、Dasha系统交叉验证 → 详见 `references/bhrigu-chakra-paddhati.md` -### 17. 多元技法系统 ⭐ v3.11.0 +### 16. 多元技法系统 ⭐ v3.11.0 -#### 17.1 Yogi / Ava Yogi 行星系统 +#### 16.1 Yogi / Ava Yogi 行星系统 **核心原理:** 基于上升点计算的三个特殊行星指派——Yogi(最吉祥,财富核心来源)、Duplicate Yogi(次吉祥)、Ava Yogi(最凶,障碍来源)。同一颗行星对不同人角色完全不同。 @@ -411,7 +329,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/yogi-avayogi-system.md` -#### 17.2 Tithi Lord 关系影响系统 +#### 16.2 Tithi Lord 关系影响系统 **核心原理:** 出生时所在 Tithi(月亮历日)的统治行星(排除 Ketu,8 颗行星循环),Sanjay Rath 命名为"水龙头"(Faucet),控制 Jala(水元素)即情感流动和关系模式。 @@ -429,7 +347,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/tithi-lord-relationship-system.md` -#### 17.3 Rashi Tulya Navamsa + 根源冲动 +#### 16.3 Rashi Tulya Navamsa + 根源冲动 **核心原理:** 将 D1 行星位置投射到 D9 坐标系(保持星座位置不变),揭示每颗行星的深层动机——Navamsa 主星给行星一个"root impulse"(根源冲动)。 @@ -444,7 +362,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/rashi-tulya-navamsa-root-impulse.md` -#### 17.4 Bhrigu Pada Dasha + 婚姻计数法 +#### 16.4 Bhrigu Pada Dasha + 婚姻计数法 **Bhrigu Pada Dasha:** Bhrigu 体系下的行星推进法(Progression),不同于 BCP(固定周期),专用于婚姻时机预测。基于命盘动态计算,可在 D9 上应用。与 Narayana Dasha D9 变体交叉验证。 @@ -456,7 +374,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/bhrigu-pada-dasha-marriage-counting.md` -#### 17.5 Pancha Pakshi + Nakshatra 三体系 + Savya/Apasavya +#### 16.5 Pancha Pakshi + Nakshatra 三体系 + Savya/Apasavya **Pancha Pakshi(五鸟择时术):** 基于出生月亮 Nakshatra 分配五种鸟,一天五个时段各有高/低振动频率,影响日常活动成功率。Sri K N Rao 推荐。 @@ -471,7 +389,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/pancha-pakshi-nakshatra-systems.md` -### 18. Badhaka障碍星系统 ⭐ v3.12.0 +### 17. Badhaka障碍星系统 ⭐ v3.12.0 **核心原理:** Badhaka(障碍星)是BPHS记载的特殊障碍机制——某些宫位及其主宰行星会对上升产生结构性障碍。分为三类上升: @@ -491,7 +409,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 **应用场景:** 障碍诊断(事业/婚姻/健康受阻)、Badhakesh激活期的风险预警 → 详见 `references/badhaka-obstacle-planet-guide.md` -### 19. B.V. Raman宫位判断方法论 ⭐ v3.12.0 +### 18. B.V. Raman宫位判断方法论 ⭐ v3.12.0 **核心原理:** B.V. Raman体系下完整的12上升吉凶星/Yogakaraka分类表+六步宫位判断法+Maraka死亡指示系统。 @@ -513,7 +431,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/raman-house-judgment-methodology.md` 【古典·B.V. Raman】 -### 20. Shasti Hayani条件Dasha ⭐ v3.12.0 +### 19. Shasti Hayani条件Dasha ⭐ v3.12.0 **核心原理:** Shasti Hayani Dasha是条件性Nakshatra Dasha系统,60年周期,**仅当太阳在1宫时适用**。8行星固定顺序,每行星10年(排除Ketu)。 @@ -525,7 +443,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/shasti-hayani-dasha-guide.md` -### 21. Marc Boney婚姻六步法 ⭐ v3.12.0 +### 20. Marc Boney婚姻六步法 ⭐ v3.12.0 **核心原理:** Marc Boney(K.N. Rao学派嫡传)提出的婚姻/关系评估六步法,核心创新是"三视角"7宫分析。 @@ -543,7 +461,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/marc-boney-marriage-six-step.md` 【现代创新·K.N. Rao学派】 -### 22. V.P. Goel Jaimini Dasha系统 ⭐ v3.12.0 +### 21. V.P. Goel Jaimini Dasha系统 ⭐ v3.12.0 **核心原理:** V.P. Goel在《Predicting through Jaimini Astrology》中记载的10种Jaimini Dasha系统。Skill此前仅有Chara Dasha深度覆盖,本次扩展至全部系统概览。 @@ -567,84 +485,82 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 → 详见 `references/vp-goel-jaimini-dasha-systems.md` 【现代·V.P. Goel研究】 -### 23. KN Rao Double Transit PAC + D9 层 ⭐ v3.9 +### 13. 计算引擎集成(Swiss Ephemeris + 数据库)⭐ v3.4.0 -**核心原理:** KN Rao 体系的 Double Transit 必须同时检查 D1 和 D9(Navamsa)两个层面。传统实现只检查 D1 的 Saturn+Jupiter 相位重叠,但 KN Rao 明确指出**宫主星的 D9 星座**是第三个必须检查的目标。 +**统一引擎入口**:`scripts/jyotish_engine.py` v3.7.1(基于 Swiss Ephemeris 天文计算库) -**PAC 检查体系(Position-Aspect-Conjunction):** -- **P(Position)**:Transit 行星与目标在同一宫 -- **A(Aspect)**:Graha Drishti 相位(Jupiter: 5/7/9, Saturn: 3/7/10, Mars: 4/7/8) -- **C(Conjunction)**:度数级合相 ≤10° +**调用方式**:AI 通过 `execute_command` 调用以下子命令(所有输出为 JSON): -**三层检查结构:** -1. **D1 层**:Saturn/Jupiter PAC → 事件宫、宫主、LL、对宫主 -2. **D9 层**:Saturn/Jupiter PAC → D9 宫主、D9 Asc、**宫主D9星座**(KN Rao 关键第三目标)、LL D9 星座 -3. **跨层**:Jupiter(D1) + Saturn(D9) 或反之激活同一主题 → 间接确认 +```bash +# 使用系统 Python 3.11 +PYTHON=/Library/Frameworks/Python.framework/Versions/3.11/bin/python3 +SCRIPT=~/.workbuddy/skills/jyotish-vedic-astrology/scripts/jyotish_engine.py +$PYTHON $SCRIPT <子命令> [参数] +``` -**CLI 子命令**:`double-transit-pac --date YYYY-MM-DD --house 7` +**13大子命令** → **22大子命令**(v3.7.1 升级): -**JS 函数**:`computeDoubleTransitPAC(transitPlanets, natalPlanets, natalAscSign, natalAscDegree, eventHouse)` +| 子命令 | 功能 | 典型用法 | +|--------|------|----------| +| **`full-reading`** | **⭐ v3.7.1 全自动综合解盘(一条命令串起13个模块)** | `full-reading --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | +| `chart` | 完整星盘计算(含Ayanamsa修正)+ `--validate` 附加R1-R10验证 | `chart --validate --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | +| `dasha` | Vimshottari大运时间线+小运展开 | `dasha --moon-lon 326.5 --birthdate REDACTED_DATE --today 2026-04-24` | +| `yoga` | Yoga格局识别(5种Yoga) | `yoga --ascendant Leo --planets 'Sun:Aries:9,Moon:Aquarius:7,...'` | +| `predict` | 三层验证法事件预测(EventPredictionModel规则引擎)+ `--past-verify` 验前事模式 | `predict --chart '' --event-type marriage` | +| `varga` | 分盘计算(D9 Navamsa/D10 Dasamsa) | `varga --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --d9 --d10` | +| `celebrity` | 名人案例查询(SQLite + 15,807条CSV) | `celebrity --name Einstein` | +| `db-stats` | 验证数据库统计(15,840条+10种技法) | `db-stats` | +| `transit` | 行星过境查询(2026-2028) | `transit --year 2026 --month 7` | +| `shadbala` | 六重力量计算(Sthana/Dig/Kala/Chesta/Naisargika/Drik Bala) | `shadbala --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | +| `ashtakavarga` | 八分法计算(BPHS完整8×8矩阵,SAV=337) | `ashtakavarga --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | +| `memory` | Hermes记忆系统(store/search/context/stats) | `memory --action store --content "..." --tags "chart" --importance 8` | +| `validate` | R1-R10数学验证(SAV/BAV/延伸角/Rahu-Ketu/逆行/Dasha/完整性/度数/宫位) | `validate --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | +| `audit` | P1-P12行星审计管线(Identity/Health/Resource/SAV/Dignity/Shadbala/Aspects/Nakshatra/Yogas) | `audit --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | +| `varga-full` | v3.7 BPHS十六分盘精确计算(D2-D60全部16分盘,精确度数输出) | `varga-full --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --divisions D9,D60` | +| `aspects` | v3.7 度数精确相位系统(tight/moderate/loose + 入相位/出相位) | `aspects --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | +| `jaimini` | v3.7 Jaimini完整系统(Chara Karaka 7/8 + Chara Dasha + Karakamsha) | `jaimini --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --mode all` | +| `nakshatra-adv` | v3.7 高级Nakshatra(Tara Bala + Sub-Lord KP + 兼容性) | `nakshatra-adv --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --mode all` | +| `argala` | v3.7 Argala门闩系统(主/副Argala + Virodha反干预 + 净评分) | `argala --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8` | +| `tajika` | v3.7 Tajika年运盘(Muntha + YearLord + Mudda Dasha + Tri-Pataka) | `tajika --year REDACTED_YEAR --month 4 --day 17 --hour 14 --minute 45 --lat 36.6 --lon 114.5 --tz 8 --age 33` | +| `synastry` | v3.7 合盘分析(Ashta Koota 36分 + Mangal Dosha + Papasamya) | `synastry --moon1 310.89 --moon2 45.5 --mars1 90.43 --mars2 120.3` | +| `report` | MD→HTML报告生成(羊皮纸主题) | `report ./report_folder --name 一楠 --lagna Leo` | +| **`prashna`** | **⭐ v3.9 Prashna问事占星(提问时刻星盘+Arudha Lagna+Sphuta组合+Sahams+失物查询)** | `prashna --datetime "2026-04-25 14:30" --lat 39.9 --lon 116.4 --mode chart` | -**精度**:KN Rao 体系 110-115 星盘测试 97% 准确率(使用 D9 Navamsa) +**外部数据源**(引擎自动读取): +- 验证数据库:`~/WorkBuddy/Claw/vedic_astrology_validation.db`(15,840条案例,10种技法准确率) +- 名人CSV:`~/WorkBuddy/Claw/vedastro_data/PersonList-15k.csv`(15,807条AA级数据) +- 过境配置:`~/WorkBuddy/Claw/月运过境配置-2026-2028.json`(36个月行星位置) -### 24. Transit LL/7L 连接 + Parivartana 互换 ⭐ v3.9 +**典型工作流**(v3.7.1 升级): -**核心原理:** 婚姻事件发生时,Lagna Lord(LL)和 7th Lord(7L)的 Transit 位置必然与本命盘产生 PAC 连接。这是 Rao 八参数验证体系中最强的 Transit 指标之一。 +### 🟢 路径A:精准出生信息(推荐,一条命令搞定) +```bash +# 一键全链路计算(13模块自动串行) +$PYTHON $SCRIPT full-reading --year YYYY --month MM --day DD --hour HH --minute MM --lat XX.XX --lon XX.XX --tz X +# 输出:chart + dasha + yoga + varga_full + aspects + jaimini + nakshatra_adv + argala + tajika + shadbala + ashtakavarga + validation + audit +# 完成后直接进入阶段二(意图识别) +``` -**三项检查:** -- **P5(98%命中率)**:Transit LL PAC natal 7L / Transit 7L PAC natal LL — 双向检查 -- **P8(59%命中率)**:Transit LL 过 7H 或 Transit 7L 过 Lagna — 位置检查 -- **Parivartana 互换**:Transit LL 在 natal 7L 星座 且 Transit 7L 在 natal LL 星座 — 最强信号 +### 📄 路径B:PDF/文字星盘(用文档数据直接推算) +1. 提取PDF/文字中的所有星象数据(行星落宫、度数、Dasha、Shadbala等) +2. 数据完整性门 → Pass/Limited/Fail +3. 如有出生时间+地点,额外调用 `full-reading` 补充计算v3.7新增模块 +4. 进入阶段二(意图识别) -**CLI 子命令**:`transit-ll7l --date YYYY-MM-DD` - -**JS 函数**:`computeTransitLL7L(transitPlanets, natalPlanets, natalAscSign)` - -### 25. 行星聚集检测 ⭐ v3.9 - -**核心原理:** 本命盘中 Lagna 或 7H 有多颗行星聚集,会显著强化该宫位的事件密度。Transit 时慢行星(Saturn/Jupiter/Rahu/Ketu)聚集事件宫,是事件触发的辅助信号。 - -**检测规则:** -- Sun 在 Lagna 或 ≥3 颗行星在 Lagna → Lagna 聚集触发 -- Sun 在 7H 或 ≥3 颗行星在 7H → 7H 聚集触发 -- Transit 慢行星 ≥2 颗在事件宫 → Transit 聚集触发 - -**CLI 子命令**:`planetary-congregation --house 7 --transit-date YYYY-MM-DD` - -**JS 函数**:`computePlanetaryCongregation(natalPlanets, natalAscSign, transitPlanets, eventHouse)` - -### 26. Vivah Saham 婚姻敏感点 ⭐ v3.9 - -**核心原理:** Vivah Saham(婚姻敏感点)是 Prashna 体系中专门用于婚姻预测的 Saham,公式为 `norm(Venus - Saturn + Asc)`。Transit 时 Jupiter 和 Saturn 同时 PAC 到 Vivah Saham 经度,是婚姻事件的精确触发信号。 - -**计算:** 度数级精确输出(sign + degree_in_sign + nakshatra + pada) - -**Transit 激活检测:** -- Jupiter PAC → Vivah Saham(单独激活) -- Saturn PAC → Vivah Saham(单独激活) -- **双星激活** = Jupiter AND Saturn 同时 PAC → 强确认信号 -- Venus Transit 过 Saham 星座 → 辅助信号 - -**CLI 子命令**:`vivah-saham --transit-date YYYY-MM-DD` - -**JS 函数**:`computeVivahSaham(natalPlanets, natalAscDegree, transitPlanets)` - -### 27. Chara Dasha Antardasha 子周期 ⭐ v3.9 - -**核心原理:** Chara Dasha 的 Antardasha(子周期)在 Mahadasha 内按同方向从 Mahadasha 星座开始排列,每个 Antardasha 时长按 `(该子星座独立年数 / 总年数) × Mahadasha 年数` 比例分配。 - -**CLI 参数**:`jaimini --mode dasha --antardasha` - -**Python 函数**:`calc_chara_dasha_with_antardasha(asc_sign_idx, planet_longitudes, birth_year, birth_month)` - -**协同验证结果(4名人案例):** -| 功能 | 命中率 | -|------|--------| -| Double Transit PAC+D9 | 50% | -| Transit LL/7L P5 | 50% | -| Vivah Saham 双星激活 | 50% | -| 行星聚集 | 50% | -| **无确认率** | **0%** | +### 🔧 路径C:时间不明确(互动式矫正) +1. 收集外表体质+生活事件(3-5轮互动) +2. 多候选时间对比验证(Dasha吻合率+Transit吻合率) +3. D9/D10精确校正 +4. 矫正完成后走路径A +8. `jaimini --mode all` 计算Chara Karaka + Dasha + Karakamsha ⭐ v3.7 +9. `nakshatra-adv --mode all` 计算Tara Bala + Sub-Lord ⭐ v3.7 +10. `argala` 计算门闩干预分析 ⭐ v3.7 +11. `transit` 查询当月过境 → 配合 dasha 做推运分析 +12. `tajika --age 33` 计算年运盘(Muntha+Tri-Pataka) ⭐ v3.7 +13. `predict` 事件预测(EventPredictionModel规则引擎) ⭐ v3.4 +14. `celebrity` 查找相似案例做对比验证 +15. 合盘场景:`synastry --moon1 ... --moon2 ...` 计算Ashta Koota 36分制 ⭐ v3.7 +16. `memory --action store` 保存分析结论供后续引用 ⭐ v3.4 ## 使用方法 @@ -881,7 +797,7 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 ## 能力水平 -当前能力水平:**顶级(5.0/5)** +当前能力水平:**顶级专业占星师水平(6.0/5)** ### 核心优势(按能力域分组) @@ -913,11 +829,11 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 ## 更新记录 -详见 `CHANGELOG.md`。当前版本:v4.2.0。 +详见 `CHANGELOG.md`。当前版本:v3.12.1。 ## 参考资料 -本Skill包含以下参考资料(存储在references/目录),共102个文件: +本Skill包含以下参考资料(存储在references/目录),共100个文件: ### AI解盘工作流(2个)⭐ v3.2 新增 0. **ai-reading-workflow-prompt.md**:AI解盘工作流Prompt工程(7阶段完整执行引擎:PDF提取→意图路由→静态分析10步→动态推运7步→应期输出→补救→现代措辞包装)⭐⭐⭐⭐⭐ @@ -1053,15 +969,15 @@ python3 scripts/jyotish_engine.py prashna --datetime "2026-04-25 14:30" --lat 39 ### 10本PDF书籍集成(5个)⭐ v3.12.0 新增 94. **badhaka-obstacle-planet-guide.md**:Badhaka障碍星系统完整指南(12上升Badhaka Sthana+Badhakesh对照表+三种上升类型规则+Leo上升Badhakesh=Mars分析+五步分析协议+补救措施)⭐⭐⭐⭐⭐ v3.12.0 新增 【古典·BPHS】 95. **raman-house-judgment-methodology.md**:B.V. Raman宫位判断方法论(12上升完整Benefic/Malefic/Yogakaraka表+六步宫位判断法+第七宫婚姻分析六维度+Maraka死亡指示系统+Mangal Dosha完整规则)⭐⭐⭐⭐⭐ v3.12.0 新增 【古典·B.V. Raman】 -96. **shasti-hayani-dasha-guide.md**:Shasti Hayani条件Dasha指南(60年周期+太阳1宫条件+8行星固定顺序Jupiter→Rahu+三级Antar结构+与其他条件Dasha对比)⭐⭐⭐⭐ v3.12.0 新增 -97. **marc-boney-marriage-six-step.md**:Marc Boney婚姻六步法(三视角7宫评估法+同居vs正式婚姻区分+Dasha/DK/Double Transit整合+K.N. Rao学派跨系统验证立场+V.P. Goel+K.N. Rao书证支持多系统整合)⭐⭐⭐⭐⭐ v3.12.0 新增 【现代创新·K.N. Rao学派】 -98. **vp-goel-jaimini-dasha-systems.md**:V.P. Goel Jaimini Dasha系统概览(10种Jaimini Dasha:Chara/Mandook/Sthira/Narayan/Navamsha/NSD/Trikon/Atmanadi等+实现优先级P0-P3+Argala四分之一度阻碍规则完整表+Jaimini星座相位规则)⭐⭐⭐⭐ v3.12.0 新增 【现代·V.P. Goel研究】 +93. **shasti-hayani-dasha-guide.md**:Shasti Hayani条件Dasha指南(60年周期+太阳1宫条件+8行星固定顺序Jupiter→Rahu+三级Antar结构+与其他条件Dasha对比)⭐⭐⭐⭐ v3.12.0 新增 +94. **marc-boney-marriage-six-step.md**:Marc Boney婚姻六步法(三视角7宫评估法+同居vs正式婚姻区分+Dasha/DK/Double Transit整合+K.N. Rao学派跨系统验证立场+V.P. Goel+K.N. Rao书证支持多系统整合)⭐⭐⭐⭐⭐ v3.12.0 新增 【现代创新·K.N. Rao学派】 +95. **vp-goel-jaimini-dasha-systems.md**:V.P. Goel Jaimini Dasha系统概览(10种Jaimini Dasha:Chara/Mandook/Sthira/Narayan/Navamsha/NSD/Trikon/Atmanadi等+实现优先级P0-P3+Argala四分之一度阻碍规则完整表+Jaimini星座相位规则)⭐⭐⭐⭐ v3.12.0 新增 【现代·V.P. Goel研究】 ### 精准解盘方法论(1个)⭐ v3.12.1 新增 -99. **precision-reading-methodology.md**:精准解盘与推运方法论(六大共识原则+PACDARES本命盘分析框架+九层复合方法L1-L9+L3矛盾检查协议+验证驱动分析流程+三级置信度系统+10条常见教条失误纠正+经典文献审慎使用BPHS考证+实战五步法)⭐⭐⭐⭐⭐ v3.12.1 新增 【核心方法论·多师共识:K.N. Rao+V.K. Choudhry+Marc Boney+Hart de Fouw+Sanjay Rath+Shyamasundara Dasa】 +96. **precision-reading-methodology.md**:精准解盘与推运方法论(六大共识原则+PACDARES本命盘分析框架+九层复合方法L1-L9+L3矛盾检查协议+验证驱动分析流程+三级置信度系统+10条常见教条失误纠正+经典文献审慎使用BPHS考证+实战五步法)⭐⭐⭐⭐⭐ v3.12.1 新增 【核心方法论·多师共识:K.N. Rao+V.K. Choudhry+Marc Boney+Hart de Fouw+Sanjay Rath+Shyamasundara Dasa】 ### 强制外部验证门控(1个)⭐ v4.2.0 新增 -100. **mandatory-verification-gate-protocol.md**:强制外部验证门控协议(MEVG)完整规范(核心问题诊断+三步验证法V1/V2/V3+门控触发条件表+权威来源优先级+强制输出格式+门控位置与执行时机+通过/失败标准+每阶段必检索关键词模板+历史违反记录+执行纪律)⭐⭐⭐⭐⭐ v4.2.0 新增 【核心方法论·强制验证·与"不跳步"同级】 +97. **mandatory-verification-gate-protocol.md**:强制外部验证门控协议(MEVG)完整规范(核心问题诊断+三步验证法V1/V2/V3+门控触发条件表+权威来源优先级+强制输出格式+门控位置与执行时机+通过/失败标准+每阶段必检索关键词模板+历史违反记录+执行纪律)⭐⭐⭐⭐⭐ v4.2.0 新增 【核心方法论·强制验证·与"不跳步"同级】 ## 模板文件 diff --git a/avastha_calculator.py b/avastha_calculator.py new file mode 100644 index 00000000..217894f5 --- /dev/null +++ b/avastha_calculator.py @@ -0,0 +1,481 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Avastha Calculator - 行星状态计算器 +印度占星 Avastha(行星状态)系统 + +核心功能: +- Bala Avastha(年龄状态):5种生命阶段 +- Jagrat Avastha(警觉状态):3种意识状态 +- Deeptadi Avastha(情绪状态):15种情绪/能量状态 +- Lajjitadi Avastha(羞耻状态):6种社会状态 +- Shayanadi Avastha(姿态状态):12种行为模式 + +参考文献: +- Brihat Parashara Hora Shastra (BPHS) Chapter 47-48 +- Phaladeepika by Mantreswara +- Jataka Parijata by Vaidyanatha Dikshita +""" + +from typing import Dict, List, Tuple +from enum import Enum + +class BalaAvastha(Enum): + """年龄状态(5种生命阶段)""" + INFANT = "Infant" # 婴儿期(0-6度) + YOUNG = "Young" # 少年期(6-12度) + YOUTH = "Youth" # 青年期(12-18度) + OLD = "Old" # 老年期(18-24度) + DEAD = "Dead" # 死亡期(24-30度) + +class JagratAvastha(Enum): + """警觉状态(3种意识状态)""" + AWAKE = "Awake" # 清醒(Jagrat) + DREAMING = "Dreaming" # 梦境(Swapna) + DEEP_SLEEP = "Deep Sleep" # 深睡(Sushupti) + +class DeeptadiAvastha(Enum): + """情绪状态(15种)- Deeptadi Avastha""" + DEEPTA = "Deepta" # 光辉(Exalted) + SWASTHA = "Swastha" # 舒适(Own Sign) + MUDITA = "Mudita" # 快乐(Friend's Sign) + SHANTA = "Shanta" # 平静(Neutral Sign) + DINA = "Dina" # 沮丧(Enemy Sign) + VIKALA = "Vikala" # 残缺(Debilitated) + KHALA = "Khala" # 恶意(Combust) + KOPA = "Kopa" # 愤怒(Defeated in War) + GARVITA = "Garvita" # 骄傲(Victorious in War) + KSHUDITA = "Kshudita" # 饥饿(In Sandhi) + TRUSHITA = "Trushita" # 口渴(In Gandanta) + MUDITA_SPECIAL = "Mudita" # 特殊快乐(Aspected by Jupiter) + KSHOBHITA = "Kshobhita" # 激动(Aspected by Mars) + LAJJITA = "Lajjita" # 羞耻(Aspected by Saturn) + GARVITA_SPECIAL = "Garvita" # 特殊骄傲(Aspected by Mercury) + +class LajjitadiAvastha(Enum): + """羞耻状态(6种社会状态)""" + LAJJITA = "Lajjita" # 羞耻(与敌对行星同宫) + GARVITA = "Garvita" # 骄傲(入庙) + KSHUDITA = "Kshudita" # 饥饿(在6/8/12宫) + TRUSHITA = "Trushita" # 口渴(在火象星座) + MUDITA = "Mudita" # 快乐(与友好行星同宫) + KSHOBHITA = "Kshobhita" # 激动(与火星同宫) + +class ShayanadiAvastha(Enum): + """姿态状态(12种行为模式)""" + SHAYANA = "Shayana" # 躺卧(在水象星座) + UPAVESHANA = "Upaveshana" # 坐着(在土象星座) + NETRAPANI = "Netrapani" # 手持武器(在火象星座) + PRAKASHANA = "Prakashana" # 显现(在风象星座) + GAMANA = "Gamana" # 行走(在双体星座) + AGAMANA = "Agamana" # 到来(在固定星座) + SABHA = "Sabha" # 集会(在变动星座) + AGAMA = "Agama" # 学习(在水星星座) + BHOJANA = "Bhojana" # 进食(在金星星座) + NRITYALIPSA = "Nrityalipsa" # 舞蹈(在月亮星座) + KAUTUKA = "Kautuka" # 好奇(在木星星座) + NIDRA = "Nidra" # 睡眠(在土星星座) + +class AvasthaCalculator: + """行星状态计算器""" + + # 星座分类 + FIRE_SIGNS = ["Aries", "Leo", "Sagittarius"] + EARTH_SIGNS = ["Taurus", "Virgo", "Capricorn"] + AIR_SIGNS = ["Gemini", "Libra", "Aquarius"] + WATER_SIGNS = ["Cancer", "Scorpio", "Pisces"] + + DUAL_SIGNS = ["Gemini", "Virgo", "Sagittarius", "Pisces"] + FIXED_SIGNS = ["Taurus", "Leo", "Scorpio", "Aquarius"] + MOVABLE_SIGNS = ["Aries", "Cancer", "Libra", "Capricorn"] + + # 行星主宰星座 + PLANET_SIGNS = { + "Mercury": ["Gemini", "Virgo"], + "Venus": ["Taurus", "Libra"], + "Moon": ["Cancer"], + "Jupiter": ["Sagittarius", "Pisces"], + "Saturn": ["Capricorn", "Aquarius"], + "Mars": ["Aries", "Scorpio"], + "Sun": ["Leo"] + } + + # 行星入庙/落陷度数 + EXALTATION = { + "Sun": ("Aries", 10), + "Moon": ("Taurus", 3), + "Mars": ("Capricorn", 28), + "Mercury": ("Virgo", 15), + "Jupiter": ("Cancer", 5), + "Venus": ("Pisces", 27), + "Saturn": ("Libra", 20) + } + + DEBILITATION = { + "Sun": ("Libra", 10), + "Moon": ("Scorpio", 3), + "Mars": ("Cancer", 28), + "Mercury": ("Pisces", 15), + "Jupiter": ("Capricorn", 5), + "Venus": ("Virgo", 27), + "Saturn": ("Aries", 20) + } + + def __init__(self): + pass + + def calculate_all_avasthas(self, planet: str, sign: str, degree: float, + house: int, conjunctions: List[str] = None, + aspects: List[str] = None, is_combust: bool = False, + is_retrograde: bool = False) -> Dict[str, any]: + """ + 计算行星的所有Avastha状态 + + Args: + planet: 行星名 + sign: 所在星座 + degree: 星座内度数(0-30) + house: 所在宫位(1-12) + conjunctions: 合相的行星列表 + aspects: 相位的行星列表 + is_combust: 是否燃烧 + is_retrograde: 是否逆行 + + Returns: + 所有Avastha状态的字典 + """ + result = { + "planet": planet, + "sign": sign, + "degree": round(degree, 4), + "house": house, + "avasthas": {} + } + + # 1. Bala Avastha(年龄状态) + result["avasthas"]["Bala"] = self._calculate_bala_avastha(degree) + + # 2. Jagrat Avastha(警觉状态) + result["avasthas"]["Jagrat"] = self._calculate_jagrat_avastha(planet, sign, house) + + # 3. Deeptadi Avastha(情绪状态) + result["avasthas"]["Deeptadi"] = self._calculate_deeptadi_avastha( + planet, sign, degree, is_combust, aspects + ) + + # 4. Lajjitadi Avastha(羞耻状态) + result["avasthas"]["Lajjitadi"] = self._calculate_lajjitadi_avastha( + planet, sign, house, conjunctions + ) + + # 5. Shayanadi Avastha(姿态状态) + result["avasthas"]["Shayanadi"] = self._calculate_shayanadi_avastha(planet, sign) + + # 6. 综合解读 + result["interpretation"] = self._generate_interpretation(result["avasthas"]) + + # 7. 补救建议 + result["remedies"] = self._generate_remedies(planet, result["avasthas"]) + + return result + + def _calculate_bala_avastha(self, degree: float) -> Dict: + """计算Bala Avastha(年龄状态)""" + if degree < 6: + state = BalaAvastha.INFANT + strength = 0.2 + meaning = "婴儿期:行星力量微弱,潜力未开发,需要时间成长" + elif degree < 12: + state = BalaAvastha.YOUNG + strength = 0.5 + meaning = "少年期:行星力量增长中,开始显现特质,但尚未成熟" + elif degree < 18: + state = BalaAvastha.YOUTH + strength = 1.0 + meaning = "青年期:行星力量最强,充满活力,能够充分发挥作用" + elif degree < 24: + state = BalaAvastha.OLD + strength = 0.7 + meaning = "老年期:行星力量开始衰退,经验丰富但活力下降" + else: + state = BalaAvastha.DEAD + strength = 0.3 + meaning = "死亡期:行星力量极弱,难以发挥作用,需要补救" + + return { + "state": state.value, + "degree_range": f"{int(degree//6)*6}-{int(degree//6)*6+6}°", + "strength": strength, + "meaning": meaning + } + + def _calculate_jagrat_avastha(self, planet: str, sign: str, house: int) -> Dict: + """计算Jagrat Avastha(警觉状态)""" + # 简化规则: + # Awake: 在角宫(1,4,7,10) + # Dreaming: 在续宫(2,5,8,11) + # Deep Sleep: 在果宫(3,6,9,12) + + if house in [1, 4, 7, 10]: + state = JagratAvastha.AWAKE + meaning = "清醒状态:行星完全活跃,能够主动发挥作用,影响显著" + elif house in [2, 5, 8, 11]: + state = JagratAvastha.DREAMING + meaning = "梦境状态:行星半活跃,作用不稳定,时强时弱" + else: + state = JagratAvastha.DEEP_SLEEP + meaning = "深睡状态:行星不活跃,难以发挥作用,影响微弱" + + return { + "state": state.value, + "house": house, + "meaning": meaning + } + + def _calculate_deeptadi_avastha(self, planet: str, sign: str, degree: float, + is_combust: bool, aspects: List[str] = None) -> Dict: + """计算Deeptadi Avastha(情绪状态)""" + aspects = aspects or [] + + # 检查入庙/落陷 + if self._is_exalted(planet, sign, degree): + state = DeeptadiAvastha.DEEPTA + meaning = "光辉状态:行星处于最佳位置,能量充沛,带来积极结果" + elif self._is_debilitated(planet, sign, degree): + state = DeeptadiAvastha.VIKALA + meaning = "残缺状态:行星处于最弱位置,能量受损,带来挑战" + elif is_combust: + state = DeeptadiAvastha.KHALA + meaning = "恶意状态:行星被太阳燃烧,能量被压制,难以正常发挥" + elif self._is_own_sign(planet, sign): + state = DeeptadiAvastha.SWASTHA + meaning = "舒适状态:行星在自己的星座,感觉自在,能够稳定发挥" + elif self._is_friend_sign(planet, sign): + state = DeeptadiAvastha.MUDITA + meaning = "快乐状态:行星在友好星座,得到支持,能够良好发挥" + elif self._is_enemy_sign(planet, sign): + state = DeeptadiAvastha.DINA + meaning = "沮丧状态:行星在敌对星座,受到压制,发挥受限" + else: + state = DeeptadiAvastha.SHANTA + meaning = "平静状态:行星在中性星座,不强不弱,平稳发挥" + + # 检查相位影响 + aspect_effects = [] + if "Jupiter" in aspects: + aspect_effects.append("木星相位:增加乐观和扩展性") + if "Mars" in aspects: + aspect_effects.append("火星相位:增加激情和冲动性") + if "Saturn" in aspects: + aspect_effects.append("土星相位:增加限制和责任感") + if "Mercury" in aspects: + aspect_effects.append("水星相位:增加智慧和沟通能力") + + return { + "state": state.value, + "meaning": meaning, + "aspect_effects": aspect_effects + } + + def _calculate_lajjitadi_avastha(self, planet: str, sign: str, house: int, + conjunctions: List[str] = None) -> Dict: + """计算Lajjitadi Avastha(羞耻状态)""" + conjunctions = conjunctions or [] + + # 简化规则 + if self._is_exalted(planet, sign, 15): # 简化判断 + state = LajjitadiAvastha.GARVITA + meaning = "骄傲状态:行星入庙,充满自信,能够展现最佳特质" + elif house in [6, 8, 12]: + state = LajjitadiAvastha.KSHUDITA + meaning = "饥饿状态:行星在困难宫位,渴望满足,但难以获得" + elif sign in self.FIRE_SIGNS: + state = LajjitadiAvastha.TRUSHITA + meaning = "口渴状态:行星在火象星座,能量过热,需要冷却" + elif "Mars" in conjunctions: + state = LajjitadiAvastha.KSHOBHITA + meaning = "激动状态:与火星合相,能量激烈,容易冲动" + elif any(self._is_enemy_planet(planet, conj) for conj in conjunctions): + state = LajjitadiAvastha.LAJJITA + meaning = "羞耻状态:与敌对行星同宫,感到不适,发挥受限" + else: + state = LajjitadiAvastha.MUDITA + meaning = "快乐状态:与友好行星同宫,感到愉悦,能够良好发挥" + + return { + "state": state.value, + "meaning": meaning, + "conjunctions": conjunctions + } + + def _calculate_shayanadi_avastha(self, planet: str, sign: str) -> Dict: + """计算Shayanadi Avastha(姿态状态)""" + # 根据星座元素和类型判断 + if sign in self.WATER_SIGNS: + state = ShayanadiAvastha.SHAYANA + meaning = "躺卧姿态:行星在水象星座,处于休息状态,被动接受" + elif sign in self.EARTH_SIGNS: + state = ShayanadiAvastha.UPAVESHANA + meaning = "坐着姿态:行星在土象星座,稳定扎根,缓慢行动" + elif sign in self.FIRE_SIGNS: + state = ShayanadiAvastha.NETRAPANI + meaning = "持武器姿态:行星在火象星座,充满战斗力,主动出击" + elif sign in self.AIR_SIGNS: + state = ShayanadiAvastha.PRAKASHANA + meaning = "显现姿态:行星在风象星座,灵活多变,善于表达" + else: + state = ShayanadiAvastha.GAMANA + meaning = "行走姿态:行星处于移动状态,不断变化" + + # 根据行星主宰星座判断特殊状态 + for planet_name, signs in self.PLANET_SIGNS.items(): + if sign in signs: + if planet_name == "Mercury": + state = ShayanadiAvastha.AGAMA + meaning = "学习姿态:在水星星座,专注于学习和沟通" + elif planet_name == "Venus": + state = ShayanadiAvastha.BHOJANA + meaning = "进食姿态:在金星星座,享受物质和感官愉悦" + elif planet_name == "Moon": + state = ShayanadiAvastha.NRITYALIPSA + meaning = "舞蹈姿态:在月亮星座,情感丰富,富有表现力" + elif planet_name == "Jupiter": + state = ShayanadiAvastha.KAUTUKA + meaning = "好奇姿态:在木星星座,渴望探索和扩展" + elif planet_name == "Saturn": + state = ShayanadiAvastha.NIDRA + meaning = "睡眠姿态:在土星星座,能量收缩,需要休息" + break + + return { + "state": state.value, + "sign": sign, + "meaning": meaning + } + + def _is_exalted(self, planet: str, sign: str, degree: float) -> bool: + """检查是否入庙""" + if planet in self.EXALTATION: + exalt_sign, exalt_degree = self.EXALTATION[planet] + return sign == exalt_sign and abs(degree - exalt_degree) < 5 + return False + + def _is_debilitated(self, planet: str, sign: str, degree: float) -> bool: + """检查是否落陷""" + if planet in self.DEBILITATION: + debil_sign, debil_degree = self.DEBILITATION[planet] + return sign == debil_sign and abs(degree - debil_degree) < 5 + return False + + def _is_own_sign(self, planet: str, sign: str) -> bool: + """检查是否在自己的星座""" + return sign in self.PLANET_SIGNS.get(planet, []) + + def _is_friend_sign(self, planet: str, sign: str) -> bool: + """检查是否在友好星座(简化版)""" + # 这里需要完整的行星友好关系表,暂时简化 + return False + + def _is_enemy_sign(self, planet: str, sign: str) -> bool: + """检查是否在敌对星座(简化版)""" + # 这里需要完整的行星敌对关系表,暂时简化 + return False + + def _is_enemy_planet(self, planet1: str, planet2: str) -> bool: + """检查两个行星是否敌对(简化版)""" + # 这里需要完整的行星关系表,暂时简化 + enemies = { + "Sun": ["Saturn", "Venus"], + "Moon": ["Rahu", "Ketu"], + "Mars": ["Mercury"], + "Mercury": ["Moon"], + "Jupiter": ["Mercury", "Venus"], + "Venus": ["Sun", "Moon"], + "Saturn": ["Sun", "Moon", "Mars"] + } + return planet2 in enemies.get(planet1, []) + + def _generate_interpretation(self, avasthas: Dict) -> str: + """生成综合解读""" + interpretation = "行星状态综合分析:\n\n" + + # Bala Avastha + bala = avasthas["Bala"] + interpretation += f"1. 年龄状态:{bala['state']}({bala['degree_range']})\n" + interpretation += f" {bala['meaning']}\n\n" + + # Jagrat Avastha + jagrat = avasthas["Jagrat"] + interpretation += f"2. 警觉状态:{jagrat['state']}(第{jagrat['house']}宫)\n" + interpretation += f" {jagrat['meaning']}\n\n" + + # Deeptadi Avastha + deeptadi = avasthas["Deeptadi"] + interpretation += f"3. 情绪状态:{deeptadi['state']}\n" + interpretation += f" {deeptadi['meaning']}\n" + if deeptadi['aspect_effects']: + interpretation += " 相位影响:\n" + for effect in deeptadi['aspect_effects']: + interpretation += f" - {effect}\n" + interpretation += "\n" + + # Lajjitadi Avastha + lajjitadi = avasthas["Lajjitadi"] + interpretation += f"4. 社会状态:{lajjitadi['state']}\n" + interpretation += f" {lajjitadi['meaning']}\n\n" + + # Shayanadi Avastha + shayanadi = avasthas["Shayanadi"] + interpretation += f"5. 行为模式:{shayanadi['state']}({shayanadi['sign']})\n" + interpretation += f" {shayanadi['meaning']}\n" + + return interpretation + + def _generate_remedies(self, planet: str, avasthas: Dict) -> List[str]: + """生成补救建议""" + remedies = [] + + # 根据Bala Avastha + bala_strength = avasthas["Bala"]["strength"] + if bala_strength < 0.5: + remedies.append(f"行星处于弱势年龄阶段,建议佩戴{planet}对应的宝石") + remedies.append(f"在{planet}主管的日子进行布施和祈祷") + + # 根据Jagrat Avastha + if avasthas["Jagrat"]["state"] == "Deep Sleep": + remedies.append("行星处于深睡状态,建议通过冥想和咒语激活其能量") + + # 根据Deeptadi Avastha + deeptadi_state = avasthas["Deeptadi"]["state"] + if deeptadi_state in ["Vikala", "Khala", "Dina"]: + remedies.append(f"行星处于{deeptadi_state}状态,需要特别补救") + remedies.append(f"念诵{planet}的Beeja Mantra(种子咒)") + + return remedies + + +# 示例用法 +if __name__ == "__main__": + calculator = AvasthaCalculator() + + # 示例:太阳在白羊座15度,第10宫 + result = calculator.calculate_all_avasthas( + planet="Sun", + sign="Aries", + degree=15.0, + house=10, + conjunctions=["Mercury"], + aspects=["Jupiter", "Saturn"], + is_combust=False, + is_retrograde=False + ) + + print("="*60) + print(f"{result['planet']} 在 {result['sign']} {result['degree']}° (第{result['house']}宫)") + print("="*60) + print(result['interpretation']) + + if result['remedies']: + print("\n补救建议:") + for i, remedy in enumerate(result['remedies'], 1): + print(f"{i}. {remedy}") diff --git a/divisional_charts_extended.py b/divisional_charts_extended.py new file mode 100644 index 00000000..4723c8c7 --- /dev/null +++ b/divisional_charts_extended.py @@ -0,0 +1,534 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Divisional Charts Extended - D2-D60完整分盘宫位图计算器 +印度占星 Shodasavarga(16分盘)+ 扩展分盘系统 + +核心功能: +- 计算D1-D60所有分盘的行星位置 +- 生成每个分盘的12宫位行星分布图 +- 支持BPHS标准算法 +- 提供分盘上升点计算 +- 输出可视化宫位图数据 + +参考文献: +- Brihat Parashara Hora Shastra (BPHS) Chapter 6 +- Phaladeepika by Mantreswara +- Jataka Parijata by Vaidyanatha Dikshita +""" + +from typing import Dict, List, Tuple +from enum import Enum + +class VargaType(Enum): + """分盘类型枚举""" + D1 = (1, "Rashi", "本命盘") + D2 = (2, "Hora", "财富") + D3 = (3, "Drekkana", "兄弟姐妹") + D4 = (4, "Chaturthamsa", "财产/运气") + D5 = (5, "Panchamsa", "名声/权力") + D6 = (6, "Shashthamsa", "健康/敌人") + D7 = (7, "Saptamsa", "子女") + D8 = (8, "Ashtamsa", "突发事件") + D9 = (9, "Navamsa", "配偶/灵性") + D10 = (10, "Dasamsa", "事业") + D11 = (11, "Rudramsa", "破坏/转化") + D12 = (12, "Dwadasamsa", "父母") + D16 = (16, "Shodasamsa", "交通工具/舒适") + D20 = (20, "Vimsamsa", "灵性修行") + D24 = (24, "Chaturvimsamsa", "教育/学习") + D27 = (27, "Bhamsa", "力量/弱点") + D30 = (30, "Trimsamsa", "不幸/困难") + D40 = (40, "Khavedamsa", "吉凶效果") + D45 = (45, "Akshavedamsa", "全面判断") + D60 = (60, "Shashtiamsa", "前世业力") + + def __init__(self, division: int, name: str, meaning: str): + self.division = division + self.varga_name = name + self.meaning = meaning + +class DivisionalChartsCalculator: + """分盘计算器""" + + SIGNS = ["Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", + "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"] + + # 星座分类 + MOVABLE_SIGNS = [0, 3, 6, 9] # Aries, Cancer, Libra, Capricorn + FIXED_SIGNS = [1, 4, 7, 10] # Taurus, Leo, Scorpio, Aquarius + DUAL_SIGNS = [2, 5, 8, 11] # Gemini, Virgo, Sagittarius, Pisces + + ODD_SIGNS = [0, 2, 4, 6, 8, 10] # 奇数星座 + EVEN_SIGNS = [1, 3, 5, 7, 9, 11] # 偶数星座 + + def __init__(self): + pass + + def calculate_all_vargas(self, planet_positions: Dict[str, float], + asc_degree: float) -> Dict[str, Dict]: + """ + 计算所有分盘的行星位置 + + Args: + planet_positions: {行星名: 黄道度数(0-360)} + asc_degree: 上升点黄道度数(0-360) + + Returns: + {分盘名: { + "planets": {行星名: {"sign": 星座, "degree": 度数, "house": 宫位}}, + "ascendant": {"sign": 星座, "degree": 度数}, + "house_chart": [宫位1的行星列表, 宫位2的行星列表, ...] + }} + """ + results = {} + + # 计算所有分盘 + for varga_type in VargaType: + varga_result = self._calculate_single_varga( + varga_type, planet_positions, asc_degree + ) + results[varga_type.varga_name] = varga_result + + return results + + def _calculate_single_varga(self, varga_type: VargaType, + planet_positions: Dict[str, float], + asc_degree: float) -> Dict: + """计算单个分盘""" + division = varga_type.division + + # 计算分盘上升点 + varga_asc = self._calculate_varga_position(asc_degree, division) + varga_asc_sign = int(varga_asc // 30) + varga_asc_degree = varga_asc % 30 + + # 计算所有行星的分盘位置 + varga_planets = {} + for planet, degree in planet_positions.items(): + varga_pos = self._calculate_varga_position(degree, division) + varga_sign = int(varga_pos // 30) + varga_degree = varga_pos % 30 + + # 计算宫位(从上升点开始) + house = ((varga_sign - varga_asc_sign) % 12) + 1 + + varga_planets[planet] = { + "sign": self.SIGNS[varga_sign], + "sign_index": varga_sign, + "degree": round(varga_degree, 4), + "house": house, + "absolute_degree": round(varga_pos, 4) + } + + # 生成宫位图(12个宫位,每个宫位包含的行星列表) + house_chart = [[] for _ in range(12)] + for planet, data in varga_planets.items(): + house_chart[data["house"] - 1].append(planet) + + return { + "division": division, + "name": varga_type.varga_name, + "meaning": varga_type.meaning, + "ascendant": { + "sign": self.SIGNS[varga_asc_sign], + "sign_index": varga_asc_sign, + "degree": round(varga_asc_degree, 4) + }, + "planets": varga_planets, + "house_chart": house_chart + } + + def _calculate_varga_position(self, degree: float, division: int) -> float: + """ + 计算分盘位置(BPHS标准算法) + + Args: + degree: 黄道度数(0-360) + division: 分盘数(2-60) + + Returns: + 分盘中的黄道度数(0-360) + """ + # 获取星座索引和星座内度数 + sign_index = int(degree // 30) + sign_degree = degree % 30 + + # 根据不同分盘使用不同算法 + if division == 2: + return self._calculate_d2(sign_index, sign_degree) + elif division == 3: + return self._calculate_d3(sign_index, sign_degree) + elif division == 4: + return self._calculate_d4(sign_index, sign_degree) + elif division == 5: + return self._calculate_d5(sign_index, sign_degree) + elif division == 6: + return self._calculate_d6(sign_index, sign_degree) + elif division == 7: + return self._calculate_d7(sign_index, sign_degree) + elif division == 8: + return self._calculate_d8(sign_index, sign_degree) + elif division == 9: + return self._calculate_d9(sign_index, sign_degree) + elif division == 10: + return self._calculate_d10(sign_index, sign_degree) + elif division == 11: + return self._calculate_d11(sign_index, sign_degree) + elif division == 12: + return self._calculate_d12(sign_index, sign_degree) + elif division == 16: + return self._calculate_d16(sign_index, sign_degree) + elif division == 20: + return self._calculate_d20(sign_index, sign_degree) + elif division == 24: + return self._calculate_d24(sign_index, sign_degree) + elif division == 27: + return self._calculate_d27(sign_index, sign_degree) + elif division == 30: + return self._calculate_d30(sign_index, sign_degree) + elif division == 40: + return self._calculate_d40(sign_index, sign_degree) + elif division == 45: + return self._calculate_d45(sign_index, sign_degree) + elif division == 60: + return self._calculate_d60(sign_index, sign_degree) + else: + # 通用算法(适用于其他分盘) + return self._calculate_generic_varga(sign_index, sign_degree, division) + + def _calculate_d2(self, sign_index: int, sign_degree: float) -> float: + """D2 Hora - 财富分盘""" + # 奇数星座:0-15度→Leo,15-30度→Cancer + # 偶数星座:0-15度→Cancer,15-30度→Leo + if sign_index in self.ODD_SIGNS: + if sign_degree < 15: + return 4 * 30 + sign_degree * 2 # Leo + else: + return 3 * 30 + (sign_degree - 15) * 2 # Cancer + else: + if sign_degree < 15: + return 3 * 30 + sign_degree * 2 # Cancer + else: + return 4 * 30 + (sign_degree - 15) * 2 # Leo + + def _calculate_d3(self, sign_index: int, sign_degree: float) -> float: + """D3 Drekkana - 兄弟姐妹分盘""" + # 每个星座分为3个10度区间 + # 第1个10度→本星座,第2个10度→第5个星座,第3个10度→第9个星座 + drekkana = int(sign_degree // 10) + offset = [0, 4, 8][drekkana] + varga_sign = (sign_index + offset) % 12 + varga_degree = (sign_degree % 10) * 3 + return varga_sign * 30 + varga_degree + + def _calculate_d4(self, sign_index: int, sign_degree: float) -> float: + """D4 Chaturthamsa - 财产/运气分盘""" + # 每个星座分为4个7.5度区间 + part = int(sign_degree // 7.5) + varga_sign = (sign_index + part * 3) % 12 + varga_degree = (sign_degree % 7.5) * 4 + return varga_sign * 30 + varga_degree + + def _calculate_d7(self, sign_index: int, sign_degree: float) -> float: + """D7 Saptamsa - 子女分盘""" + # 每个星座分为7个约4.286度区间 + part = int(sign_degree // (30/7)) + if sign_index in self.ODD_SIGNS: + varga_sign = (sign_index + part) % 12 + else: + varga_sign = (sign_index + 6 + part) % 12 + varga_degree = (sign_degree % (30/7)) * 7 + return varga_sign * 30 + varga_degree + + def _calculate_d9(self, sign_index: int, sign_degree: float) -> float: + """D9 Navamsa - 配偶/灵性分盘(最重要的分盘)""" + # 每个星座分为9个3.333度区间 + part = int(sign_degree // (30/9)) + + # 根据星座类型确定起始点 + if sign_index in self.MOVABLE_SIGNS: + start = sign_index # 从本星座开始 + elif sign_index in self.FIXED_SIGNS: + start = (sign_index + 8) % 12 # 从第9个星座开始 + else: # DUAL_SIGNS + start = (sign_index + 4) % 12 # 从第5个星座开始 + + varga_sign = (start + part) % 12 + varga_degree = (sign_degree % (30/9)) * 9 + return varga_sign * 30 + varga_degree + + def _calculate_d10(self, sign_index: int, sign_degree: float) -> float: + """D10 Dasamsa - 事业分盘""" + # 每个星座分为10个3度区间 + part = int(sign_degree // 3) + if sign_index in self.ODD_SIGNS: + varga_sign = (sign_index + part) % 12 + else: + varga_sign = (sign_index + 8 + part) % 12 + varga_degree = (sign_degree % 3) * 10 + return varga_sign * 30 + varga_degree + + def _calculate_d12(self, sign_index: int, sign_degree: float) -> float: + """D12 Dwadasamsa - 父母分盘""" + # 每个星座分为12个2.5度区间 + part = int(sign_degree // 2.5) + varga_sign = (sign_index + part) % 12 + varga_degree = (sign_degree % 2.5) * 12 + return varga_sign * 30 + varga_degree + + def _calculate_d16(self, sign_index: int, sign_degree: float) -> float: + """D16 Shodasamsa - 交通工具/舒适分盘""" + # 每个星座分为16个1.875度区间 + part = int(sign_degree // 1.875) + if sign_index in self.MOVABLE_SIGNS: + start = sign_index + elif sign_index in self.FIXED_SIGNS: + start = (sign_index + 4) % 12 + else: + start = (sign_index + 8) % 12 + varga_sign = (start + part) % 12 + varga_degree = (sign_degree % 1.875) * 16 + return varga_sign * 30 + varga_degree + + def _calculate_d20(self, sign_index: int, sign_degree: float) -> float: + """D20 Vimsamsa - 灵性修行分盘""" + # 每个星座分为20个1.5度区间 + part = int(sign_degree // 1.5) + if sign_index in self.MOVABLE_SIGNS: + start = sign_index + elif sign_index in self.FIXED_SIGNS: + start = (sign_index + 8) % 12 + else: + start = (sign_index + 4) % 12 + varga_sign = (start + part) % 12 + varga_degree = (sign_degree % 1.5) * 20 + return varga_sign * 30 + varga_degree + + def _calculate_d24(self, sign_index: int, sign_degree: float) -> float: + """D24 Chaturvimsamsa - 教育/学习分盘""" + # 每个星座分为24个1.25度区间 + part = int(sign_degree // 1.25) + if sign_index in self.ODD_SIGNS: + varga_sign = (4 + part) % 12 # 从Leo开始 + else: + varga_sign = (3 + part) % 12 # 从Cancer开始 + varga_degree = (sign_degree % 1.25) * 24 + return varga_sign * 30 + varga_degree + + def _calculate_d27(self, sign_index: int, sign_degree: float) -> float: + """D27 Bhamsa - 力量/弱点分盘""" + # 每个星座分为27个1.111度区间 + part = int(sign_degree // (30/27)) + if sign_index in self.ODD_SIGNS: + start = sign_index + else: + start = (sign_index + 8) % 12 + varga_sign = (start + part) % 12 + varga_degree = (sign_degree % (30/27)) * 27 + return varga_sign * 30 + varga_degree + + def _calculate_d30(self, sign_index: int, sign_degree: float) -> float: + """D30 Trimsamsa - 不幸/困难分盘(特殊算法)""" + # D30使用特殊的不等分算法 + # 奇数星座:Mars(5°), Saturn(5°), Jupiter(8°), Mercury(7°), Venus(5°) + # 偶数星座:Venus(5°), Mercury(7°), Jupiter(8°), Saturn(5°), Mars(5°) + + if sign_index in self.ODD_SIGNS: + if sign_degree < 5: + varga_sign = 0 # Aries (Mars) + varga_degree = sign_degree * 6 + elif sign_degree < 10: + varga_sign = 10 # Aquarius (Saturn) + varga_degree = (sign_degree - 5) * 6 + elif sign_degree < 18: + varga_sign = 8 # Sagittarius (Jupiter) + varga_degree = (sign_degree - 10) * 3.75 + elif sign_degree < 25: + varga_sign = 2 # Gemini (Mercury) + varga_degree = (sign_degree - 18) * 4.286 + else: + varga_sign = 1 # Taurus (Venus) + varga_degree = (sign_degree - 25) * 6 + else: + if sign_degree < 5: + varga_sign = 1 # Taurus (Venus) + varga_degree = sign_degree * 6 + elif sign_degree < 12: + varga_sign = 2 # Gemini (Mercury) + varga_degree = (sign_degree - 5) * 4.286 + elif sign_degree < 20: + varga_sign = 8 # Sagittarius (Jupiter) + varga_degree = (sign_degree - 12) * 3.75 + elif sign_degree < 25: + varga_sign = 10 # Aquarius (Saturn) + varga_degree = (sign_degree - 20) * 6 + else: + varga_sign = 0 # Aries (Mars) + varga_degree = (sign_degree - 25) * 6 + + return varga_sign * 30 + varga_degree + + def _calculate_d40(self, sign_index: int, sign_degree: float) -> float: + """D40 Khavedamsa - 吉凶效果分盘""" + # 每个星座分为40个0.75度区间 + part = int(sign_degree // 0.75) + if sign_index in self.MOVABLE_SIGNS: + start = sign_index + elif sign_index in self.FIXED_SIGNS: + start = (sign_index + 8) % 12 + else: + start = (sign_index + 4) % 12 + varga_sign = (start + part) % 12 + varga_degree = (sign_degree % 0.75) * 40 + return varga_sign * 30 + varga_degree + + def _calculate_d45(self, sign_index: int, sign_degree: float) -> float: + """D45 Akshavedamsa - 全面判断分盘""" + # 每个星座分为45个0.667度区间 + part = int(sign_degree // (30/45)) + if sign_index in self.ODD_SIGNS: + start = sign_index + else: + start = (sign_index + 8) % 12 + varga_sign = (start + part) % 12 + varga_degree = (sign_degree % (30/45)) * 45 + return varga_sign * 30 + varga_degree + + def _calculate_d60(self, sign_index: int, sign_degree: float) -> float: + """D60 Shashtiamsa - 前世业力分盘(最精细的分盘)""" + # 每个星座分为60个0.5度区间 + part = int(sign_degree // 0.5) + varga_sign = (sign_index + part) % 12 + varga_degree = (sign_degree % 0.5) * 60 + return varga_sign * 30 + varga_degree + + def _calculate_d5(self, sign_index: int, sign_degree: float) -> float: + """D5 Panchamsa - 名声/权力分盘""" + part = int(sign_degree // 6) + if sign_index in self.ODD_SIGNS: + varga_sign = (sign_index + part) % 12 + else: + varga_sign = (sign_index + 8 + part) % 12 + varga_degree = (sign_degree % 6) * 5 + return varga_sign * 30 + varga_degree + + def _calculate_d6(self, sign_index: int, sign_degree: float) -> float: + """D6 Shashthamsa - 健康/敌人分盘""" + part = int(sign_degree // 5) + if sign_index in self.ODD_SIGNS: + varga_sign = (sign_index + part) % 12 + else: + varga_sign = (sign_index + 6 + part) % 12 + varga_degree = (sign_degree % 5) * 6 + return varga_sign * 30 + varga_degree + + def _calculate_d8(self, sign_index: int, sign_degree: float) -> float: + """D8 Ashtamsa - 突发事件分盘""" + part = int(sign_degree // 3.75) + if sign_index in self.ODD_SIGNS: + varga_sign = (sign_index + part) % 12 + else: + varga_sign = (sign_index + 8 + part) % 12 + varga_degree = (sign_degree % 3.75) * 8 + return varga_sign * 30 + varga_degree + + def _calculate_d11(self, sign_index: int, sign_degree: float) -> float: + """D11 Rudramsa - 破坏/转化分盘""" + part = int(sign_degree // (30/11)) + if sign_index in self.ODD_SIGNS: + varga_sign = (sign_index + part) % 12 + else: + varga_sign = (sign_index + 8 + part) % 12 + varga_degree = (sign_degree % (30/11)) * 11 + return varga_sign * 30 + varga_degree + + def _calculate_generic_varga(self, sign_index: int, sign_degree: float, division: int) -> float: + """通用分盘算法(适用于其他分盘)""" + part = int(sign_degree // (30/division)) + varga_sign = (sign_index + part) % 12 + varga_degree = (sign_degree % (30/division)) * division + return varga_sign * 30 + varga_degree + + def generate_house_chart_ascii(self, house_chart: List[List[str]]) -> str: + """ + 生成ASCII格式的宫位图 + + Args: + house_chart: 12个宫位的行星列表 + + Returns: + ASCII格式的宫位图字符串 + """ + # 北印度风格宫位图(菱形) + chart = f""" + ┌─────────┬─────────┬─────────┐ + │ 12 │ 1 │ 2 │ + │ {self._format_planets(house_chart[11]):7} │ {self._format_planets(house_chart[0]):7} │ {self._format_planets(house_chart[1]):7} │ + ├─────────┼─────────┼─────────┤ + │ 11 │ │ 3 │ + │ {self._format_planets(house_chart[10]):7} │ ASC │ {self._format_planets(house_chart[2]):7} │ + ├─────────┼─────────┼─────────┤ + │ 10 │ 9 │ 4 │ + │ {self._format_planets(house_chart[9]):7} │ {self._format_planets(house_chart[8]):7} │ {self._format_planets(house_chart[3]):7} │ + ├─────────┼─────────┼─────────┤ + │ 9 │ 8 │ 5 │ + │ {self._format_planets(house_chart[8]):7} │ {self._format_planets(house_chart[7]):7} │ {self._format_planets(house_chart[4]):7} │ + ├─────────┼─────────┼─────────┤ + │ 8 │ 7 │ 6 │ + │ {self._format_planets(house_chart[7]):7} │ {self._format_planets(house_chart[6]):7} │ {self._format_planets(house_chart[5]):7} │ + └─────────┴─────────┴─────────┘ + """ + return chart + + def _format_planets(self, planets: List[str]) -> str: + """格式化行星列表为简写""" + if not planets: + return " " + + # 行星简写 + abbrev = { + "Sun": "Su", "Moon": "Mo", "Mars": "Ma", "Mercury": "Me", + "Jupiter": "Ju", "Venus": "Ve", "Saturn": "Sa", + "Rahu": "Ra", "Ketu": "Ke" + } + + short = [abbrev.get(p, p[:2]) for p in planets] + return " ".join(short)[:7].ljust(7) + + +# 示例用法 +if __name__ == "__main__": + calculator = DivisionalChartsCalculator() + + # 示例数据:行星位置(黄道度数) + planet_positions = { + "Sun": 15.5, # Aries 15.5° + "Moon": 125.3, # Leo 5.3° + "Mars": 285.7, # Capricorn 15.7° + "Mercury": 25.2, # Aries 25.2° + "Jupiter": 95.8, # Cancer 5.8° + "Venus": 335.4, # Pisces 5.4° + "Saturn": 245.6, # Sagittarius 5.6° + "Rahu": 185.9, # Libra 5.9° + "Ketu": 5.9 # Aries 5.9° + } + + asc_degree = 10.0 # Aries 10° + + # 计算所有分盘 + all_vargas = calculator.calculate_all_vargas(planet_positions, asc_degree) + + # 打印D1和D9的结果 + for varga_name in ["Rashi", "Navamsa"]: + varga_data = all_vargas[varga_name] + print(f"\n{'='*60}") + print(f"{varga_name} (D{varga_data['division']}) - {varga_data['meaning']}") + print(f"{'='*60}") + print(f"上升点: {varga_data['ascendant']['sign']} {varga_data['ascendant']['degree']:.2f}°") + print(f"\n行星位置:") + for planet, data in varga_data['planets'].items(): + print(f" {planet:10} → {data['sign']:12} {data['degree']:6.2f}° (第{data['house']}宫)") + + print(f"\n宫位图:") + print(calculator.generate_house_chart_ascii(varga_data['house_chart'])) diff --git a/karaka_calculator.py b/karaka_calculator.py new file mode 100644 index 00000000..b19be884 --- /dev/null +++ b/karaka_calculator.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Karaka Calculator - Jaimini Chara Karaka System +印度占星 Karaka(象征星)计算器 + +支持两种模式: +1. BPHS标准模式(8-Karaka):Sun > Moon > Mars > Mercury > Jupiter > Venus > Saturn > Rahu +2. Jagannatha Hora兼容模式(7-Karaka + Rahu限制):Rahu只能是Matrukaraka(MK) + +核心功能: +- 计算7大Chara Karaka(可变象征星) +- 支持8-Karaka系统(包含Rahu) +- 自动识别Karaka模式 +- 提供详细的度数排序和Karaka分配 +""" + +import sys +from typing import Dict, List, Tuple, Optional +from enum import Enum + +class KarakaMode(Enum): + """Karaka计算模式""" + BPHS_8_KARAKA = "bphs" # 标准BPHS 8-Karaka系统 + JH_COMPATIBLE = "jh" # Jagannatha Hora兼容模式(Rahu限制在MK) + BPHS_7_KARAKA = "bphs7" # 标准BPHS 7-Karaka系统(不含Rahu) + +class KarakaType(Enum): + """7大Chara Karaka类型""" + ATMAKARAKA = "AK" # 灵魂象征星(最高度数) + AMATYAKARAKA = "AmK" # 事业象征星(第二高) + BHRATRUKARAKA = "BK" # 兄弟象征星(第三高) + MATRUKARAKA = "MK" # 母亲象征星(第四高) + PUTRAKARAKA = "PK" # 子女象征星(第五高) + GNATIKARAKA = "GK" # 敌人/疾病象征星(第六高) + DARAKARAKA = "DK" # 配偶象征星(最低度数) + EXTRA_KARAKA = "XK" # 额外象征星(仅在8-Karaka系统中) + +class KarakaCalculator: + """Karaka计算器""" + + SEVEN_PLANETS = ["Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn"] + EIGHT_PLANETS = ["Sun", "Moon", "Mars", "Mercury", "Jupiter", "Venus", "Saturn", "Rahu"] + + def __init__(self, mode: KarakaMode = KarakaMode.BPHS_8_KARAKA): + self.mode = mode + + def calculate_karaka(self, planet_positions: Dict[str, float]) -> Dict[str, any]: + """ + 计算Chara Karaka + + Args: + planet_positions: 行星位置字典 {行星名: 黄道度数} + + Returns: + Karaka分配结果字典 + """ + result = { + "mode": self.mode.value, + "karakas": {}, + "sorted_planets": [], + "warnings": [] + } + + # 1. 提取有效行星 + valid_planets = self._extract_valid_planets(planet_positions, result) + if not valid_planets: + result["warnings"].append("No valid planets found") + return result + + # 2. 转换为星座内度数(0-30度) + sign_degrees = {p: d % 30.0 for p, d in valid_planets.items()} + + # 3. 按度数排序(降序) + sorted_planets = sorted(sign_degrees.items(), key=lambda x: x[1], reverse=True) + result["sorted_planets"] = [(p, round(d, 4)) for p, d in sorted_planets] + + # 4. 分配Karaka + result["karakas"] = self._assign_karakas(sorted_planets, result) + + # 5. 验证 + self._validate_karakas(result) + + return result + + def _extract_valid_planets(self, positions: Dict[str, float], result: Dict) -> Dict[str, float]: + """提取有效行星""" + valid = {} + planets = self.SEVEN_PLANETS if self.mode == KarakaMode.BPHS_7_KARAKA else self.EIGHT_PLANETS + + for planet in planets: + if planet in positions: + valid[planet] = positions[planet] + else: + result["warnings"].append(f"Missing planet: {planet}") + + return valid + + def _assign_karakas(self, sorted_planets: List[Tuple[str, float]], result: Dict) -> Dict: + """分配Karaka""" + karakas = {} + + if self.mode == KarakaMode.JH_COMPATIBLE: + # JH模式:强制Rahu为MK + rahu_idx = next((i for i, (p, _) in enumerate(sorted_planets) if p == "Rahu"), None) + if rahu_idx is not None and rahu_idx != 3: + result["warnings"].append(f"JH Mode: Rahu forced to MK (was rank {rahu_idx + 1})") + adjusted = [p for p in sorted_planets if p[0] != "Rahu"] + adjusted.insert(3, sorted_planets[rahu_idx]) + sorted_planets = adjusted + + # 分配Karaka + karaka_types = [ + ("AK", "灵魂象征星"), + ("AmK", "事业象征星"), + ("BK", "兄弟象征星"), + ("MK", "母亲象征星"), + ("PK", "子女象征星"), + ("GK", "敌人/疾病象征星"), + ] + + if self.mode == KarakaMode.BPHS_8_KARAKA: + karaka_types.append(("XK", "额外象征星")) + + karaka_types.append(("DK", "配偶象征星")) + + for i, (planet, degree) in enumerate(sorted_planets[:len(karaka_types)]): + code, name = karaka_types[i] + karakas[code] = { + "planet": planet, + "sign_degree": round(degree, 4), + "name": name, + "rank": i + 1 + } + + return karakas + + def _validate_karakas(self, result: Dict): + """验证Karaka分配""" + expected = 7 if self.mode != KarakaMode.BPHS_8_KARAKA else 8 + if len(result["karakas"]) != expected: + result["warnings"].append(f"Expected {expected} Karakas, got {len(result['karakas'])}") + + def format_output(self, result: Dict) -> str: + """格式化输出""" + lines = ["=" * 60, "Chara Karaka Calculation", "=" * 60] + lines.append(f"Mode: {result['mode'].upper()}\n") + + lines.append("Karaka Assignment:") + for code, data in result['karakas'].items(): + lines.append(f" {code:4s} = {data['planet']:10s} ({data['sign_degree']:6.2f}°) - {data['name']}") + + if result['warnings']: + lines.append("\nWarnings:") + for w in result['warnings']: + lines.append(f" ⚠️ {w}") + + lines.append("=" * 60) + return "\n".join(lines) + + +def main(): + """命令行接口""" + import argparse + + parser = argparse.ArgumentParser(description="Calculate Jaimini Chara Karaka") + parser.add_argument("--mode", choices=["bphs", "jh", "bphs7"], default="bphs") + parser.add_argument("--planets", type=str, help="Format: Sun:45.5,Moon:120.3,...") + parser.add_argument("--json", action="store_true") + + args = parser.parse_args() + + # 解析行星位置 + if args.planets: + positions = {} + for pair in args.planets.split(","): + planet, degree = pair.split(":") + positions[planet.strip()] = float(degree.strip()) + else: + # 示例数据 + positions = { + "Sun": 45.5, "Moon": 120.3, "Mars": 200.1, + "Mercury": 50.8, "Jupiter": 180.5, "Venus": 90.2, + "Saturn": 250.7, "Rahu": 150.4 + } + print("Using example data\n") + + # 计算 + mode_map = {"bphs": KarakaMode.BPHS_8_KARAKA, "jh": KarakaMode.JH_COMPATIBLE, "bphs7": KarakaMode.BPHS_7_KARAKA} + calc = KarakaCalculator(mode=mode_map[args.mode]) + result = calc.calculate_karaka(positions) + + # 输出 + if args.json: + import json + print(json.dumps(result, indent=2, ensure_ascii=False)) + else: + print(calc.format_output(result)) + + +if __name__ == "__main__": + main() diff --git a/special_lagnas.py b/special_lagnas.py new file mode 100644 index 00000000..d2afa598 --- /dev/null +++ b/special_lagnas.py @@ -0,0 +1,315 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Special Lagnas Calculator - 特殊上升点计算器 +印度占星特殊上升点(Bhava/Hora/Ghati/Arudha/Upapada Lagna) + +核心功能: +- Bhava Lagna(宫位上升):反映物质层面的实际状况 +- Hora Lagna(时辰上升):财富和物质收益的指示器 +- Ghati Lagna(Ghati上升):基于Ghati单位的精确上升点 +- Arudha Lagna(映像上升):公众形象和社会地位 +- Upapada Lagna(配偶映像上升):配偶和婚姻的公众形象 +""" + +from typing import Dict, Tuple +from datetime import datetime, timedelta + +class SpecialLagnasCalculator: + """特殊上升点计算器""" + + SIGNS = ["Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", + "Libra", "Scorpio", "Sagittarius", "Capricorn", "Aquarius", "Pisces"] + + def __init__(self): + pass + + def calculate_all_lagnas(self, asc_degree: float, sun_degree: float, + moon_degree: float, birth_time: datetime, + sunrise_time: datetime) -> Dict[str, Dict]: + """ + 计算所有特殊上升点 + + Args: + asc_degree: 上升点度数(0-360) + sun_degree: 太阳度数(0-360) + moon_degree: 月亮度数(0-360) + birth_time: 出生时间 + sunrise_time: 当天日出时间 + + Returns: + 所有特殊上升点的字典 + """ + result = {} + + # 1. Bhava Lagna + result["Bhava_Lagna"] = self.calculate_bhava_lagna(asc_degree, sun_degree, moon_degree) + + # 2. Hora Lagna + result["Hora_Lagna"] = self.calculate_hora_lagna(asc_degree, sun_degree, birth_time, sunrise_time) + + # 3. Ghati Lagna + result["Ghati_Lagna"] = self.calculate_ghati_lagna(asc_degree, birth_time, sunrise_time) + + # 4. Arudha Lagna (需要1宫主星位置) + # 注意:这里需要额外的行星位置信息,暂时返回占位符 + result["Arudha_Lagna"] = {"note": "Requires 1st house lord position"} + + # 5. Upapada Lagna (需要12宫主星位置) + result["Upapada_Lagna"] = {"note": "Requires 12th house lord position"} + + return result + + def calculate_bhava_lagna(self, asc_degree: float, sun_degree: float, + moon_degree: float) -> Dict: + """ + 计算Bhava Lagna(宫位上升) + + 公式:Bhava Lagna = Asc + (Sun - Moon) + + 含义: + - 反映物质层面的实际状况 + - 显示真实的生活环境和物质条件 + - 与上升点的差异揭示表象与实质的差距 + """ + # 计算太阳-月亮的度数差 + sun_moon_diff = sun_degree - moon_degree + + # 如果差值为负,加360度 + if sun_moon_diff < 0: + sun_moon_diff += 360 + + # 计算Bhava Lagna + bhava_lagna = (asc_degree + sun_moon_diff) % 360 + + # 转换为星座和度数 + sign_index = int(bhava_lagna // 30) + sign_degree = bhava_lagna % 30 + + return { + "degree": round(bhava_lagna, 4), + "sign": self.SIGNS[sign_index], + "sign_degree": round(sign_degree, 4), + "formula": "Asc + (Sun - Moon)", + "meaning": "物质层面的实际状况,真实的生活环境" + } + + def calculate_hora_lagna(self, asc_degree: float, sun_degree: float, + birth_time: datetime, sunrise_time: datetime) -> Dict: + """ + 计算Hora Lagna(时辰上升) + + 公式:Hora Lagna = Asc + (出生时间距日出的Hora数 × 15度) + + 含义: + - 财富和物质收益的指示器 + - 显示金钱来源和财富积累方式 + - 与2宫(财富宫)密切相关 + """ + # 计算出生时间距日出的小时数 + time_diff = birth_time - sunrise_time + hours_from_sunrise = time_diff.total_seconds() / 3600 + + # 计算Hora数(每个Hora = 1小时) + hora_count = hours_from_sunrise + + # 计算Hora Lagna(每个Hora推进15度) + hora_lagna = (asc_degree + (hora_count * 15)) % 360 + + # 转换为星座和度数 + sign_index = int(hora_lagna // 30) + sign_degree = hora_lagna % 30 + + return { + "degree": round(hora_lagna, 4), + "sign": self.SIGNS[sign_index], + "sign_degree": round(sign_degree, 4), + "hours_from_sunrise": round(hours_from_sunrise, 2), + "formula": "Asc + (Hora数 × 15°)", + "meaning": "财富和物质收益的指示器" + } + + def calculate_ghati_lagna(self, asc_degree: float, birth_time: datetime, + sunrise_time: datetime) -> Dict: + """ + 计算Ghati Lagna(Ghati上升) + + 公式:Ghati Lagna = Asc + (Ghati数 × 6度) + + Ghati单位: + - 1 Ghati = 24分钟 + - 1天 = 60 Ghati + - 每个Ghati推进6度(360度 / 60 Ghati = 6度) + + 含义: + - 基于Ghati单位的精确上升点 + - 用于精确的时间矫正和事件预测 + - 在Prashna(问事占星)中特别重要 + """ + # 计算出生时间距日出的分钟数 + time_diff = birth_time - sunrise_time + minutes_from_sunrise = time_diff.total_seconds() / 60 + + # 计算Ghati数(1 Ghati = 24分钟) + ghati_count = minutes_from_sunrise / 24 + + # 计算Ghati Lagna(每个Ghati推进6度) + ghati_lagna = (asc_degree + (ghati_count * 6)) % 360 + + # 转换为星座和度数 + sign_index = int(ghati_lagna // 30) + sign_degree = ghati_lagna % 30 + + return { + "degree": round(ghati_lagna, 4), + "sign": self.SIGNS[sign_index], + "sign_degree": round(sign_degree, 4), + "ghati_count": round(ghati_count, 2), + "formula": "Asc + (Ghati数 × 6°)", + "meaning": "基于Ghati单位的精确上升点,用于精确预测" + } + + def calculate_arudha_lagna(self, asc_degree: float, first_lord_degree: float) -> Dict: + """ + 计算Arudha Lagna(映像上升/AL) + + 公式: + 1. 计算1宫主星距离上升点的宫位数(A) + 2. 从1宫主星再数A个宫位,得到AL + 3. 特殊规则:如果AL落在1宫或7宫,则从该位置再数10个宫位 + + 含义: + - 公众形象和社会地位 + - 他人如何看待你 + - 外在表现与内在本质的差异 + """ + # 计算上升点和1宫主星的星座 + asc_sign = int(asc_degree // 30) + lord_sign = int(first_lord_degree // 30) + + # 计算1宫主星距离上升点的宫位数 + distance = (lord_sign - asc_sign) % 12 + if distance == 0: + distance = 12 + + # 从1宫主星再数相同的宫位数 + al_sign = (lord_sign + distance - 1) % 12 + + # 应用1/7宫例外规则 + if al_sign == asc_sign or al_sign == (asc_sign + 6) % 12: + al_sign = (al_sign + 9) % 12 # 再数10个宫位(索引+9) + + # 计算AL的度数(使用1宫主星的度数) + al_degree = (al_sign * 30 + (first_lord_degree % 30)) % 360 + + return { + "degree": round(al_degree, 4), + "sign": self.SIGNS[al_sign], + "sign_degree": round(al_degree % 30, 4), + "distance_from_asc": distance, + "formula": "从1宫主星数相同宫位数(1/7宫例外)", + "meaning": "公众形象和社会地位,他人如何看待你" + } + + def calculate_upapada_lagna(self, asc_degree: float, twelfth_lord_degree: float) -> Dict: + """ + 计算Upapada Lagna(配偶映像上升/UL) + + 公式: + 1. 计算12宫主星距离12宫的宫位数(A) + 2. 从12宫主星再数A个宫位,得到UL + 3. 特殊规则:如果UL落在12宫或6宫,则从该位置再数10个宫位 + + 含义: + - 配偶的公众形象 + - 婚姻在社会中的表现 + - 配偶的社会地位和声誉 + """ + # 计算12宫的起始度数 + asc_sign = int(asc_degree // 30) + twelfth_house_sign = (asc_sign + 11) % 12 + + # 计算12宫主星的星座 + lord_sign = int(twelfth_lord_degree // 30) + + # 计算12宫主星距离12宫的宫位数 + distance = (lord_sign - twelfth_house_sign) % 12 + if distance == 0: + distance = 12 + + # 从12宫主星再数相同的宫位数 + ul_sign = (lord_sign + distance - 1) % 12 + + # 应用12/6宫例外规则 + if ul_sign == twelfth_house_sign or ul_sign == (twelfth_house_sign + 6) % 12: + ul_sign = (ul_sign + 9) % 12 # 再数10个宫位 + + # 计算UL的度数 + ul_degree = (ul_sign * 30 + (twelfth_lord_degree % 30)) % 360 + + return { + "degree": round(ul_degree, 4), + "sign": self.SIGNS[ul_sign], + "sign_degree": round(ul_degree % 30, 4), + "distance_from_12th": distance, + "formula": "从12宫主星数相同宫位数(12/6宫例外)", + "meaning": "配偶的公众形象和婚姻的社会表现" + } + + def format_output(self, lagnas: Dict) -> str: + """格式化输出所有特殊上升点""" + lines = ["=" * 60, "Special Lagnas Calculation", "=" * 60, ""] + + for lagna_name, data in lagnas.items(): + lines.append(f"{lagna_name}:") + if "note" in data: + lines.append(f" {data['note']}") + else: + lines.append(f" Position: {data['sign']} {data['sign_degree']:.2f}° ({data['degree']:.2f}°)") + lines.append(f" Formula: {data['formula']}") + lines.append(f" Meaning: {data['meaning']}") + lines.append("") + + lines.append("=" * 60) + return "\n".join(lines) + + +def main(): + """命令行接口""" + import argparse + from datetime import datetime + + parser = argparse.ArgumentParser(description="Calculate Special Lagnas") + parser.add_argument("--asc", type=float, required=True, help="Ascendant degree (0-360)") + parser.add_argument("--sun", type=float, required=True, help="Sun degree (0-360)") + parser.add_argument("--moon", type=float, required=True, help="Moon degree (0-360)") + parser.add_argument("--birth-time", type=str, help="Birth time (YYYY-MM-DD HH:MM:SS)") + parser.add_argument("--sunrise-time", type=str, help="Sunrise time (YYYY-MM-DD HH:MM:SS)") + parser.add_argument("--first-lord", type=float, help="1st house lord degree (for AL)") + parser.add_argument("--twelfth-lord", type=float, help="12th house lord degree (for UL)") + + args = parser.parse_args() + + calc = SpecialLagnasCalculator() + + # 解析时间 + birth_time = datetime.strptime(args.birth_time, "%Y-%m-%d %H:%M:%S") if args.birth_time else datetime.now() + sunrise_time = datetime.strptime(args.sunrise_time, "%Y-%m-%d %H:%M:%S") if args.sunrise_time else birth_time.replace(hour=6, minute=0, second=0) + + # 计算所有特殊上升点 + lagnas = calc.calculate_all_lagnas(args.asc, args.sun, args.moon, birth_time, sunrise_time) + + # 如果提供了1宫主星位置,计算AL + if args.first_lord is not None: + lagnas["Arudha_Lagna"] = calc.calculate_arudha_lagna(args.asc, args.first_lord) + + # 如果提供了12宫主星位置,计算UL + if args.twelfth_lord is not None: + lagnas["Upapada_Lagna"] = calc.calculate_upapada_lagna(args.asc, args.twelfth_lord) + + # 输出结果 + print(calc.format_output(lagnas)) + + +if __name__ == "__main__": + main() diff --git a/vimsopaka_calculator.py b/vimsopaka_calculator.py new file mode 100644 index 00000000..39afb8eb --- /dev/null +++ b/vimsopaka_calculator.py @@ -0,0 +1,306 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Vimsopaka Bala Calculator - 分盘综合力量计算器 +印度占星 Vimsopaka Bala(20分力量)系统 + +核心功能: +- 计算16种分盘(Shodasavarga)的行星尊严 +- 根据BPHS权重系统计算Vimsopaka Bala +- 提供行星在各分盘的综合力量评分 +- 支持Dasa Varga(10分盘)和Shodasavarga(16分盘)两种模式 + +参考文献: +- Brihat Parashara Hora Shastra (BPHS) Chapter 7 +- B.V. Raman - "A Manual of Hindu Astrology" +""" + +from typing import Dict, List, Tuple +from enum import Enum + +class VargaType(Enum): + """分盘类型""" + D1 = "Rashi" # 本命盘 + D2 = "Hora" # 财富 + D3 = "Drekkana" # 兄弟姐妹 + D4 = "Chaturthamsa" # 财产/运气 + D7 = "Saptamsa" # 子女 + D9 = "Navamsa" # 配偶/灵性 + D10 = "Dasamsa" # 事业 + D12 = "Dwadasamsa" # 父母 + D16 = "Shodasamsa" # 交通工具 + D20 = "Vimsamsa" # 灵性修行 + D24 = "Chaturvimsamsa" # 教育/学习 + D27 = "Bhamsa" # 力量/弱点 + D30 = "Trimsamsa" # 不幸/困难 + D40 = "Khavedamsa" # 吉凶效果 + D45 = "Akshavedamsa" # 全面判断 + D60 = "Shashtiamsa" # 前世业力 + +class DignityLevel(Enum): + """行星尊严等级""" + EXALTED = "Exalted" # 入庙(最高) + MOOLATRIKONA = "Moolatrikona" # 根本三角 + OWN_SIGN = "Own Sign" # 自己的星座 + FRIEND = "Friend" # 友好星座 + NEUTRAL = "Neutral" # 中性星座 + ENEMY = "Enemy" # 敌对星座 + DEBILITATED = "Debilitated" # 落陷(最低) + +class VimsopakaBalaCalculator: + """Vimsopaka Bala计算器""" + + # BPHS标准权重系统(Shodasavarga - 16分盘) + SHODASAVARGA_WEIGHTS = { + VargaType.D1: 3.5, # Rashi + VargaType.D2: 1.0, # Hora + VargaType.D3: 1.0, # Drekkana + VargaType.D4: 0.5, # Chaturthamsa + VargaType.D7: 0.5, # Saptamsa + VargaType.D9: 3.5, # Navamsa + VargaType.D10: 0.5, # Dasamsa + VargaType.D12: 0.5, # Dwadasamsa + VargaType.D16: 2.0, # Shodasamsa + VargaType.D20: 0.5, # Vimsamsa + VargaType.D24: 0.5, # Chaturvimsamsa + VargaType.D27: 0.5, # Bhamsa + VargaType.D30: 1.0, # Trimsamsa + VargaType.D40: 0.5, # Khavedamsa + VargaType.D45: 0.5, # Akshavedamsa + VargaType.D60: 4.0 # Shashtiamsa + } + + # Dasa Varga权重系统(10分盘 - 简化版) + DASAVARGA_WEIGHTS = { + VargaType.D1: 3.0, + VargaType.D2: 1.5, + VargaType.D3: 1.5, + VargaType.D7: 1.5, + VargaType.D9: 3.0, + VargaType.D10: 1.5, + VargaType.D12: 1.5, + VargaType.D16: 1.5, + VargaType.D30: 1.5, + VargaType.D60: 5.0 + } + + # 尊严等级对应的Virupas(力量单位) + DIGNITY_VIRUPAS = { + DignityLevel.EXALTED: 20.0, + DignityLevel.MOOLATRIKONA: 18.0, + DignityLevel.OWN_SIGN: 15.0, + DignityLevel.FRIEND: 10.0, + DignityLevel.NEUTRAL: 7.5, + DignityLevel.ENEMY: 5.0, + DignityLevel.DEBILITATED: 2.0 + } + + # 力量等级分类(基于总分) + STRENGTH_CATEGORIES = { + "Parijatamsa": (18.0, 20.0), # 极强(18-20) + "Uttamamsa": (16.0, 18.0), # 优秀(16-18) + "Gopuramsa": (12.0, 16.0), # 良好(12-16) + "Simhasanamsa": (10.0, 12.0), # 中等偏上(10-12) + "Paravatamsa": (8.0, 10.0), # 中等(8-10) + "Devalokamsa": (6.0, 8.0), # 中等偏下(6-8) + "Brahmalokamsa": (4.0, 6.0), # 较弱(4-6) + "Airavata": (2.0, 4.0), # 弱(2-4) + "Vaiseshikamsa": (0.0, 2.0) # 极弱(0-2) + } + + def __init__(self, mode: str = "shodasavarga"): + """ + 初始化计算器 + + Args: + mode: "shodasavarga" (16分盘) 或 "dasavarga" (10分盘) + """ + self.mode = mode + self.weights = self.SHODASAVARGA_WEIGHTS if mode == "shodasavarga" else self.DASAVARGA_WEIGHTS + + def calculate_vimsopaka_bala(self, planet_vargas: Dict[str, Dict[VargaType, DignityLevel]]) -> Dict[str, Dict]: + """ + 计算所有行星的Vimsopaka Bala + + Args: + planet_vargas: {行星名: {分盘类型: 尊严等级}} + + Returns: + {行星名: { + "total_score": 总分, + "category": 力量等级, + "varga_scores": {分盘: 得分}, + "interpretation": 解读 + }} + """ + results = {} + + for planet, vargas in planet_vargas.items(): + planet_result = self._calculate_planet_vimsopaka(planet, vargas) + results[planet] = planet_result + + return results + + def _calculate_planet_vimsopaka(self, planet: str, vargas: Dict[VargaType, DignityLevel]) -> Dict: + """计算单个行星的Vimsopaka Bala""" + varga_scores = {} + total_weighted_score = 0.0 + total_weight = 0.0 + + # 计算每个分盘的得分 + for varga_type, dignity in vargas.items(): + if varga_type in self.weights: + # 获取尊严对应的Virupas + virupas = self.DIGNITY_VIRUPAS.get(dignity, 0.0) + + # 获取分盘权重 + weight = self.weights[varga_type] + + # 计算加权得分 + weighted_score = virupas * weight + + varga_scores[varga_type.value] = { + "dignity": dignity.value, + "virupas": virupas, + "weight": weight, + "weighted_score": round(weighted_score, 2) + } + + total_weighted_score += weighted_score + total_weight += weight + + # 计算最终得分(归一化到20分制) + if total_weight > 0: + final_score = total_weighted_score / total_weight + else: + final_score = 0.0 + + # 确定力量等级 + category = self._get_strength_category(final_score) + + # 生成解读 + interpretation = self._generate_interpretation(planet, final_score, category, varga_scores) + + return { + "planet": planet, + "total_score": round(final_score, 2), + "category": category, + "varga_scores": varga_scores, + "interpretation": interpretation, + "mode": self.mode + } + + def _get_strength_category(self, score: float) -> str: + """根据得分确定力量等级""" + for category, (min_score, max_score) in self.STRENGTH_CATEGORIES.items(): + if min_score <= score < max_score: + return category + return "Vaiseshikamsa" # 默认最低等级 + + def _generate_interpretation(self, planet: str, score: float, category: str, varga_scores: Dict) -> str: + """生成解读文本""" + interpretation = f"{planet}的Vimsopaka Bala得分为{score:.2f}/20,属于{category}等级。\n\n" + + # 根据等级给出解读 + if score >= 16: + interpretation += "这是极强的行星力量,表示该行星在生活中能够充分发挥其积极作用,带来显著的成果和成功。" + elif score >= 12: + interpretation += "这是良好的行星力量,表示该行星能够有效发挥作用,在其主管领域带来正面影响。" + elif score >= 8: + interpretation += "这是中等的行星力量,表示该行星的作用较为平衡,既有积极面也有挑战。" + elif score >= 4: + interpretation += "这是较弱的行星力量,表示该行星在发挥作用时会遇到一些困难和阻碍。" + else: + interpretation += "这是极弱的行星力量,表示该行星难以充分发挥其作用,需要通过补救措施来增强。" + + # 找出最强和最弱的分盘 + if varga_scores: + sorted_vargas = sorted(varga_scores.items(), key=lambda x: x[1]['weighted_score'], reverse=True) + strongest = sorted_vargas[0] + weakest = sorted_vargas[-1] + + interpretation += f"\n\n最强分盘:{strongest[0]}({strongest[1]['dignity']},得分{strongest[1]['weighted_score']})" + interpretation += f"\n最弱分盘:{weakest[0]}({weakest[1]['dignity']},得分{weakest[1]['weighted_score']})" + + return interpretation + + def compare_planets(self, results: Dict[str, Dict]) -> List[Tuple[str, float]]: + """ + 比较所有行星的力量,返回排序列表 + + Args: + results: calculate_vimsopaka_bala的返回结果 + + Returns: + [(行星名, 得分), ...] 按得分降序排列 + """ + planet_scores = [(planet, data["total_score"]) for planet, data in results.items()] + return sorted(planet_scores, key=lambda x: x[1], reverse=True) + + def get_remedial_recommendations(self, planet: str, score: float) -> List[str]: + """ + 根据Vimsopaka Bala得分提供补救建议 + + Args: + planet: 行星名 + score: Vimsopaka Bala得分 + + Returns: + 补救建议列表 + """ + recommendations = [] + + if score < 8: # 力量较弱,需要补救 + recommendations.append(f"建议佩戴{planet}对应的宝石来增强力量") + recommendations.append(f"在{planet}主管的日子进行布施(Daan)") + recommendations.append(f"念诵{planet}的咒语(Mantra)") + recommendations.append(f"在{planet}主管的时辰进行重要活动") + + if score < 4: # 极弱,需要额外补救 + recommendations.append(f"考虑进行{planet}的火祭仪式(Homa)") + recommendations.append(f"在{planet}主管的日子断食") + + return recommendations + + +# 示例用法 +if __name__ == "__main__": + # 创建计算器(使用16分盘模式) + calculator = VimsopakaBalaCalculator(mode="shodasavarga") + + # 示例数据:太阳在各分盘的尊严 + sun_vargas = { + VargaType.D1: DignityLevel.EXALTED, + VargaType.D2: DignityLevel.OWN_SIGN, + VargaType.D3: DignityLevel.FRIEND, + VargaType.D9: DignityLevel.MOOLATRIKONA, + VargaType.D10: DignityLevel.FRIEND, + VargaType.D12: DignityLevel.NEUTRAL, + VargaType.D16: DignityLevel.OWN_SIGN, + VargaType.D20: DignityLevel.FRIEND, + VargaType.D30: DignityLevel.ENEMY, + VargaType.D60: DignityLevel.EXALTED + } + + # 计算所有行星的Vimsopaka Bala + planet_vargas = { + "Sun": sun_vargas + } + + results = calculator.calculate_vimsopaka_bala(planet_vargas) + + # 打印结果 + for planet, data in results.items(): + print(f"\n{'='*60}") + print(f"{planet} - Vimsopaka Bala分析") + print(f"{'='*60}") + print(f"总分:{data['total_score']}/20") + print(f"等级:{data['category']}") + print(f"\n{data['interpretation']}") + + # 如果需要补救 + remedies = calculator.get_remedial_recommendations(planet, data['total_score']) + if remedies: + print(f"\n补救建议:") + for i, remedy in enumerate(remedies, 1): + print(f"{i}. {remedy}")