getTimeFromAngle static method
已知位置反求时间,对于节气计算,应满足t在t1到t1+360天之间,对于Y年第n个节气(n=0是春分),t1可取值Y365.2422+n15.2, 对于朔望计算,应满足t在t1到t1+25天之间,在此范围之外,求右边的根
@param t1 J2000起算儒略日数,传入的t1是指定角度对应真时刻t的前一些天 @param angle 已知角度(jiao)求时间(t) @param lx lx=0是太阳黄经达某角度的时刻计算(用于节气计算) lx=1是日月角距达某角度的时刻计算(用于定朔望等) @return 已知位置反求时间
Implementation
static double getTimeFromAngle(double t1, double angle, int lx) {
double t2 = t1, t = 0, v;
if (lx == 0)
t2 += 360; // 在t1到t2范围内求解(范气360天范围),结果置于t
else
t2 += 25;
angle *= pi / 180; // 待搜索目标角
// 利用截弦法计算
double v1 = angleDiff(lx, t1, angle); // v1,v2为t1,t2时对应的黄经
double v2 = angleDiff(lx, t2, angle);
if (v1 < v2) v2 -= 2 * pi; // 减2pi作用是将周期性角度转为连续角度
double k = 1, k2; // k是截弦的斜率
for (int i = 0; i < 10; i++) {
// 快速截弦求根,通常截弦三四次就已达所需精度
k2 = (v2 - v1) / (t2 - t1); // 算出斜率
if (Math.abs(k2) > 1e-15) k = k2; // 差商可能为零,应排除
t = t1 - v1 / k;
v = angleDiff(lx, t, angle); // 直线逼近法求根(直线方程的根)
if (v > 1) v -= 2 * pi; // 一次逼近后,v1就已接近0,如果很大,则应减1周
if (Math.abs(v) < 1e-8) break; // 已达精度
t1 = t2;
v1 = v2;
t2 = t;
v2 = v; // 下一次截弦
}
return t;
}