getStartIndex function
起紫微星诀算法
- 六五四三二,酉午亥辰丑,
- 局数除日数,商数宫前走;
- 若见数无余,便要起虎口,
- 日数小於局,还直宫中守。
举例:
- 例一:27日出生木三局,以三除27,循环0次就可以整除,27➗3=9,从寅进9格,在戍安紫微。
- 例二:13日出生火六局,以六除13,最少需要加5才能整除, 18➗8=3,从寅进3格为辰,添加数为5(奇数),故要逆回五宫,在亥安紫微。
- 例三:6日出生土五局,以五除6,最少需要加4才能整除,10➗5=2,从寅进2格为卯,添加数为4(偶数),顺行4格为未,在未安紫微。
@param solarDateStr 公历日期 YYYY-MM-DD @param timeIndex 时辰索引【0~12】 @param fixLeap 是否调整农历闰月(若该月不是闰月则不会生效) @returns 紫微和天府星所在宫位索引
Implementation
Map<String, int> getStartIndex(AstrolabeParams params) {
var soulAndBody = getSoulAndBody(params);
HeavenlyStemName heavenlyStemOfSoul = soulAndBody.heavenlyStenName;
EarthlyBranchName earthlyBranchOfSoul = soulAndBody.earthlyBranchName;
int lunarDay = solar2Lunar(params.solarDate).lunarDay;
/// 如果已传入干支,则用传入干支起五行局
/// 确定用于起五行局的地盘干支
final baseHeavenlyStem = params.from?.heavenlyStem ?? heavenlyStemOfSoul;
final baseEarthlyBranch = params.from?.earthlyBranch ?? earthlyBranchOfSoul;
FiveElementsFormat fiveElements = getFiveElementClass(
baseHeavenlyStem,
baseEarthlyBranch,
);
int remainder = -1; // 余数
int quotient; // 商
int offset = -1; // 循环次数
// 获取当月最大天数
int maxDays = getTotalDaysOfLunarMonth(params.solarDate);
// 如果timeIndex等于12说明是晚子时,需要加一天
int day = params.timeIndex == 12 ? lunarDay + 1 : lunarDay;
if (day > maxDays) {
// 假如日期超过当月最大天数,说明跨月了,需要处理为合法日期
day -= maxDays;
}
do {
// 农历出生日(初一为1,以此类推)加上偏移量作为除数,以这个数处以五行局的数向下取整
// 需要一直运算到余数为0为止
offset++;
int divisor = day + offset;
quotient = (divisor ~/ fiveElements.value).floor();
remainder = divisor % fiveElements.value;
} while (remainder != 0);
// 将商除以12取余数
quotient %= 12;
// 以商减一(因为需要从0开始)作为起始位置
int ziweiIndex = quotient - 1;
if (offset % 2 == 0) {
// 若循环次数为偶数,则索引逆时针数到循环数
ziweiIndex += offset;
} else {
// 若循环次数为偶数,则索引顺时针数到循环数
ziweiIndex -= offset;
}
ziweiIndex = fixIndex(ziweiIndex);
// 天府星位置与紫微星相对
int tianfuIndex = fixIndex(12 - ziweiIndex);
return {'ziweiIndex': ziweiIndex, 'tianfuIndex': tianfuIndex};
}