
Yijing Fengshui
- 254 installs
- 3 repo stars
- Updated January 22, 2026
- wolke/yijing-fengshui
Helps with ai & agent building tasks.
About
yijing-fengshui is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- yijing-fengshui
- AI & Agent Building
- AI-coding skill
Yijing Fengshui by the numbers
- 254 all-time installs (skills.sh)
- +12 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #2,538 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Jul 27, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wolke/yijing-fengshui --skill yijing-fengshuiAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 254 |
|---|---|
| repo stars | ★ 3 |
| Last updated | January 22, 2026 |
| Repository | wolke/yijing-fengshui ↗ |
What it does
Helps with ai & agent building tasks.
Files
易經陽宅風水分析技能
!易經陽宅風水
基於倪海廈老師的易經陽宅學說,分析家庭與辦公室的風水格局。
核心理念
重「神」不重「形」:本技能著重於「位置」與「格局」,而非風水擺件。
核心原則:名位相等、長幼有序
使用時機
當用戶詢問以下內容時啟用:
- 家庭成員臥室方位分析
- 房屋格局風水診斷
- 廚房、廁所方位問題
- 辦公室風水、老闆座位
- 關鍵詞:「風水」「陽宅」「方位」「臥室」「辦公室」
技能結構
yijing-fengshui/
├── SKILL.md ← 本文件
├── scripts/
│ └── fengshui_calc.py ← 卦象計算工具
└── references/
├── 64gua.md ← 六十四卦詳解
├── bagua-wanwu.md ← 八卦萬物類象
├── yangzhai-theory.md← 陽宅風水理論
├── room-fengshui.md ← 房間風水規則
└── office-fengshui.md← 辦公室風水八卦方位與家庭成員對應
| 卦名 | 方位 | 家庭成員 | 五行 | 自然象 |
|---|---|---|---|---|
| 乾 | 西北 | 父親(男主人、45歲以上男性) | 金 | 天 |
| 坤 | 西南 | 母親(女主人、45歲以上女性) | 土 | 地 |
| 震 | 正東 | 長子(31-45歲男性) | 木 | 雷 |
| 巽 | 東南 | 長女(31-45歲女性) | 木 | 風 |
| 坎 | 正北 | 中男(次子、16-30歲男性) | 水 | 水 |
| 離 | 正南 | 中女(次女、16-30歲女性) | 火 | 火 |
| 艮 | 東北 | 少男(幼子、15歲以下男性) | 土 | 山 |
| 兌 | 正西 | 少女(幼女、15歲以下女性) | 金 | 澤 |
分析流程
重要:無論居家或辦公室風水,都必須使用scripts/fengshui_calc.py計算卦象,再參考references/64gua.md解讀!
---
居家風水分析(格局導向)
居家風水以房屋格局為核心,分析廚房、廁所、臥室方位的吉凶。
步驟 1:收集格局資訊
詢問用戶各房間的方位:
- 廚房、廁所方位(最重要)
- 主臥室、子女房方位
- 客廳、玄關方位
步驟 1.5:從房間名稱推論家庭成員
重要:根據房間名稱自動推斷家庭成員,無需使用者重複說明!
| 房間名稱 | 推論的家庭成員 |
|---|---|
| 主臥室、主臥、父母房 | 父親 + 母親 |
| 長子房、大兒子房 | 長子 |
| 長女房、大女兒房 | 長女 |
| 次子房、二兒子房 | 中男/次子 |
| 次女房、二女兒房 | 中女/次女 |
| 小兒子房、幼子房 | 少男/幼子 |
| 小女兒房、幼女房 | 少女/幼女 |
範例推論:
- 用戶說「主臥室在東北」→ 自動推斷:父親在東北、母親在東北
- 用戶說「長子房在東」→ 自動推斷:長子在東
- 用戶說「長女房在東南」→ 自動推斷:長女在東南
步驟 2:執行卦象計算
使用 scripts/fengshui_calc.py 計算各房間的風水卦象:
# 分析房間風水(將步驟 1.5 推論出的家庭成員帶入)
# 範例:主臥室在東北 → 父親+母親在東北;長子房在東 → 長子在東
python scripts/fengshui_calc.py --analyze \
--family '{"父親": "東北", "母親": "東北", "長子": "東", "長女": "東南"}' \
--rooms '{"廚房": "西", "廁所1": "中央", "廁所2": "北"}'
# 輸出範例:
# {
# "family_analysis": [
# {"member": "父親", "hexagram_name": "天山遯", "status": "錯位", ...},
# {"member": "母親", "hexagram_name": "地山謙", "status": "錯位", ...},
# {"member": "長子", "hexagram_name": "震為雷", "status": "本位大吉", ...},
# ...
# ],
# "room_analysis": [...],
# "issues": [...],
# "recommendations": [...]
# }步驟 3:查詢卦義
對於涉及人員位置的情況(如主臥室方位),參考 references/64gua.md 解讀形成的卦象:
# 例如:父親住在東北方(艮位)
python scripts/fengshui_calc.py --person 乾 --position 艮
# 輸出: {"hexagram_number": 33, "hexagram_name": "天山遯", ...}然後在 references/64gua.md 中查找第 33 卦「天山遯」的含義。
步驟 4:綜合評估與建議
- 結合卦象含義與房間風水規則
- 提供調整或緩解建議(位置調整、通風、減少使用等)
---
辦公室風水分析(人員導向)
辦公室風水以決策者(老闆)為核心,需確認其屬卦後分析座位吉凶。
步驟 1:確認老闆資訊
必須詢問:
- 老闆的性別與年齡
步驟 2:判定屬卦與最佳座位
依據年齡性別對應:
- 男45歲+ → 乾卦 → 西北
- 女45歲+ → 坤卦 → 西南
- 男31-45歲 → 震卦 → 東
- 女31-45歲 → 巽卦 → 東南
- 其他參考
references/office-fengshui.md
步驟 3:執行卦象計算
python scripts/fengshui_calc.py --person 乾 --position 東
# 輸出: {"hexagram_number": 25, "hexagram_name": "天雷无妄", ...}步驟 4:查詢卦義給出建議
在 references/64gua.md 中查找對應卦象,解讀含義並給出建議
特殊房間規則
廚房
- 吉方:東、東南(木火通明)、北(水火既濟)
- 凶方:西北(火燒天門,傷男主人)、西南(裡鬼門)
- 詳見
references/room-fengshui.md
廁所
- 大忌:房屋中央、東北(鬼門)、西南(傷女主人)
- 注意:西北(傷男主人)
- 詳見
references/room-fengshui.md
辦公室
- 老闆座位依照其性別年齡對應的卦位
- 詳見
references/office-fengshui.md
輸出格式範例
## 🏠 陽宅風水分析報告
### 家庭成員位置分析
| 成員 | 屬卦 | 應住方位 | 實際方位 | 狀態 | 形成卦象 |
|------|------|----------|----------|------|----------|
| 父親 | 乾 | 西北 | 東 | ⚠️ 錯位 | 天雷无妄 |
| 長子 | 震 | 東 | 西北 | ⚠️ 錯位 | 雷天大壯 |
| 母親 | 坤 | 西南 | 西南 | ✅ 本位 | 坤為地 |
### 卦象解讀
**父親 → 天雷无妄(第25卦)**
- 卦辭:元亨利貞,其匪正有眚,不利有攸往
- 主題:不妄為,誠實
- 風水含義:父親住長子位,易有「無妄之災」,可能在事業或健康上遇到意外狀況
**長子 → 雷天大壯(第34卦)**
- 卦辭:利貞
- 主題:強壯,盛極
- 風水含義:長子住父親位,陽氣過盛,易衝動驕傲、與父親起衝突
### 房間風水
- ⚠️ **廚房在西北**:火燒天門,不利男主人健康(呼吸系統、大腸)
- ❌ **廁所在中央**:中宮穢氣,影響全家健康與運勢
### 改善建議
1. **最重要**:父親與長子對調房間,恢復「名位相等」
2. 廁所為大忌位置,若無法搬遷,需加強通風、保持門常關
3. 廚房問題可透過減少西北方火氣(如改用電磁爐)緩解解讀原則
1. 名位相等為吉:每個人住在自己對應的卦位最佳 2. 長幼有序:尊重家庭倫理,父母住主位 3. 卦象活用:64卦解讀需結合陽宅風水語境 4. 實用建議:著重位置調整,不建議買擺件 5. 心態引導:風水影響心境,心境影響行為
注意事項
- 若家庭成員不完整(如單親、獨居),以實際居住者為準
- 若空間有限無法調整,可建議次優方案
- 辦公室以老闆或主要決策者為核心分析
- 避免過度恐嚇用戶,以正面引導為主
Attribution-NonCommercial-ShareAlike 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
For the full license text, see:
https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
易經陽宅風水 Yijing Yangzhai Fengshui
!Hero Image
基於倪海廈老師易經陽宅學說的 AI 風水分析技能。

核心理念
重「神」不重「形」:強調「名位相等」與「長幼有序」,而非風水擺件。
本技能著重於:
- 位置與格局的分析
- 家庭成員臥室方位
- 廚房、廁所等特殊空間
- 辦公室老闆座位
功能
- 🏠 住宅風水分析:根據家庭成員組成與臥室方位,推導卦象
- 🍳 房間風水判斷:廚房、廁所、客廳的吉凶分析
- 🏢 辦公室風水:老闆座位方位分析
- 📖 六十四卦解讀:結合陽宅風水語境的卦象詮釋
使用方式
作為 AI Skill 使用
1. 將此資料夾複製到 Skills 目錄:
- Claude Code:
.agent/skills/ - Antigravity:
~/.gemini/antigravity/skills/
2. 在對話中使用觸發詞:
- 「幫我看風水」
- 「分析我家的方位」
- 「辦公室風水」
使用計算工具
# 單一卦象查詢
python scripts/fengshui_calc.py --person 震 --position 乾
# 輸出: {"hexagram_number": 34, "hexagram_name": "雷天大壯", ...}
# 完整分析
python scripts/fengshui_calc.py --analyze \
--family '{"父親": "東", "長子": "西北", "母親": "西南"}' \
--rooms '{"廚房": "西北", "廁所": "中央"}'使用網頁介面
提供視覺化平面圖建構器,可拖拉房間和家庭成員:
[👉 點此直接進行線上體驗 (Demo)](https://wolke.github.io/yijing-fengshui/)
或者本地運行:
cd web
npx -y serve .
# 打開 http://localhost:3000功能:
- 🖱️ 點擊或拖拉房間到畫布
- 📐 拖拉邊角縮放房間
- 🔄 拖拉黃點旋轉房間
- 👨👩👧👦 將家人放入臥室(會跟著房間移動)
- 📋 一鍵生成 AI 分析 Prompt
專案結構
yijing-fengshui/
├── SKILL.md # AI 技能指引
├── README.md # 本文件
├── LICENSE # CC BY-NC-SA 4.0
├── scripts/
│ └── fengshui_calc.py # 卦象計算工具
└── references/
├── 64gua.md # 六十四卦詳解
├── bagua-wanwu.md # 八卦萬物類象
├── yangzhai-theory.md# 陽宅風水理論
├── room-fengshui.md # 房間風水規則
└── office-fengshui.md# 辦公室風水八卦方位對應
| 卦 | 方位 | 家庭成員 | 五行 |
|---|---|---|---|
| 乾 | 西北 | 父親 | 金 |
| 坤 | 西南 | 母親 | 土 |
| 震 | 東 | 長子 | 木 |
| 巽 | 東南 | 長女 | 木 |
| 坎 | 北 | 中男 | 水 |
| 離 | 南 | 中女 | 火 |
| 艮 | 東北 | 少男 | 土 |
| 兌 | 西 | 少女 | 金 |
參考來源
- 倪海廈老師陽宅學說
- 《易經》六十四卦
License
六十四卦詳解
卦序表(上卦對橫行,下卦對縱行)
| 乾1 | 兌2 | 離3 | 震4 | 巽5 | 坎6 | 艮7 | 坤8 | |
|---|---|---|---|---|---|---|---|---|
| 乾1 | 1乾 | 10履 | 13同人 | 25无妄 | 44姤 | 6訟 | 33遯 | 12否 |
| 兌2 | 43夬 | 58兌 | 49革 | 17隨 | 28大過 | 47困 | 31咸 | 45萃 |
| 離3 | 14大有 | 38睽 | 30離 | 21噬嗑 | 50鼎 | 64未濟 | 56旅 | 35晉 |
| 震4 | 34大壯 | 54歸妹 | 55豐 | 51震 | 32恆 | 40解 | 62小過 | 16豫 |
| 巽5 | 9小畜 | 61中孚 | 37家人 | 42益 | 57巽 | 59渙 | 53漸 | 20觀 |
| 坎6 | 5需 | 60節 | 63既濟 | 3屯 | 48井 | 29坎 | 39蹇 | 8比 |
| 艮7 | 26大畜 | 41損 | 22賁 | 27頤 | 18蠱 | 4蒙 | 52艮 | 23剝 |
| 坤8 | 11泰 | 19臨 | 36明夷 | 24復 | 46升 | 7師 | 15謙 | 2坤 |
---
上經(1-30卦)
1. 乾為天 ䷀
- 卦辭:元亨利貞
- 主題:剛健進取,自強不息
- 關鍵:潛龍勿用→見龍在田→飛龍在天→亢龍有悔
- 陽宅含義:本位大吉,父親住西北為最佳
2. 坤為地 ䷁
- 卦辭:元亨,利牝馬之貞
- 主題:柔順包容,厚德載物
- 關鍵:順從為吉,不宜主動
- 陽宅含義:本位大吉,母親住西南為最佳
3. 水雷屯 ䷂
- 卦辭:元亨利貞,勿用有攸往,利建侯
- 主題:初生困難,需要積蓄力量
- 關鍵:創業維艱,宜靜待時機
- 陽宅含義:中男住長子位,事業初創有阻礙
4. 山水蒙 ䷃
- 卦辭:亨。匪我求童蒙,童蒙求我
- 主題:啟蒙教育,虛心學習
- 關鍵:不是我求他,是他來求我
- 陽宅含義:少男住中男位,需要學習成長
5. 水天需 ䷄
- 卦辭:有孚,光亨,貞吉,利涉大川
- 主題:等待時機,以誠待人
- 關鍵:需要等待,不可急躁
- 陽宅含義:中男住父親位,需等待時機
6. 天水訟 ䷅
- 卦辭:有孚窒惕,中吉,終凶
- 主題:爭訟,訴訟
- 關鍵:適可而止,不宜堅持到底
- 陽宅含義:父親住中男位,易有爭執訴訟
7. 地水師 ䷆
- 卦辭:貞,丈人吉,无咎
- 主題:軍隊,團隊領導
- 關鍵:需要有經驗的領導者
- 陽宅含義:母親住中男位,需有長者領導
8. 水地比 ䷇
- 卦辭:吉。原筮元永貞,无咎
- 主題:親比輔助,團結合作
- 關鍵:依附有力量者為吉
- 陽宅含義:中男住母親位,宜依附長輩
9. 風天小畜 ䷈
- 卦辭:亨。密雲不雨,自我西郊
- 主題:小的積蓄,力量不足
- 關鍵:時機未到,需繼續積累
- 陽宅含義:長女住父親位,力量尚不足
10. 天澤履 ䷉
- 卦辭:履虎尾,不咥人,亨
- 主題:如履薄冰,謹慎行事
- 關鍵:小心謹慎則無災
- 陽宅含義:父親住少女位,需謹慎處事
11. 地天泰 ䷊
- 卦辭:小往大來,吉亨
- 主題:通泰順利,天地交感
- 關鍵:否極泰來,好運開始
- 陽宅含義:母親住父親位,陰陽調和,夫妻和諧
12. 天地否 ䷋
- 卦辭:否之匪人,不利君子貞
- 主題:閉塞不通,小人當道
- 關鍵:宜守不宜進,靜待變化
- 陽宅含義:父親住母親位,陰盛陽衰,閉塞不通
13. 天火同人 ䷌
- 卦辭:同人于野,亨,利涉大川
- 主題:志同道合,團結合作
- 關鍵:與人合作共事為吉
- 陽宅含義:父親住中女位,志同道合
14. 火天大有 ䷍
- 卦辭:元亨
- 主題:富有,收穫豐盛
- 關鍵:大獲全勝,盛極之象
- 陽宅含義:中女住父親位,財運亨通
15. 地山謙 ䷎
- 卦辭:亨,君子有終
- 主題:謙虛退讓
- 關鍵:謙受益,滿招損
- 陽宅含義:母親住少男位,謙虛為吉
16. 雷地豫 ䷏
- 卦辭:利建侯行師
- 主題:歡樂預備
- 關鍵:預先準備,順勢而為
- 陽宅含義:長子住母親位,順勢發展
17. 澤雷隨 ䷐
- 卦辭:元亨利貞,无咎
- 主題:隨從,順應
- 關鍵:隨機應變,順勢而行
- 陽宅含義:少女住長子位,隨機應變
18. 山風蠱 ䷑
- 卦辭:元亨,利涉大川
- 主題:整治腐敗,革新
- 關鍵:敗壞需整頓
- 陽宅含義:少男住長女位,需整頓革新
19. 地澤臨 ䷒
- 卦辭:元亨利貞,至于八月有凶
- 主題:居高臨下,監督管理
- 關鍵:好運有時限
- 陽宅含義:母親住少女位,監督管理
20. 風地觀 ䷓
- 卦辭:盥而不薦,有孚顒若
- 主題:觀察,被觀察
- 關鍵:觀察形勢,以觀待變
- 陽宅含義:長女住母親位,觀察局勢
21. 火雷噬嗑 ䷔
- 卦辭:亨,利用獄
- 主題:咬合,排除障礙
- 關鍵:有障礙需突破
- 陽宅含義:中女住長子位,需排除阻礙
22. 山火賁 ䷕
- 卦辭:亨,小利有攸往
- 主題:文飾,裝飾
- 關鍵:外表裝飾,內在才是關鍵
- 陽宅含義:少男住中女位,重視表面
23. 山地剝 ䷖
- 卦辭:不利有攸往
- 主題:剝落,衰敗
- 關鍵:小人得勢,宜守不宜進
- 陽宅含義:少男住母親位,運勢剝落
24. 地雷復 ䷗
- 卦辭:亨。出入无疾,朋來无咎
- 主題:一陽來復,重新開始
- 關鍵:回歸正道,好運回轉
- 陽宅含義:母親住長子位,運勢回轉
25. 天雷无妄 ䷘
- 卦辭:元亨利貞,其匪正有眚,不利有攸往
- 主題:不妄為,誠實
- 關鍵:無妄之災要防範
- 陽宅含義:父親住長子位,易有無妄之災,意外頻發
26. 山天大畜 ䷙
- 卦辭:利貞。不家食吉,利涉大川
- 主題:大的積蓄,厚積薄發
- 關鍵:蓄積力量,待時而動
- 陽宅含義:少男住父親位,蓄積力量
27. 山雷頤 ䷚
- 卦辭:貞吉。觀頤,自求口實
- 主題:養育,修養
- 關鍵:養生之道
- 陽宅含義:少男住長子位,需注重修養
28. 澤風大過 ䷛
- 卦辭:棟橈,利有攸往,亨
- 主題:過度,危機
- 關鍵:棟梁彎曲,需非常手段
- 陽宅含義:少女住長女位,壓力過大
29. 坎為水 ䷜
- 卦辭:習坎,有孚,維心亨
- 主題:險阻重重
- 關鍵:重重險難,需堅持
- 陽宅含義:本位,中男住北方,需面對挑戰
30. 離為火 ䷝
- 卦辭:利貞,亨。畜牝牛吉
- 主題:光明依附
- 關鍵:依附正道為吉
- 陽宅含義:本位,中女住南方為吉
---
下經(31-64卦)
31. 澤山咸 ䷞
- 卦辭:亨利貞,取女吉
- 主題:感應,戀愛婚姻
- 關鍵:男女相感,婚姻吉
- 陽宅含義:少女住少男位,婚姻感情佳
32. 雷風恆 ䷟
- 卦辭:亨,无咎,利貞
- 主題:恆久,持久
- 關鍵:持之以恆
- 陽宅含義:長子住長女位,恆久穩定
33. 天山遯 ䷠
- 卦辭:亨,小利貞
- 主題:退避,隱退
- 關鍵:識時務者為俊傑
- 陽宅含義:父親住少男位,宜退避
34. 雷天大壯 ䷡
- 卦辭:利貞
- 主題:強壯,盛極
- 關鍵:強盛但要守正
- 陽宅含義:長子住父親位,陽氣過盛,易衝動驕傲、與父親起衝突
35. 火地晉 ䷢
- 卦辭:康侯用錫馬蕃庶
- 主題:晉升,進步
- 關鍵:升遷有望
- 陽宅含義:中女住母親位,事業晉升
36. 地火明夷 ䷣
- 卦辭:利艱貞
- 主題:光明受傷,韜光養晦
- 關鍵:暗藏實力,靜待時機
- 陽宅含義:母親住中女位,宜低調
37. 風火家人 ䷤
- 卦辭:利女貞
- 主題:家庭
- 關鍵:家和萬事興
- 陽宅含義:長女住中女位,家庭和諧
38. 火澤睽 ䷥
- 卦辭:小事吉
- 主題:乖離,不合
- 關鍵:意見分歧,小事可成
- 陽宅含義:中女住少女位,意見分歧
39. 水山蹇 ䷦
- 卦辭:利西南,不利東北
- 主題:困難險阻
- 關鍵:前有障礙,宜求助
- 陽宅含義:中男住少男位,困難重重
40. 雷水解 ䷧
- 卦辭:利西南
- 主題:解除困難
- 關鍵:雨過天晴
- 陽宅含義:長子住中男位,困難解除
41. 山澤損 ䷨
- 卦辭:有孚,元吉,无咎
- 主題:減損,付出
- 關鍵:損下益上
- 陽宅含義:少男住少女位,需要付出
42. 風雷益 ䷩
- 卦辭:利有攸往,利涉大川
- 主題:增益,獲得
- 關鍵:損上益下,利民
- 陽宅含義:長女住長子位,互利增益
43. 澤天夬 ䷪
- 卦辭:揚于王庭
- 主題:決斷,突破
- 關鍵:果斷處理
- 陽宅含義:少女住父親位,需果斷決策
44. 天風姤 ䷫
- 卦辭:女壯,勿用取女
- 主題:相遇,邂逅
- 關鍵:不期而遇
- 陽宅含義:父親住長女位,不期而遇
45. 澤地萃 ䷬
- 卦辭:亨,王假有廟
- 主題:聚集,匯聚
- 關鍵:人才匯聚
- 陽宅含義:少女住母親位,聚集資源
46. 地風升 ䷭
- 卦辭:元亨,用見大人
- 主題:上升,晉升
- 關鍵:穩步上升
- 陽宅含義:母親住長女位,穩步發展
47. 澤水困 ䷮
- 卦辭:亨,貞大人吉
- 主題:困窮,受困
- 關鍵:困境中需堅持
- 陽宅含義:少女住中男位,暫時受困
48. 水風井 ䷯
- 卦辭:改邑不改井
- 主題:井,資源
- 關鍵:養人濟民
- 陽宅含義:中男住長女位,資源穩定
49. 澤火革 ䷰
- 卦辭:己日乃孚
- 主題:變革,革新
- 關鍵:革故鼎新
- 陽宅含義:少女住中女位,需要變革
50. 火風鼎 ䷱
- 卦辭:元吉,亨
- 主題:鼎新,更新
- 關鍵:革新後的穩定
- 陽宅含義:中女住長女位,革新穩定
51. 震為雷 ䷲
- 卦辭:亨。震來虩虩
- 主題:震動,驚醒
- 關鍵:震撼後反省
- 陽宅含義:本位,長子住東方為吉
52. 艮為山 ䷳
- 卦辭:艮其背,不獲其身
- 主題:止,停止
- 關鍵:適可而止
- 陽宅含義:本位,少男住東北為吉
53. 風山漸 ䷴
- 卦辭:女歸吉,利貞
- 主題:漸進,循序
- 關鍵:循序漸進
- 陽宅含義:長女住少男位,循序發展
54. 雷澤歸妹 ䷵
- 卦辭:征凶,无攸利
- 主題:嫁妹,婚姻
- 關鍵:婚姻需謹慎
- 陽宅含義:長子住少女位,感情波折、家庭失和
55. 雷火豐 ䷶
- 卦辭:亨,王假之
- 主題:豐盛,盛大
- 關鍵:盛極必衰
- 陽宅含義:長子住中女位,運勢豐盛
56. 火山旅 ䷷
- 卦辭:小亨,旅貞吉
- 主題:旅行,漂泊
- 關鍵:在外謹慎
- 陽宅含義:中女住少男位,漂泊不定
57. 巽為風 ䷸
- 卦辭:小亨,利有攸往
- 主題:謙遜,順從
- 關鍵:以柔克剛
- 陽宅含義:本位,長女住東南為吉
58. 兌為澤 ䷹
- 卦辭:亨,利貞
- 主題:喜悅,和諧
- 關鍵:喜悅相處
- 陽宅含義:本位,少女住西方為吉
59. 風水渙 ䷺
- 卦辭:亨,王假有廟
- 主題:渙散,分散
- 關鍵:聚散離合
- 陽宅含義:長女住中男位,易聚散
60. 水澤節 ䷻
- 卦辭:亨。苦節不可貞
- 主題:節制,節約
- 關鍵:適度節制
- 陽宅含義:中男住少女位,需節制
61. 風澤中孚 ䷼
- 卦辭:豚魚吉,利涉大川
- 主題:誠信,信任
- 關鍵:以誠待人
- 陽宅含義:長女住少女位,誠信為本
62. 雷山小過 ䷽
- 卦辭:亨,利貞。可小事不可大事
- 主題:小的過失
- 關鍵:小事可成,大事不宜
- 陽宅含義:長子住少男位,小事可成
63. 水火既濟 ䷾
- 卦辭:亨小,利貞。初吉終亂
- 主題:已完成,圓滿
- 關鍵:成功後要守成
- 陽宅含義:中男住中女位,圓滿但需守成
64. 火水未濟 ䷿
- 卦辭:亨,小狐汔濟
- 主題:未完成,尚待努力
- 關鍵:功敗垂成之象
- 陽宅含義:中女住中男位,尚未完成
---
爻辭通則
- 初爻:事之始,位卑力微
- 二爻:內卦之中,得中位吉
- 三爻:內卦之極,多凶多懼
- 四爻:近君之位,多憂慮
- 五爻:君位,九五之尊
- 上爻:事之終,物極必反
八卦萬物類象
八卦與萬物的對應關係,用於風水分析時的延伸解讀。
---
八卦基本類象
乾卦 ☰(西北)
| 類別 | 對應 |
|---|---|
| 家人 | 父親、老人、長輩 |
| 人體 | 頭、肺、大腸 |
| 動物 | 馬、獅、象 |
| 五行 | 金 |
| 性質 | 剛健、積極、領導 |
| 職業 | 領導、官員、CEO |
坤卦 ☷(西南)
| 類別 | 對應 |
|---|---|
| 家人 | 母親、老婦、主婦 |
| 人體 | 腹、脾、胃 |
| 動物 | 牛、母馬 |
| 五行 | 土 |
| 性質 | 順從、包容、厚德 |
| 職業 | 農業、地產、教育 |
震卦 ☳(東)
| 類別 | 對應 |
|---|---|
| 家人 | 長子、青年男性 |
| 人體 | 足、肝、神經 |
| 動物 | 龍、蛇、蟲 |
| 五行 | 木 |
| 性質 | 震動、驚醒、行動 |
| 職業 | 運動員、創業者、開拓者 |
巽卦 ☴(東南)
| 類別 | 對應 |
|---|---|
| 家人 | 長女、青年女性 |
| 人體 | 股、膽、氣管 |
| 動物 | 雞、蛇、蜂 |
| 五行 | 木 |
| 性質 | 柔順、進入、溝通 |
| 職業 | 商人、文書、傳媒 |
坎卦 ☵(北)
| 類別 | 對應 |
|---|---|
| 家人 | 中男、次子 |
| 人體 | 耳、腎、血液 |
| 動物 | 豬、魚、水生動物 |
| 五行 | 水 |
| 性質 | 險阻、智慧、變通 |
| 職業 | 漁業、水利、思想家 |
離卦 ☲(南)
| 類別 | 對應 |
|---|---|
| 家人 | 中女、次女 |
| 人體 | 目、心、血管 |
| 動物 | 鳳、雉、蝦蟹 |
| 五行 | 火 |
| 性質 | 光明、依附、文明 |
| 職業 | 文化、藝術、傳媒 |
艮卦 ☶(東北)
| 類別 | 對應 |
|---|---|
| 家人 | 少男、幼子 |
| 人體 | 手、背、鼻 |
| 動物 | 狗、鼠、虎 |
| 五行 | 土 |
| 性質 | 停止、穩重、保守 |
| 職業 | 礦業、建築、守門 |
兌卦 ☱(西)
| 類別 | 對應 |
|---|---|
| 家人 | 少女、幼女 |
| 人體 | 口、舌、牙 |
| 動物 | 羊、澤中動物 |
| 五行 | 金 |
| 性質 | 喜悅、口才、交際 |
| 職業 | 演說家、歌手、銷售 |
---
八卦與疾病
在陽宅風水中,方位問題可能影響對應的身體部位:
| 卦位 | 受損時影響 |
|---|---|
| 乾(西北) | 頭痛、肺病、大腸問題 |
| 坤(西南) | 腹痛、脾胃病、婦科 |
| 震(東) | 足病、肝病、神經衰弱 |
| 巽(東南) | 感冒、氣管炎、股部 |
| 坎(北) | 耳疾、腎病、泌尿系統 |
| 離(南) | 眼疾、心臟病、血液 |
| 艮(東北) | 手傷、背痛、鼻病 |
| 兌(西) | 口腔病、呼吸道、皮膚 |
---
五行生剋
相生循環
木 → 火 → 土 → 金 → 水 → 木相剋循環
木 → 土 → 水 → 火 → 金 → 木方位五行關係
| 方位 | 五行 | 生 | 剋 |
|---|---|---|---|
| 東、東南 | 木 | 生火 | 剋土 |
| 南 | 火 | 生土 | 剋金 |
| 西南、東北 | 土 | 生金 | 剋水 |
| 西、西北 | 金 | 生水 | 剋木 |
| 北 | 水 | 生木 | 剋火 |
---
顏色對應
| 五行 | 顏色 | 方位 |
|---|---|---|
| 木 | 青、綠 | 東、東南 |
| 火 | 紅、紫 | 南 |
| 土 | 黃、棕 | 西南、東北、中央 |
| 金 | 白、銀 | 西、西北 |
| 水 | 黑、藍 | 北 |
---
數字對應
先天八卦數
| 卦 | 數 |
|---|---|
| 乾 | 1 |
| 兌 | 2 |
| 離 | 3 |
| 震 | 4 |
| 巽 | 5 |
| 坎 | 6 |
| 艮 | 7 |
| 坤 | 8 |
洛書數
| 方位 | 數 |
|---|---|
| 南 | 9 |
| 西南 | 2 |
| 東 | 3 |
| 東南 | 4 |
| 中央 | 5 |
| 西北 | 6 |
| 西 | 7 |
| 東北 | 8 |
| 北 | 1 |
辦公室風水
將陽宅風水原則應用於辦公室環境。
---
核心原則
辦公室風水以老闆(主要決策者)為核心分析對象。
老闆的屬卦判定
根據老闆的性別和年齡:
| 條件 | 屬卦 | 最佳座位方位 |
|---|---|---|
| 男性,45歲以上 | 乾 | 西北 |
| 女性,45歲以上 | 坤 | 西南 |
| 男性,31-45歲 | 震 | 東 |
| 女性,31-45歲 | 巽 | 東南 |
| 男性,16-30歲 | 坎 | 北 |
| 女性,16-30歲 | 離 | 南 |
| 男性,15歲以下 | 艮 | 東北 |
| 女性,15歲以下 | 兌 | 西 |
註:若企業由夫妻共同經營,以主要決策者為準。
---
老闆座位分析
本位大吉
老闆座位在其屬卦對應的方位:
- 權威穩固
- 決策正確
- 員工服從
- 事業順利
錯位影響
老闆座位不在正確方位時,形成相應卦象:
常見錯位情況
| 老闆屬卦 | 錯位方位 | 形成卦象 | 影響 |
|---|---|---|---|
| 乾(男老闆45+) | 東 | 天雷无妄 | 無妄之災,意外損失 |
| 乾 | 西南 | 天地否 | 閉塞不通,事業受阻 |
| 坤(女老闆45+) | 西北 | 地天泰 | 尚可,但非最佳 |
| 震(男老闆31-45) | 西北 | 雷天大壯 | 過於強勢,易與合作方衝突 |
---
辦公室格局
老闆辦公室
1. 位置:辦公室的財位或其屬卦對應方位 2. 門向:不宜正對電梯、廁所、樓梯 3. 座位背後:宜有實牆,象徵靠山 4. 窗戶:宜有窗但不宜座位正對窗
員工座位
1. 依照員工在公司的角色安排 2. 主管級員工可參考其屬卦 3. 一般員工以工作效率為主
會議室
1. 宜在公司的東南方(巽卦,溝通順暢) 2. 或南方(離卦,思維清晰) 3. 避免在東北方(鬼門位)
---
辦公室廁所
大忌位置
| 位置 | 問題 |
|---|---|
| 辦公室中央 | 穢氣擴散,影響全體員工健康 |
| 老闆辦公室旁 | 影響老闆決策與健康 |
| 財位 | 財運受損 |
| 大門正對 | 財氣外洩 |
緩解方法
1. 保持廁所門常關 2. 加強通風除臭 3. 在廁所與辦公區之間設置屏風或植物
---
茶水間/廚房
辦公室的茶水間相當於家庭的廚房。
建議位置
- 東方或東南方:木火通明,員工關係融洽
- 北方:水火既濟,尚可
避免位置
- 西北方:傷老闆(尤其男性老闆)
- 西南方:傷女性主管
---
簡易分析流程
1. 確定老闆資訊:性別、年齡 2. 判定屬卦:根據上表 3. 確認座位方位:老闆座位在辦公室的哪個方位 4. 推導卦象:老闆屬卦(上卦)+ 座位方位卦(下卦) 5. 分析吉凶:查詢64卦含義 6. 給出建議:調整座位或提供緩解方案
---
輸出範例
## 🏢 辦公室風水分析報告
### 老闆資訊
- 性別:男
- 年齡:52歲
- 屬卦:乾
- 最佳座位方位:西北
### 當前狀況
- 老闆座位方位:東
- 形成卦象:天雷无妄(第25卦)
### 分析
- 卦辭:元亨利貞,其匪正有眚,不利有攸往
- 含義:老闆座位不在本位,易有無妄之災
- 具體影響:
- 可能遇到意外的商業糾紛
- 決策時容易失誤
- 員工可能不服管理
### 建議
1. **最佳方案**:將老闆座位移至辦公室西北角
2. **次佳方案**:若無法調整,可在座位後方放置山水畫(象徵靠山)
3. **心態調整**:遇事三思,避免衝動決策---
注意事項
1. 辦公室風水以老闆為核心,但也需考慮整體格局 2. 若是租賃辦公室,格局無法大改,重點放在座位安排 3. 現代辦公室多為開放式,可用屏風、植物區隔 4. 風水為輔助,經營管理才是根本
房間風水規則
特殊房間(廚房、廁所、客廳)的風水規則。
---
廚房
廚房是烹煮食物的地方,直接影響家人的飲食健康。屬火。
吉方
| 方位 | 評級 | 說明 |
|---|---|---|
| 東 | 大吉 | 木火通明,家人得貴人扶持 |
| 東南 | 大吉 | 木火通明,有助家庭和諧 |
| 北 | 中吉 | 水火既濟,家人平安 |
| 東北 | 中吉 | 火土相生 |
凶方
| 方位 | 評級 | 說明 |
|---|---|---|
| 西北 | 凶 | 火燒天門,傷男主人(呼吸系統、大腸) |
| 西南 | 凶 | 裡鬼門,午後西曬不利食物保存,家人多病 |
| 西 | 凶 | 火金相剋,運氣反覆 |
| 南 | 小吉 | 火氣太旺,家人易急躁爭執 |
廚房與生育
- 廚房在東方或東南方:有助生育
- 廚房在東北方(艮卦):不利子女運勢,可能影響懷孕
緩解方法
若廚房位置不佳且無法搬遷: 1. 減少使用明火,改用電磁爐 2. 加強廚房通風 3. 保持廚房整潔 4. 在廚房放置與該方位相生的五行元素
---
廁所
廁所為不潔之地,排污性質,風水上需謹慎處理。屬水。
大忌方位
| 方位 | 評級 | 說明 |
|---|---|---|
| 中央 | 大凶 | 中宮穢氣,嚴重影響全家健康,尤其男主人 |
| 東北 | 大凶 | 鬼門位,陰暗潮濕,土克水,家人體弱多病 |
| 西南 | 凶 | 傷女主人,脾胃不佳、婦科疾病 |
| 西北 | 凶 | 傷男主人,事業及健康受損 |
可接受方位
| 方位 | 評級 | 說明 |
|---|---|---|
| 東 | 中 | 水木相生,需保持通風 |
| 東南 | 中 | 水木相生,採光較好 |
| 北 | 中 | 坎位屬水,尚可 |
| 西 | 中 | 金水相生,尚可 |
| 南 | 凶 | 水火相沖,易生是非疾病 |
緩解方法
若廁所位置不佳且無法搬遷: 1. 保持門常關:減少穢氣外溢 2. 加強通風:避免濕氣、臭氣滋生 3. 保持明亮整潔:減少陰暗潮濕 4. 放置綠色植物:吸收濕氣(注意選擇耐陰植物) 5. 定期清潔:避免細菌滋生
---
客廳
客廳是家人聚集、接待賓客的地方,代表家庭的對外形象。
基本原則
1. 宜在房屋中心偏南:光線充足 2. 宜開闘明亮:氣場流通 3. 忌過於陰暗:影響家人精神 4. 忌雜亂:影響運勢
方位建議
| 方位 | 說明 |
|---|---|
| 南 | 光線充足,利於社交 |
| 東南 | 和諧,利於家人關係 |
| 中央 | 家庭重心,但需通風 |
---
餐廳
餐廳是全家人共享美食的地方,象徵家庭的財富與食祿。
吉方
- 中心位置:設於客廳與廚房之間,有利家庭和諧。
- 東南方:財位,有利財運。
避忌
1. 進門見餐桌:容易導致漏財,缺乏奮鬥精神。 2. 正對廁所門:穢氣直衝,影響食慾與健康。 3. 橫樑壓頂:影響用餐情緒與消化健康。 4. 與廚房相連但無門:油煙擴散,影響空氣品質(建議設推拉門)。
佈局建議
- 餐桌宜選圓形或方形,象徵圓滿與方正。
- 保持明亮通風,氣場流通。
- 避免使用尖角過多的餐桌。
---
書房
書房與文昌運勢相關,影響學業與事業決策。
吉方
- 文昌位:東南(流年文昌位或本命文昌位),有利讀書考試。
- 東北:適合思考與學習。
避忌
1. 書桌背門:缺乏安全感,容易分心。 2. 書桌衝門:氣流直衝,難以專注。 3. 橫樑壓頂:壓力過大,思緒受阻。 4. 面朝窗戶:容易被窗外景象分心(書桌宜側對窗)。
---
神明廳
神明廳是安置祖先與神明之處,地位至關重要,影響家運興衰。
吉方
- 視野開闊處:宜面向屋外,忌面對牆壁或死角。
- 最高樓層:若為透天,通常設於頂樓。
大忌
1. 背後無靠:神桌後方必須是實牆,不可是窗戶或走道。 2. 後方為廁所/廚房:對神明不敬,易招致災禍。 3. 橫樑壓頂:家運受壓,難以伸展。 4. 與祖先牌位錯置:神明宜在面對神桌的左方(龍邊),祖先在右方(虎邊)。
---
臥室
臥室是休息之處,風水上最重要的是讓正確的人住在正確的位置。
主臥室
- 最佳位置:西北方(男主人)或西南方(女主人主導時)
- 避免:正對廁所門、廚房門
子女房
- 依照子女的角色安排對應方位
- 長子宜東、長女宜東南
- 次子宜北、次女宜南
- 幼子宜東北、幼女宜西
通用原則
1. 床頭宜靠實牆 2. 避免床頭朝門 3. 避免橫樑壓床 4. 保持通風但避免風直吹
---
大門與玄關
大門是「納氣之口」,玄關則是氣流緩衝區,主宰全家的事業運與財運。
大門禁忌
1. 穿堂煞:大門直通後門或陽台,財氣無法聚集(需設屏風或櫃體化解)。 2. 開口煞:大門正對電梯或樓梯口,氣場不穩。 3. 開門見灶/廁/鏡:見灶漏財,見廁晦氣,見鏡反射財氣。
玄關重點
- 保持明亮整潔:不宜堆放雜物鞋子,以免阻擋運勢。
- 避免狹窄:不宜過於狹長陰暗。
- 化煞功能:可擺放綠植或吉祥物化解外煞。
---
陽台
陽台代表「外明堂」,象徵前途事業與人際關係。
規則
1. 保持整潔:不宜堆放雜物,以免前途受阻。 2. 忌路沖/天斬煞:若面對反弓路或兩樓夾縫,需掛風水物化解。 3. 忌正對大門:形成穿堂煞(見大門章節)。 4. 適度植栽:種植闊葉植物可招財,但忌過多爬藤類招陰。
---
樓梯
樓梯是氣流傳遞的通道。
禁忌
1. 居中:樓梯不宜設在房屋正中央(斷心煞),大凶。 2. 正對大門:財氣一進門就隨樓梯流失,或樓梯氣流直衝大門。 3. 螺旋梯/陡梯:氣流不穩,易生意外。 4. 樓梯下設衛浴/水景:不利健康與事業。
---
車庫
建議
1. 方位:西北(乾位)為最佳車庫方位,因汽車屬金。 2. 避免方位:南方(火剋金)、東北(鬼門)。 3. 避忌:車庫上方不宜為臥室(尤其主臥),氣場浮動影響睡眠。
---
儲藏室
規則
- 忌堆放雜亂:即使是儲藏室也要分類整理,不可成為死氣聚集地。
- 忌設於吉方:吉方(如財位、文昌位)宜做主要活動空間,儲藏室宜設於凶方鎮壓。
- 保持乾燥:避免發霉晦氣擴散。
---
五行相生相剋速查
相生(有利)
- 木生火
- 火生土
- 土生金
- 金生水
- 水生木
相剋(不利)
- 木剋土
- 土剋水
- 水剋火
- 火剋金
- 金剋木
方位五行
| 方位 | 五行 |
|---|---|
| 東、東南 | 木 |
| 南 | 火 |
| 西南、東北 | 土 |
| 西、西北 | 金 |
| 北 | 水 |
陽宅風水理論
基於倪海廈老師的易經陽宅學說整理。
核心原則
1. 重「神」不重「形」
真正的風水並非依賴水晶、八卦鏡等裝飾品,而是著重於:
- 位(位置)而非形(形式)
- 睡覺位置對個人運勢有決定性影響
- 避免在「形」上做文章(如買魚缸、玉石、改門對門)
2. 名位相等
人的名分與其所居住的位置應當相符,才能帶來吉利。
家庭和睦(家和):
- 家庭成員居住在與其身分相應的位置時,家庭就能和睦
- 父親居於西北方(乾位)= 本位大吉
- 母親居於西南方(坤位)= 本位大吉
事業興旺(萬事興):
- 負責賺錢的人應居住在正確的位置上
- 以其名分來開展事業
- 例:主臥室位於東方(長子位),以長子名義註冊公司,事業興旺
- 若居住位置與名分不符,可能招致不測之災
特殊情況:
- 若夫妻因格局限制,先生暫居西南方,公司法定代表人應改為太太
- 這樣仍符合「名位相等」原則
3. 長幼有序
家庭成員應按照輩份和年齡,居住在符合其身份的卦位上。
基本排序:
- 爸爸媽媽 > 哥哥姐姐 > 弟弟妹妹
- 這些名分代表著長幼有序
錯位後果:
- 僅有名分上的「長幼有序」,缺乏實質的「神」與「位」
- 名分作用大打折扣
- 可能出現:子女不聽管教、妹妹比姐姐早嫁
---
八卦方位對應
後天八卦方位圖
南(離)
☲
東南(巽) 西南(坤)
☴ ☷
東(震)☳ 中 ☱(兌)西
東北(艮) 西北(乾)
☶ ☰
☵
北(坎)家庭成員對應表
| 卦 | 方位 | 成員 | 年齡範圍 | 五行 |
|---|---|---|---|---|
| 乾 | 西北 | 父親/男主人 | 45歲以上男性 | 金 |
| 坤 | 西南 | 母親/女主人 | 45歲以上女性 | 土 |
| 震 | 東 | 長子 | 31-45歲男性 | 木 |
| 巽 | 東南 | 長女 | 31-45歲女性 | 木 |
| 坎 | 北 | 中男/次子 | 16-30歲男性 | 水 |
| 離 | 南 | 中女/次女 | 16-30歲女性 | 火 |
| 艮 | 東北 | 少男/幼子 | 15歲以下男性 | 土 |
| 兌 | 西 | 少女/幼女 | 15歲以下女性 | 金 |
---
錯位卦象分析
當人住錯位置時,會形成特定的《易經》卦象,導致性格或運勢改變。
主要錯位情況
長子住父親位(西北)→ 雷天大壯
- 卦象:震上乾下
- 含義:陽氣盛壯,聲勢浩大
- 影響:
- 易衝動驕傲
- 與父親起衝突
- 物極必反,過剛易折
- 建議:心平氣和,避免蠻幹
父親住長子位(東)→ 天雷无妄
- 卦象:乾上震下
- 含義:不期而至的災禍
- 影響:
- 無妄之災
- 事業或健康意外
- 不應妄為
- 建議:順應天命,真誠無妄
長子住少女位(西)→ 雷澤歸妹
- 卦象:震上兌下
- 含義:少女嫁給長男,不合常理
- 影響:
- 感情波折
- 家庭失和
- 婚姻不順
- 建議:回歸正位
夫妻對調(乾坤互換)
母親住父親位(西北)→ 地天泰
- 陰陽調和,天地交感
- 相對吉利,但非最佳
父親住母親位(西南)→ 天地否
- 閉塞不通
- 陰盛陽衰
- 太太比先生強勢
- 諸事不順
---
本位大吉
每個人住在自己對應的卦位上,形成「純卦」,為最佳狀態:
| 成員 | 方位 | 形成卦象 | 狀態 |
|---|---|---|---|
| 父親 | 西北 | 乾為天 | ✅ 本位大吉 |
| 母親 | 西南 | 坤為地 | ✅ 本位大吉 |
| 長子 | 東 | 震為雷 | ✅ 本位大吉 |
| 長女 | 東南 | 巽為風 | ✅ 本位大吉 |
| 中男 | 北 | 坎為水 | ✅ 本位大吉 |
| 中女 | 南 | 離為火 | ✅ 本位大吉 |
| 少男 | 東北 | 艮為山 | ✅ 本位大吉 |
| 少女 | 西 | 兌為澤 | ✅ 本位大吉 |
---
分析方法
步驟一:確定家庭成員
1. 列出所有家庭成員 2. 確定每個人的角色(父/母/長子/長女等) 3. 若角色不完整,以實際最年長者為主位
步驟二:對應卦位
1. 根據成員角色,確定其屬卦 2. 記錄其實際居住的方位 3. 將方位轉換為對應的卦
步驟三:推導卦象
- 上卦:人的屬卦
- 下卦:所住位置的卦
- 查64卦表,得出形成的卦象
步驟四:分析吉凶
1. 若為純卦(上下相同)= 本位大吉 2. 若不同,查詢該卦的含義 3. 結合陽宅風水語境解讀
步驟五:提出建議
1. 優先建議調整位置 2. 若無法調整,提供緩解方案 3. 強調心態調整的重要性
---
注意事項
1. 不賣擺件:真正的風水在於位置,不是物品 2. 心念重要:風水影響心境,心境影響行為 3. 因地制宜:現代住宅格局有限,需靈活應用 4. 不過度恐嚇:以正面引導為主 5. 尊重選擇:最終決定權在用戶
#!/usr/bin/env python3
"""
易經陽宅風水卦象計算工具
Yijing Yangzhai Fengshui Hexagram Calculator
根據人的屬卦與所住方位,推導形成的六十四卦。
"""
import json
import argparse
from typing import Dict, Tuple, Optional
# 八卦資料(先天八卦數)
BAGUA = {
"乾": {"number": 1, "direction": "西北", "member": "父", "element": "金", "symbol": "☰"},
"兌": {"number": 2, "direction": "西", "member": "少女", "element": "金", "symbol": "☱"},
"離": {"number": 3, "direction": "南", "member": "中女", "element": "火", "symbol": "☲"},
"震": {"number": 4, "direction": "東", "member": "長男", "element": "木", "symbol": "☳"},
"巽": {"number": 5, "direction": "東南", "member": "長女", "element": "木", "symbol": "☴"},
"坎": {"number": 6, "direction": "北", "member": "中男", "element": "水", "symbol": "☵"},
"艮": {"number": 7, "direction": "東北", "member": "少男", "element": "土", "symbol": "☶"},
"坤": {"number": 8, "direction": "西南", "member": "母", "element": "土", "symbol": "☷"},
}
# 方位到卦的反查
DIRECTION_TO_GUA = {
"西北": "乾", "NW": "乾",
"西": "兌", "W": "兌",
"南": "離", "S": "離",
"東": "震", "E": "震",
"東南": "巽", "SE": "巽",
"北": "坎", "N": "坎",
"東北": "艮", "NE": "艮",
"西南": "坤", "SW": "坤",
"中央": "中央", "C": "中央", # 特殊處理
}
# 家庭成員到卦的對應
MEMBER_TO_GUA = {
"父": "乾", "父親": "乾", "男主人": "乾", "老闆(男)": "乾",
"母": "坤", "母親": "坤", "女主人": "坤", "老闆(女)": "坤",
"長子": "震", "長男": "震",
"長女": "巽",
"中男": "坎", "次子": "坎",
"中女": "離", "次女": "離",
"少男": "艮", "幼子": "艮", "三子": "艮",
"少女": "兌", "幼女": "兌", "三女": "兌",
}
# 六十四卦名稱(上卦, 下卦)
HEXAGRAMS = {
(1, 1): (1, "乾為天"), (1, 2): (10, "天澤履"), (1, 3): (13, "天火同人"), (1, 4): (25, "天雷无妄"),
(1, 5): (44, "天風姤"), (1, 6): (6, "天水訟"), (1, 7): (33, "天山遯"), (1, 8): (12, "天地否"),
(2, 1): (43, "澤天夬"), (2, 2): (58, "兌為澤"), (2, 3): (49, "澤火革"), (2, 4): (17, "澤雷隨"),
(2, 5): (28, "澤風大過"), (2, 6): (47, "澤水困"), (2, 7): (31, "澤山咸"), (2, 8): (45, "澤地萃"),
(3, 1): (14, "火天大有"), (3, 2): (38, "火澤睽"), (3, 3): (30, "離為火"), (3, 4): (21, "火雷噬嗑"),
(3, 5): (50, "火風鼎"), (3, 6): (64, "火水未濟"), (3, 7): (56, "火山旅"), (3, 8): (35, "火地晉"),
(4, 1): (34, "雷天大壯"), (4, 2): (54, "雷澤歸妹"), (4, 3): (55, "雷火豐"), (4, 4): (51, "震為雷"),
(4, 5): (32, "雷風恆"), (4, 6): (40, "雷水解"), (4, 7): (62, "雷山小過"), (4, 8): (16, "雷地豫"),
(5, 1): (9, "風天小畜"), (5, 2): (61, "風澤中孚"), (5, 3): (37, "風火家人"), (5, 4): (42, "風雷益"),
(5, 5): (57, "巽為風"), (5, 6): (59, "風水渙"), (5, 7): (53, "風山漸"), (5, 8): (20, "風地觀"),
(6, 1): (5, "水天需"), (6, 2): (60, "水澤節"), (6, 3): (63, "水火既濟"), (6, 4): (3, "水雷屯"),
(6, 5): (48, "水風井"), (6, 6): (29, "坎為水"), (6, 7): (39, "水山蹇"), (6, 8): (8, "水地比"),
(7, 1): (26, "山天大畜"), (7, 2): (41, "山澤損"), (7, 3): (22, "山火賁"), (7, 4): (27, "山雷頤"),
(7, 5): (18, "山風蠱"), (7, 6): (4, "山水蒙"), (7, 7): (52, "艮為山"), (7, 8): (23, "山地剝"),
(8, 1): (11, "地天泰"), (8, 2): (19, "地澤臨"), (8, 3): (36, "地火明夷"), (8, 4): (24, "地雷復"),
(8, 5): (46, "地風升"), (8, 6): (7, "地水師"), (8, 7): (15, "地山謙"), (8, 8): (2, "坤為地"),
}
def normalize_direction(direction: str) -> str:
"""標準化方位輸入"""
direction = direction.strip().upper() if direction.isascii() else direction.strip()
# 處理各種輸入格式
mappings = {
"正東": "東", "正西": "西", "正南": "南", "正北": "北",
"EAST": "東", "WEST": "西", "SOUTH": "南", "NORTH": "北",
"NORTHEAST": "東北", "NORTHWEST": "西北", "SOUTHEAST": "東南", "SOUTHWEST": "西南",
"CENTER": "中央", "MIDDLE": "中央",
}
return mappings.get(direction, direction)
def direction_to_gua(direction: str) -> Optional[str]:
"""將方位轉換為卦名"""
direction = normalize_direction(direction)
return DIRECTION_TO_GUA.get(direction)
def get_person_gua(member: str) -> Optional[str]:
"""根據家庭成員角色取得屬卦"""
return MEMBER_TO_GUA.get(member)
def get_hexagram(upper_gua: str, lower_gua: str) -> Dict:
"""
根據上卦和下卦推導六十四卦
Args:
upper_gua: 上卦名稱(人的屬卦)
lower_gua: 下卦名稱(所住位置的卦)
Returns:
卦象資訊字典
"""
if upper_gua not in BAGUA or lower_gua not in BAGUA:
return {"error": f"無效的卦名: {upper_gua} 或 {lower_gua}"}
upper_num = BAGUA[upper_gua]["number"]
lower_num = BAGUA[lower_gua]["number"]
if (upper_num, lower_num) not in HEXAGRAMS:
return {"error": f"找不到對應的卦象: 上{upper_gua} 下{lower_gua}"}
number, name = HEXAGRAMS[(upper_num, lower_num)]
# 判斷是否為本位
is_native = upper_gua == lower_gua
return {
"hexagram_number": number,
"hexagram_name": name,
"upper_gua": upper_gua,
"upper_symbol": BAGUA[upper_gua]["symbol"],
"lower_gua": lower_gua,
"lower_symbol": BAGUA[lower_gua]["symbol"],
"is_native_position": is_native,
"status": "本位大吉" if is_native else "錯位"
}
def analyze_family(family: Dict[str, str], rooms: Optional[Dict[str, str]] = None) -> Dict:
"""
分析家庭成員的風水配置
Args:
family: {"成員名": "方位"} 如 {"父親": "東", "長子": "西北"}
rooms: {"房間": "方位"} 如 {"廚房": "西北", "廁所": "中央"}
Returns:
完整分析結果
"""
results = {
"family_analysis": [],
"room_analysis": [],
"issues": [],
"recommendations": []
}
# 分析家庭成員
for member, direction in family.items():
person_gua = get_person_gua(member)
if not person_gua:
results["family_analysis"].append({
"member": member,
"error": f"無法識別成員角色: {member}"
})
continue
position_gua = direction_to_gua(direction)
if not position_gua:
results["family_analysis"].append({
"member": member,
"error": f"無法識別方位: {direction}"
})
continue
ideal_direction = BAGUA[person_gua]["direction"]
hexagram_info = get_hexagram(person_gua, position_gua)
analysis = {
"member": member,
"role": BAGUA[person_gua]["member"],
"person_gua": person_gua,
"ideal_direction": ideal_direction,
"actual_direction": direction,
**hexagram_info
}
results["family_analysis"].append(analysis)
# 記錄問題
if not hexagram_info.get("is_native_position"):
results["issues"].append(
f"{member}住在{direction}(應住{ideal_direction}),形成「{hexagram_info['hexagram_name']}」卦"
)
# 分析房間
if rooms:
for room, direction in rooms.items():
room_analysis = analyze_room(room, direction)
results["room_analysis"].append(room_analysis)
if room_analysis.get("status") in ["凶", "大凶"]:
results["issues"].append(
f"{room}在{direction}:{room_analysis.get('effect', '')}"
)
# 生成建議
if results["issues"]:
results["recommendations"] = generate_recommendations(results)
return results
def analyze_room(room: str, direction: str) -> Dict:
"""分析特殊房間的風水"""
direction = normalize_direction(direction)
# 廚房規則
kitchen_rules = {
"東": {"status": "吉", "effect": "木火通明,家人得貴人扶持"},
"東南": {"status": "吉", "effect": "木火通明,有助家庭和諧"},
"北": {"status": "中吉", "effect": "水火既濟,家人平安"},
"東北": {"status": "中吉", "effect": "火土相生"},
"南": {"status": "小吉", "effect": "火氣較旺,家人易急躁"},
"西南": {"status": "凶", "effect": "裡鬼門,午後西曬不利食物保存,家人多病"},
"西北": {"status": "凶", "effect": "火燒天門,不利男主人健康(呼吸系統、大腸)"},
"西": {"status": "凶", "effect": "火金相剋,運氣反覆"},
}
# 廁所規則
toilet_rules = {
"中央": {"status": "大凶", "effect": "中宮穢氣,嚴重影響全家健康"},
"東北": {"status": "大凶", "effect": "鬼門位,陰暗潮濕,家人體弱多病"},
"西南": {"status": "凶", "effect": "傷女主人,脾胃不佳、婦科問題"},
"西北": {"status": "凶", "effect": "傷男主人,事業及健康受損"},
"東": {"status": "中", "effect": "水木相生,需保持通風"},
"東南": {"status": "中", "effect": "水木相生,需保持通風"},
"南": {"status": "凶", "effect": "水火相沖,易生是非疾病"},
"北": {"status": "中", "effect": "坎位屬水,尚可"},
"西": {"status": "中", "effect": "金水相生,尚可"},
}
if "廚房" in room or "kitchen" in room.lower():
rules = kitchen_rules
elif "廁所" in room or "浴室" in room or "toilet" in room.lower() or "bathroom" in room.lower():
rules = toilet_rules
else:
return {"room": room, "direction": direction, "status": "未知", "effect": "無特殊規則"}
rule = rules.get(direction, {"status": "未知", "effect": "無對應規則"})
return {"room": room, "direction": direction, **rule}
def generate_recommendations(results: Dict) -> list:
"""根據分析結果生成建議"""
recommendations = []
# 檢查成員錯位
misplaced = [a for a in results["family_analysis"] if not a.get("is_native_position") and "error" not in a]
if len(misplaced) >= 2:
# 檢查是否可以互換
for i, p1 in enumerate(misplaced):
for p2 in misplaced[i+1:]:
if p1["actual_direction"] == p2["ideal_direction"] and p2["actual_direction"] == p1["ideal_direction"]:
recommendations.append(
f"建議 {p1['member']} 與 {p2['member']} 對調房間,可同時恢復「名位相等」"
)
# 房間問題建議
for room in results["room_analysis"]:
if room.get("status") == "大凶":
recommendations.append(
f"{room['room']}位置為大忌,若無法搬遷,需加強通風並保持門常關"
)
elif room.get("status") == "凶":
recommendations.append(
f"{room['room']}方位不理想,可透過減少該區域使用頻率或加強通風來緩解"
)
return recommendations
def main():
parser = argparse.ArgumentParser(description="易經陽宅風水卦象計算")
parser.add_argument("--person", help="人的屬卦(乾兌離震巽坎艮坤)")
parser.add_argument("--position", help="所住位置的卦")
parser.add_argument("--analyze", action="store_true", help="完整分析模式")
parser.add_argument("--family", help="家庭成員 JSON,如 '{\"父親\": \"東\", \"長子\": \"西北\"}'")
parser.add_argument("--rooms", help="房間位置 JSON,如 '{\"廚房\": \"西北\", \"廁所\": \"中央\"}'")
args = parser.parse_args()
if args.person and args.position:
# 單一卦象查詢
result = get_hexagram(args.person, args.position)
print(json.dumps(result, ensure_ascii=False, indent=2))
elif args.analyze and args.family:
# 完整分析模式
family = json.loads(args.family)
rooms = json.loads(args.rooms) if args.rooms else None
result = analyze_family(family, rooms)
print(json.dumps(result, ensure_ascii=False, indent=2))
else:
parser.print_help()
print("\n範例:")
print(" python fengshui_calc.py --person 震 --position 乾")
print(" python fengshui_calc.py --analyze --family '{\"父親\": \"東\", \"長子\": \"西北\"}' --rooms '{\"廚房\": \"西北\"}'")
if __name__ == "__main__":
main()
// ===== Config =====
const ROOM_MIN_SIZE = 60;
const ROOM_DEFAULT_SIZE = 100;
const PERSON_SIZE = 32;
const HANDLE_SIZE = 10;
const COLORS = {
room: { fill: 'rgba(159, 74, 223, 0.3)', stroke: '#9f4adf' },
facility: { fill: 'rgba(223, 159, 74, 0.3)', stroke: '#df9f4a' },
bedroom: { fill: 'rgba(74, 159, 223, 0.2)', stroke: '#4a9fdf' }
};
// ===== State =====
let rooms = [];
let persons = [];
let selectedRoom = null;
let selectedPerson = null;
let dragMode = null; // 'move', 'resize', 'rotate', 'move-person'
let dragStart = { x: 0, y: 0 };
let originalState = null;
let compassRotation = 0; // in degrees, 0 = north up
// ===== Canvas Setup =====
const canvas = document.getElementById('floorCanvas');
const ctx = canvas.getContext('2d');
function resizeCanvas() {
const rect = canvas.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;
draw();
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
// ===== Utility =====
function isBedroom(value) {
return value.includes('臥室') || value === '主臥室';
}
function getDirection(x, y, w, h) {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const objCenterX = x + w / 2;
const objCenterY = y + h / 2;
const dx = objCenterX - centerX;
const dy = objCenterY - centerY;
const threshold = 50;
if (Math.abs(dx) < threshold && Math.abs(dy) < threshold) return '中央';
// Calculate angle and adjust for compass rotation
let angle = Math.atan2(-dy, dx) * 180 / Math.PI;
angle = angle - compassRotation; // Adjust for compass rotation
// Normalize angle to -180 to 180
while (angle > 180) angle -= 360;
while (angle < -180) angle += 360;
if (angle >= -22.5 && angle < 22.5) return '東';
if (angle >= 22.5 && angle < 67.5) return '東北';
if (angle >= 67.5 && angle < 112.5) return '北';
if (angle >= 112.5 && angle < 157.5) return '西北';
if (angle >= 157.5 || angle < -157.5) return '西';
if (angle >= -157.5 && angle < -112.5) return '西南';
if (angle >= -112.5 && angle < -67.5) return '南';
if (angle >= -67.5 && angle < -22.5) return '東南';
return '中央';
}
function isInsideRoom(px, py, room) {
// Simple rectangle check (ignoring rotation for now)
return px >= room.x && px <= room.x + room.w &&
py >= room.y && py <= room.y + room.h;
}
function findBedroomAt(x, y) {
for (let i = rooms.length - 1; i >= 0; i--) {
if (isBedroom(rooms[i].value) && isInsideRoom(x, y, rooms[i])) {
return rooms[i];
}
}
return null;
}
// ===== Drawing =====
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Center crosshair
ctx.strokeStyle = 'rgba(201, 162, 39, 0.3)';
ctx.setLineDash([5, 5]);
ctx.beginPath();
ctx.moveTo(canvas.width / 2, 0);
ctx.lineTo(canvas.width / 2, canvas.height);
ctx.moveTo(0, canvas.height / 2);
ctx.lineTo(canvas.width, canvas.height / 2);
ctx.stroke();
ctx.setLineDash([]);
// Draw rooms
rooms.forEach((room, idx) => {
ctx.save();
const cx = room.x + room.w / 2;
const cy = room.y + room.h / 2;
ctx.translate(cx, cy);
ctx.rotate(room.rotation || 0);
ctx.translate(-cx, -cy);
const colors = isBedroom(room.value) ? COLORS.bedroom :
(room.type === 'room' ? COLORS.room : COLORS.facility);
// Fill
ctx.fillStyle = colors.fill;
ctx.fillRect(room.x, room.y, room.w, room.h);
// Border
ctx.strokeStyle = selectedRoom === idx ? '#fff' : colors.stroke;
ctx.lineWidth = selectedRoom === idx ? 3 : 2;
ctx.strokeRect(room.x, room.y, room.w, room.h);
// Icon & Label
ctx.fillStyle = '#fff';
ctx.font = '20px Arial';
ctx.textAlign = 'center';
ctx.fillText(room.icon, cx, cy - 5);
ctx.font = 'bold 11px Arial';
ctx.fillText(room.value, cx, cy + 15);
// Direction
const dir = getDirection(room.x, room.y, room.w, room.h);
ctx.fillStyle = 'rgba(201, 162, 39, 0.9)';
ctx.font = '9px Arial';
ctx.fillText(dir, cx, room.y + room.h - 5);
ctx.restore();
// Resize handle (when selected)
if (selectedRoom === idx) {
ctx.fillStyle = '#fff';
ctx.fillRect(room.x + room.w - HANDLE_SIZE, room.y + room.h - HANDLE_SIZE, HANDLE_SIZE, HANDLE_SIZE);
// Rotate handle
ctx.beginPath();
ctx.arc(room.x + room.w / 2, room.y - 15, 6, 0, Math.PI * 2);
ctx.fillStyle = '#c9a227';
ctx.fill();
}
});
// Draw persons (positioned relative to their bedroom)
persons.forEach((person, idx) => {
const bedroom = rooms[person.bedroomId];
if (!bedroom) return;
// Calculate position from bedroom center + offset
const px = bedroom.x + bedroom.w / 2 + (person.offsetX || 0);
const py = bedroom.y + bedroom.h / 2 + (person.offsetY || 0);
ctx.font = '22px Arial';
ctx.textAlign = 'center';
ctx.fillText(person.icon, px, py);
ctx.font = 'bold 9px Arial';
ctx.fillStyle = selectedPerson === idx ? '#fff' : '#4a9fdf';
ctx.fillText(person.value, px, py + 16);
});
}
// ===== Toolbox: Drag & Click =====
function addItemToCanvas(type, value, icon, targetX, targetY) {
if (type === 'person') {
// Check if dropped on a bedroom
const bedroom = findBedroomAt(targetX, targetY);
if (bedroom) {
const bedroomIdx = rooms.indexOf(bedroom);
// Remove existing person with same value
persons = persons.filter(p => p.value !== value);
// Store as offset from bedroom center (fixed position)
const personsInRoom = persons.filter(p => p.bedroomId === bedroomIdx).length;
const offsetX = (personsInRoom % 2) * 30 - 15;
const offsetY = Math.floor(personsInRoom / 2) * 25;
persons.push({
value,
icon,
bedroomId: bedroomIdx,
offsetX: offsetX,
offsetY: offsetY
});
} else {
showToast('⚠️ 家人只能放入臥室!');
return false;
}
} else {
// Room or facility - random position if no target
const x = targetX || (100 + Math.random() * (canvas.width - 300));
const y = targetY || (100 + Math.random() * (canvas.height - 300));
rooms.push({
type,
value,
icon,
x: x - ROOM_DEFAULT_SIZE / 2,
y: y - ROOM_DEFAULT_SIZE / 2,
w: ROOM_DEFAULT_SIZE,
h: ROOM_DEFAULT_SIZE,
rotation: 0
});
}
return true;
}
let isDraggingFromToolbox = false;
document.querySelectorAll('.tool-item').forEach(item => {
// Drag start
item.addEventListener('dragstart', (e) => {
isDraggingFromToolbox = true;
e.dataTransfer.setData('type', item.dataset.type);
e.dataTransfer.setData('value', item.dataset.value);
e.dataTransfer.setData('icon', item.dataset.icon);
});
item.addEventListener('dragend', () => {
// Reset after a short delay to allow drop to complete
setTimeout(() => { isDraggingFromToolbox = false; }, 100);
});
// Click to spawn (only if not dragging)
item.addEventListener('click', (e) => {
// Skip if this was a drag action
if (isDraggingFromToolbox) {
isDraggingFromToolbox = false;
return;
}
const type = item.dataset.type;
const value = item.dataset.value;
const icon = item.dataset.icon;
if (type === 'person') {
// Person needs a bedroom first
const bedrooms = rooms.filter(r => isBedroom(r.value));
if (bedrooms.length === 0) {
showToast('請先放置臥室!');
return;
}
// Find a bedroom without this person
let targetBedroom = bedrooms.find(b => {
const idx = rooms.indexOf(b);
return !persons.some(p => p.bedroomId === idx && p.value === value);
});
if (!targetBedroom) targetBedroom = bedrooms[0];
const cx = targetBedroom.x + targetBedroom.w / 2;
const cy = targetBedroom.y + targetBedroom.h / 2;
addItemToCanvas(type, value, icon, cx, cy);
} else {
// Random position for rooms/facilities
addItemToCanvas(type, value, icon, null, null);
}
draw();
updateConfigList();
});
});
canvas.addEventListener('dragover', (e) => e.preventDefault());
canvas.addEventListener('drop', (e) => {
e.preventDefault();
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const type = e.dataTransfer.getData('type');
const value = e.dataTransfer.getData('value');
const icon = e.dataTransfer.getData('icon');
addItemToCanvas(type, value, icon, x, y);
draw();
updateConfigList();
});
// ===== Canvas Mouse Events =====
canvas.addEventListener('mousedown', (e) => {
const rect = canvas.getBoundingClientRect();
const mx = e.clientX - rect.left;
const my = e.clientY - rect.top;
// Check persons first (calculate their actual position)
for (let i = persons.length - 1; i >= 0; i--) {
const p = persons[i];
const bedroom = rooms[p.bedroomId];
if (!bedroom) continue;
const px = bedroom.x + bedroom.w / 2 + (p.offsetX || 0);
const py = bedroom.y + bedroom.h / 2 + (p.offsetY || 0);
if (Math.abs(mx - px) < PERSON_SIZE / 2 && Math.abs(my - py) < PERSON_SIZE / 2) {
selectedPerson = i;
selectedRoom = null;
dragMode = 'move-person';
dragStart = { x: mx, y: my };
originalState = { bedroomId: p.bedroomId, offsetX: p.offsetX, offsetY: p.offsetY };
draw();
return;
}
}
// Check rooms
for (let i = rooms.length - 1; i >= 0; i--) {
const r = rooms[i];
// Resize handle
if (selectedRoom === i) {
if (mx >= r.x + r.w - HANDLE_SIZE && mx <= r.x + r.w &&
my >= r.y + r.h - HANDLE_SIZE && my <= r.y + r.h) {
dragMode = 'resize';
dragStart = { x: mx, y: my };
originalState = { w: r.w, h: r.h };
return;
}
// Rotate handle
const rotateX = r.x + r.w / 2;
const rotateY = r.y - 15;
if (Math.sqrt((mx - rotateX) ** 2 + (my - rotateY) ** 2) < 10) {
dragMode = 'rotate';
dragStart = { x: mx, y: my };
originalState = { rotation: r.rotation || 0 };
return;
}
}
// Room body
if (mx >= r.x && mx <= r.x + r.w && my >= r.y && my <= r.y + r.h) {
selectedRoom = i;
selectedPerson = null;
dragMode = 'move-room';
dragStart = { x: mx - r.x, y: my - r.y };
draw();
return;
}
}
selectedRoom = null;
selectedPerson = null;
draw();
});
canvas.addEventListener('mousemove', (e) => {
if (!dragMode) return;
const rect = canvas.getBoundingClientRect();
const mx = e.clientX - rect.left;
const my = e.clientY - rect.top;
if (dragMode === 'move-room' && selectedRoom !== null) {
rooms[selectedRoom].x = mx - dragStart.x;
rooms[selectedRoom].y = my - dragStart.y;
} else if (dragMode === 'resize' && selectedRoom !== null) {
const dx = mx - dragStart.x;
const dy = my - dragStart.y;
rooms[selectedRoom].w = Math.max(ROOM_MIN_SIZE, originalState.w + dx);
rooms[selectedRoom].h = Math.max(ROOM_MIN_SIZE, originalState.h + dy);
} else if (dragMode === 'rotate' && selectedRoom !== null) {
const r = rooms[selectedRoom];
const cx = r.x + r.w / 2;
const cy = r.y + r.h / 2;
const angle = Math.atan2(my - cy, mx - cx);
rooms[selectedRoom].rotation = angle + Math.PI / 2;
} else if (dragMode === 'move-person' && selectedPerson !== null) {
// Update offset relative to current bedroom
const p = persons[selectedPerson];
const bedroom = rooms[p.bedroomId];
if (bedroom) {
p.offsetX = mx - (bedroom.x + bedroom.w / 2);
p.offsetY = my - (bedroom.y + bedroom.h / 2);
}
}
draw();
updateConfigList();
});
canvas.addEventListener('mouseup', (e) => {
if (dragMode === 'move-person' && selectedPerson !== null) {
const p = persons[selectedPerson];
const bedroom = rooms[p.bedroomId];
if (bedroom) {
const px = bedroom.x + bedroom.w / 2 + (p.offsetX || 0);
const py = bedroom.y + bedroom.h / 2 + (p.offsetY || 0);
const newBedroom = findBedroomAt(px, py);
if (!newBedroom) {
// Bounce back to original position
p.bedroomId = originalState.bedroomId;
p.offsetX = originalState.offsetX;
p.offsetY = originalState.offsetY;
showToast('⚠️ 家人必須在臥室內!');
} else if (newBedroom !== bedroom) {
// Moved to a different bedroom
p.bedroomId = rooms.indexOf(newBedroom);
p.offsetX = px - (newBedroom.x + newBedroom.w / 2);
p.offsetY = py - (newBedroom.y + newBedroom.h / 2);
}
}
draw();
updateConfigList();
}
dragMode = null;
originalState = null;
});
canvas.addEventListener('dblclick', (e) => {
const rect = canvas.getBoundingClientRect();
const mx = e.clientX - rect.left;
const my = e.clientY - rect.top;
// Check persons (calculate actual position)
for (let i = persons.length - 1; i >= 0; i--) {
const p = persons[i];
const bedroom = rooms[p.bedroomId];
if (!bedroom) continue;
const px = bedroom.x + bedroom.w / 2 + (p.offsetX || 0);
const py = bedroom.y + bedroom.h / 2 + (p.offsetY || 0);
if (Math.abs(mx - px) < PERSON_SIZE / 2 && Math.abs(my - py) < PERSON_SIZE / 2) {
persons.splice(i, 1);
selectedPerson = null;
draw();
updateConfigList();
return;
}
}
// Check rooms
for (let i = rooms.length - 1; i >= 0; i--) {
const r = rooms[i];
if (mx >= r.x && mx <= r.x + r.w && my >= r.y && my <= r.y + r.h) {
// Remove persons in this room too
persons = persons.filter(p => p.bedroomId !== i);
rooms.splice(i, 1);
selectedRoom = null;
draw();
updateConfigList();
return;
}
}
});
// ===== Toast =====
function showToast(msg) {
const toast = document.createElement('div');
toast.textContent = msg;
toast.className = 'toast-msg';
toast.style.cssText = `
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
background: #1b2838;
color: #fbbf24;
padding: 10px 20px;
border-radius: 8px;
border: 1px solid #fbbf24;
z-index: 9999;
animation: fadeOut 2s forwards;
`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 2000);
}
// ===== Config List =====
function updateConfigList() {
const list = document.getElementById('configList');
if (rooms.length === 0 && persons.length === 0) {
list.innerHTML = `<p style="color: var(--text-muted); font-size: 0.75rem;">
1. 先拖拉房間到平面圖<br>
2. 再將家人放入臥室
</p>`;
return;
}
let html = '';
rooms.forEach(r => {
const dir = getDirection(r.x, r.y, r.w, r.h);
html += `<div class="config-item">
<span>${r.icon} ${r.value}</span>
<span class="dir">${dir}</span>
</div>`;
});
persons.forEach(p => {
const bedroom = rooms[p.bedroomId];
const dir = bedroom ? getDirection(bedroom.x, bedroom.y, bedroom.w, bedroom.h) : '?';
html += `<div class="config-item" style="border-left: 2px solid #4a9fdf;">
<span>${p.icon} ${p.value}</span>
<span class="dir">${dir}</span>
</div>`;
});
list.innerHTML = html;
}
// ===== Clear =====
document.getElementById('clearCanvas').addEventListener('click', () => {
rooms = [];
persons = [];
selectedRoom = null;
selectedPerson = null;
draw();
updateConfigList();
document.getElementById('promptOutput').classList.remove('show');
document.getElementById('copyBtn').classList.remove('show');
});
// ===== Generate Prompt =====
document.getElementById('generateBtn').addEventListener('click', () => {
if (rooms.length === 0) {
showToast('請先放置至少一個房間');
return;
}
const family = [];
const roomsData = [];
// Collect Family Data
persons.forEach(p => {
const bedroom = rooms[p.bedroomId];
if (bedroom) {
const dir = getDirection(bedroom.x, bedroom.y, bedroom.w, bedroom.h);
family.push({ member: p.value, dir: dir });
}
});
// Collect Rooms Data
rooms.forEach(r => {
if (!isBedroom(r.value)) {
const dir = getDirection(r.x, r.y, r.w, r.h);
roomsData.push({ room: r.value, dir: dir });
}
});
let prompt = `請幫我分析住宅風水:\n\n`;
if (family.length > 0) {
prompt += `【家庭成員臥室位置】\n`;
family.forEach(item => {
prompt += `- ${item.member}:${item.dir}\n`;
});
prompt += '\n';
}
if (roomsData.length > 0) {
prompt += `【房間/設施位置】\n`;
roomsData.forEach(item => {
prompt += `- ${item.room}:${item.dir}\n`;
});
prompt += '\n';
}
prompt += `請根據易經陽宅風水理論分析:
1. 各成員的卦象與吉凶
2. 房間位置的風水影響
3. 改善建議
(使用 yijing-fengshui Skill)`;
const output = document.getElementById('promptOutput');
const copyBtn = document.getElementById('copyBtn');
output.textContent = prompt;
output.classList.add('show');
copyBtn.classList.add('show');
});
// ===== Copy =====
document.getElementById('copyBtn').addEventListener('click', () => {
const text = document.getElementById('promptOutput').textContent;
navigator.clipboard.writeText(text).then(() => {
const btn = document.getElementById('copyBtn');
btn.textContent = '✅ 已複製!';
btn.style.background = 'var(--success)';
btn.style.color = 'var(--bg-dark)';
setTimeout(() => {
btn.textContent = '📋 複製 Prompt';
btn.style.background = 'transparent';
btn.style.color = 'var(--success)';
}, 2000);
});
});
// ===== Compass Rotation =====
const compass = document.getElementById('compass');
const compassInner = document.getElementById('compassInner');
let isRotatingCompass = false;
let compassStartAngle = 0;
compass.addEventListener('mousedown', (e) => {
isRotatingCompass = true;
const rect = compass.getBoundingClientRect();
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
compassStartAngle = Math.atan2(e.clientY - cy, e.clientX - cx) * 180 / Math.PI - compassRotation;
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (!isRotatingCompass) return;
const rect = compass.getBoundingClientRect();
const cx = rect.left + rect.width / 2;
const cy = rect.top + rect.height / 2;
const currentAngle = Math.atan2(e.clientY - cy, e.clientX - cx) * 180 / Math.PI;
compassRotation = currentAngle - compassStartAngle;
// Update visual rotation
compassInner.style.transform = `rotate(${compassRotation}deg)`;
// Redraw to update directions
draw();
updateConfigList();
});
document.addEventListener('mouseup', () => {
isRotatingCompass = false;
});
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>易經陽宅風水 - 平面圖建構器</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<header>
<h1>🏠 易經陽宅風水 - 平面圖建構器</h1>
<p class="subtitle">拖拉房間建構平面圖,再將家人放入臥室</p>
</header>
<div class="main-layout">
<!-- Toolbox -->
<div class="toolbox">
<h3>👨👩👧👦 家庭成員</h3>
<div class="tool-item person" draggable="true" data-type="person" data-value="父親" data-icon="👴">
<span class="icon">👴</span> 父親
</div>
<div class="tool-item person" draggable="true" data-type="person" data-value="母親" data-icon="👵">
<span class="icon">👵</span> 母親
</div>
<div class="tool-item person" draggable="true" data-type="person" data-value="長子" data-icon="👦">
<span class="icon">👦</span> 長子
</div>
<div class="tool-item person" draggable="true" data-type="person" data-value="長女" data-icon="👧">
<span class="icon">👧</span> 長女
</div>
<div class="tool-item person" draggable="true" data-type="person" data-value="次子" data-icon="👦">
<span class="icon">👦</span> 次子
</div>
<div class="tool-item person" draggable="true" data-type="person" data-value="次女" data-icon="👧">
<span class="icon">👧</span> 次女
</div>
<div class="tool-item person" draggable="true" data-type="person" data-value="少子" data-icon="👶">
<span class="icon">👶</span> 少子
</div>
<div class="tool-item person" draggable="true" data-type="person" data-value="少女" data-icon="👶">
<span class="icon">👶</span> 少女
</div>
<h3>🛏️ 房間</h3>
<div class="tool-item room" draggable="true" data-type="room" data-value="主臥室" data-icon="🛏️">
<span class="icon">🛏️</span> 主臥室
</div>
<div class="tool-item room" draggable="true" data-type="room" data-value="臥室" data-icon="🛏️">
<span class="icon">🛏️</span> 臥室
</div>
<div class="tool-item room" draggable="true" data-type="room" data-value="客廳" data-icon="🛋️">
<span class="icon">🛋️</span> 客廳
</div>
<div class="tool-item room" draggable="true" data-type="room" data-value="餐廳" data-icon="🍽️">
<span class="icon">🍽️</span> 餐廳
</div>
<div class="tool-item room" draggable="true" data-type="room" data-value="書房" data-icon="📚">
<span class="icon">📚</span> 書房
</div>
<div class="tool-item room" draggable="true" data-type="room" data-value="儲藏室" data-icon="📦">
<span class="icon">📦</span> 儲藏室
</div>
<h3>🔧 設施</h3>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="廚房" data-icon="🍳">
<span class="icon">🍳</span> 廚房
</div>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="廁所" data-icon="🚽">
<span class="icon">🚽</span> 廁所
</div>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="浴室" data-icon="🛁">
<span class="icon">🛁</span> 浴室
</div>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="大門" data-icon="🚪">
<span class="icon">🚪</span> 大門
</div>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="陽台" data-icon="🌿">
<span class="icon">🌿</span> 陽台
</div>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="玄關" data-icon="🚶">
<span class="icon">🚶</span> 玄關
</div>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="車庫" data-icon="🚗">
<span class="icon">🚗</span> 車庫
</div>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="樓梯" data-icon="🪜">
<span class="icon">🪜</span> 樓梯
</div>
<div class="tool-item facility" draggable="true" data-type="facility" data-value="神明廳" data-icon="🙏">
<span class="icon">🙏</span> 神明廳
</div>
</div>
<!-- Canvas -->
<div class="canvas-wrapper">
<div class="canvas-header">
<h3>📐 平面圖(上方為北)</h3>
<div class="canvas-actions">
<button id="clearCanvas">🗑️ 清除全部</button>
</div>
</div>
<canvas id="floorCanvas"></canvas>
<div class="compass" id="compass">
<span class="compass-hint">拖拉旋轉</span>
<div class="compass-inner" id="compassInner">
<span class="compass-n">北</span>
<span class="compass-s">南</span>
<span class="compass-e">東</span>
<span class="compass-w">西</span>
</div>
</div>
</div>
<!-- Output Panel -->
<div class="output-panel">
<h3>📋 配置清單</h3>
<div class="config-list" id="configList">
<p style="color: var(--text-muted); font-size: 0.75rem;">
1. 先拖拉房間到平面圖<br>
2. 再將家人放入臥室
</p>
</div>
<button class="generate-btn" id="generateBtn">✨ 生成 AI 分析 Prompt</button>
<div class="prompt-output" id="promptOutput"></div>
<button class="copy-btn" id="copyBtn">📋 複製 Prompt</button>
<div class="hint">
<strong>操作說明:</strong><br>
• 拖拉邊角可縮放房間<br>
• 拖拉旋轉鈕可旋轉<br>
• 雙擊可刪除<br>
• 家人只能放入臥室
</div>
</div>
</div>
<footer>
<p>基於倪海廈老師易經陽宅學說 | <a href="https://github.com/Wolke/yijing-fengshui" target="_blank">GitHub</a></p>
</footer>
</div>
<script src="app.js" defer></script>
</body>
</html>:root {
--primary: #1a5f7a;
--secondary: #c9a227;
--bg-dark: #0d1b2a;
--bg-card: #1b2838;
--text: #e8e8e8;
--text-muted: #8892a0;
--success: #4ade80;
--warning: #fbbf24;
--danger: #f87171;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Noto Sans TC', -apple-system, sans-serif;
background: linear-gradient(135deg, var(--bg-dark) 0%, #1b2838 100%);
color: var(--text);
min-height: 100vh;
user-select: none;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 15px;
}
header {
text-align: center;
padding: 15px 0;
}
header h1 {
font-size: 1.8rem;
background: linear-gradient(90deg, var(--secondary), #f0d78c);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.subtitle {
color: var(--text-muted);
font-size: 0.9rem;
}
.main-layout {
display: grid;
grid-template-columns: 180px 1fr 260px;
gap: 15px;
margin-top: 15px;
}
/* Toolbox */
.toolbox {
background: var(--bg-card);
border-radius: 10px;
padding: 12px;
max-height: 600px;
overflow-y: auto;
}
.toolbox h3 {
color: var(--secondary);
font-size: 0.8rem;
margin: 12px 0 8px 0;
padding-bottom: 5px;
border-bottom: 1px solid #3a4a5a;
}
.toolbox h3:first-child {
margin-top: 0;
}
.tool-item {
display: flex;
align-items: center;
gap: 6px;
padding: 8px;
margin-bottom: 5px;
background: #243447;
border-radius: 6px;
cursor: grab;
transition: all 0.2s;
font-size: 0.8rem;
}
.tool-item:hover {
background: #2d4a5f;
transform: translateX(2px);
}
.tool-item .icon {
font-size: 1.1rem;
}
.tool-item.person {
border-left: 3px solid #4a9fdf;
background: linear-gradient(90deg, rgba(74, 159, 223, 0.1), transparent);
}
.tool-item.room {
border-left: 3px solid #9f4adf;
}
.tool-item.facility {
border-left: 3px solid #df9f4a;
}
/* Canvas Area */
.canvas-wrapper {
background: var(--bg-card);
border-radius: 10px;
padding: 12px;
position: relative;
}
.canvas-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.canvas-header h3 {
color: var(--secondary);
font-size: 0.85rem;
}
.canvas-actions button {
padding: 5px 10px;
margin-left: 6px;
border: 1px solid #3a4a5a;
border-radius: 5px;
background: transparent;
color: var(--text);
cursor: pointer;
font-size: 0.75rem;
}
.canvas-actions button:hover {
border-color: var(--secondary);
}
#floorCanvas {
width: 100%;
height: 550px;
background:
linear-gradient(rgba(255, 255, 255, 0.02) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.02) 1px, transparent 1px),
#0a1218;
background-size: 20px 20px;
border-radius: 8px;
cursor: default;
}
.compass {
position: absolute;
top: 50px;
right: 22px;
width: 80px;
height: 80px;
background: rgba(0, 0, 0, 0.7);
border-radius: 50%;
border: 2px solid #5a6a7a;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.7rem;
color: var(--text-muted);
cursor: grab;
transition: border-color 0.2s;
user-select: none;
}
.compass:hover {
border-color: var(--secondary);
}
.compass:active {
cursor: grabbing;
}
.compass-inner {
position: relative;
width: 100%;
height: 100%;
transition: transform 0.1s ease-out;
}
.compass-n {
position: absolute;
top: 8px;
left: 50%;
transform: translateX(-50%);
color: var(--danger);
font-weight: bold;
font-size: 0.9rem;
}
.compass-s {
position: absolute;
bottom: 8px;
left: 50%;
transform: translateX(-50%);
color: var(--secondary);
}
.compass-e {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
}
.compass-w {
position: absolute;
left: 8px;
top: 50%;
transform: translateY(-50%);
}
.compass-hint {
position: absolute;
top: -18px;
left: 50%;
transform: translateX(-50%);
font-size: 0.6rem;
color: var(--text-muted);
white-space: nowrap;
}
/* Output Panel */
.output-panel {
background: var(--bg-card);
border-radius: 10px;
padding: 12px;
display: flex;
flex-direction: column;
}
.output-panel h3 {
color: var(--secondary);
font-size: 0.85rem;
margin-bottom: 8px;
}
.config-list {
flex: 1;
overflow-y: auto;
margin-bottom: 12px;
max-height: 250px;
}
.config-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 6px 8px;
background: #243447;
border-radius: 5px;
margin-bottom: 4px;
font-size: 0.8rem;
}
.config-item .dir {
color: var(--secondary);
font-weight: bold;
}
.generate-btn {
padding: 10px;
border: none;
border-radius: 6px;
background: linear-gradient(90deg, var(--primary), #2d8eb4);
color: white;
font-size: 0.9rem;
cursor: pointer;
transition: all 0.2s;
}
.generate-btn:hover {
transform: translateY(-1px);
box-shadow: 0 3px 12px rgba(26, 95, 122, 0.4);
}
.prompt-output {
margin-top: 10px;
padding: 10px;
background: #0d1520;
border-radius: 6px;
font-size: 0.7rem;
max-height: 150px;
overflow-y: auto;
white-space: pre-wrap;
display: none;
}
.prompt-output.show {
display: block;
}
.copy-btn {
margin-top: 8px;
padding: 8px;
border: 2px solid var(--success);
border-radius: 6px;
background: transparent;
color: var(--success);
cursor: pointer;
font-size: 0.8rem;
display: none;
}
.copy-btn.show {
display: block;
}
.copy-btn:hover {
background: var(--success);
color: var(--bg-dark);
}
.hint {
margin-top: 10px;
padding: 8px;
background: rgba(201, 162, 39, 0.1);
border-radius: 6px;
font-size: 0.7rem;
color: var(--text-muted);
line-height: 1.5;
}
footer {
text-align: center;
padding: 15px;
color: var(--text-muted);
font-size: 0.8rem;
}
footer a {
color: var(--primary);
text-decoration: none;
}
/* Animations */
@keyframes bounceBack {
0% {
transform: scale(1);
}
50% {
transform: scale(0.8);
}
100% {
transform: scale(1);
}
}
.bounce-back {
animation: bounceBack 0.3s ease;
}
@keyframes fadeOut {
0% {
opacity: 1;
}
70% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@media (max-width: 1000px) {
.main-layout {
grid-template-columns: 1fr;
}
.toolbox {
display: flex;
flex-wrap: wrap;
gap: 5px;
max-height: none;
}
.toolbox h3 {
width: 100%;
margin: 8px 0 5px 0;
}
.tool-item {
margin-bottom: 0;
}
}