紫微斗数安星演算法:如何计算 108+ 颗星曜的位置

分类:程式设计 × 东方术数

紫微斗数的安星(Star Placement,安星),是指依照出生资料,计算每一颗星曜在十二宫中的位置。本文将从程式设计角度介绍完整紫微斗数 Engine 的核心演算法。


1. 十二宫资料结构(Data Structure,资料结构)

一张紫微斗数命盘由 十二宫 组成,通常排列成四行三列。

每一宫保存:

  • 宫位名称
  • 星曜列表
  • 天干、地支
  • 长生位置
const CUNG_ORDER = [
  '命宫', '兄弟', '夫妻', '子女',
  '财帛', '疾厄', '迁移', '仆役',
  '官禄', '田宅', '福德', '父母'
];

// 每一宫对应一个地支(子~亥),
// 并依命宫位置旋转整个命盘。

2. 第一步:计算局数(Cục Số)

局数(Configuration Number,局数)决定紫微星的安星方式。

局数共有五种:

  • 水二局
  • 木三局
  • 金四局
  • 土五局
  • 火六局

其计算依据:

  • 出生年天干
  • 农历月份
  • 命宫纳音五行

演算法如下:

function cucSo(amLichMonth, yearStem) {
  // Step 1:
  // 找出命宫干支的纳音五行

  // Step 2:
  // 五行对应局数

  const NH = napAmNguHanh;

  return {
    水:2,
    木:3,
    金:4,
    土:5,
    火:6
  }[NH];
}

3. 第二步:安紫微星

紫微星的位置取决于:

  • 农历生日
  • 局数

通常可表示为一个 30 × 5 Lookup Table(查找表)

// 简化后的概念

tuViPosition =
    (lunarDay - 1 + offset[cuc]) % 12;

const TV_TABLE = {

  2: [/* 水二局 30 笔 */],

  3: [/* 木三局 30 笔 */],

  4: [/* 金四局 30 笔 */],

  5: [/* 土五局 30 笔 */],

  6: [/* 火六局 30 笔 */]
};

不同局数会对应不同的查找表,因此同一天出生的人,在不同局数下,紫微星的位置也可能不同。


4. 第三步:安其他星曜

确定紫微星位置后,其余星曜便依各自规则配置。

十四主星

十四主星的位置通常以紫微星为基准,依固定规则配置。


六吉星

包括:

  • 文昌
  • 文曲
  • 左辅
  • 右弼
  • 天魁
  • 天钺

主要依据:

  • 出生年天干
  • 地支
  • 出生时辰

六煞星

包括:

  • 擎羊
  • 陀罗
  • 火星
  • 铃星
  • 天空
  • 地劫

主要依据:

  • 年干
  • 时支

四化(Four Transformations,四化)

包括:

  • 化禄
  • 化权
  • 化科
  • 化忌

通常使用:

十天干 × 四化

形成固定查找表,共约四十笔对应资料。


5. 演算法复杂度(Complexity Analysis,复杂度分析)

完整安星流程如下:

输入:

  • 出生年
  • 农历月
  • 农历日
  • 出生时辰
  • 性别

输出:

  • 十二宫
  • 约 108~115 颗星曜(依不同流派而异)

演算法特性:

  • 时间复杂度(Time Complexity,时间复杂度):O
  • 几乎全部采用 Lookup Table(查找表)完成
  • 不涉及大量数值运算

真正最耗时的部分并不是安星,而是:

西历 → 农历转换

此步骤通常需要依赖 VSOP87(行星位置模型) 等天文演算法计算节气、新月与农历月份。

在现代硬体上,

整个紫微斗数 Engine 通常可于 10 毫秒以内完成安星,实际执行时间多半消耗于介面绘制(Rendering,渲染)而非演算法本身。