getTimeFromAngle static method

double getTimeFromAngle(
  1. double t1,
  2. double angle,
  3. int lx
)

已知位置反求时间,对于节气计算,应满足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;
}