// File: /workspace/github_cpp_makefile_star2_O3/wrighteagle2d[P]wrighteaglebase/Debug/../src/InterceptModel.cpp
// Function: InterceptModel::CalcTangPoint(double, double, double, double, double, InterceptModel::InterceptSolution*)
int InterceptModel::CalcTangPoint(double x0, double y0, double vp, double ka,
                                  double cd, InterceptSolution *sol) {
  static const double MINERROR = 0.01;

  const double &alpha = ServerParam::instance().ballDecay();
  const double &ln_alpha = ServerParam::instance().logBallDecay();

  double s, p, alpha_p, f, dfdx, last_f = 1000.0, x;
  int iteration_cycle = 0;

  if (fabs(y0) < FLOAT_EPS) {
    sol->tangc = 0;
    return 0; //没有切点
  }

  x = x0;
  do {
    iteration_cycle += 1;
    if (iteration_cycle > 10) {
      break;
    }
    s = Sqrt((x - x0) * (x - x0) + y0 * y0);
    p = (s - ka) / vp - cd;
    if (p < 0.0)
      p = 0.0;
    alpha_p = pow(alpha, (p));
    f = 1.0 - alpha_p * (1 - x * (x - x0) * ln_alpha / (s * vp));

    if (fabs(f) > fabs(last_f)) {
      sol->tangc = 0;
      return 0; //没有切点
    } else {
      last_f = f;
    }

    dfdx =
        ln_alpha / vp *
        ((x - x0) * (f - 1.0) / s +
         alpha_p * ((x + x - x0) / s - x * (x - x0) * (x - x0) / (s * s * s)));
    dfdx = fabs(dfdx) < FLOAT_EPS ? (Sign(dfdx) * FLOAT_EPS) : dfdx;
    x = x - f / dfdx;
  } while (fabs(f) > MINERROR);

  sol->tangp[0] = x;

  s = Sqrt((x - x0) * (x - x0) + y0 * y0);
  p = (s - ka) / vp - cd;
  if (p < 0.0)
    p = 0.0;
  alpha_p = pow(alpha, (p));
  if (1.0 - alpha_p < FLOAT_EPS) { //表示自己到那里几乎不花时间
    sol->tangv[0] = 1000.0;
    sol->tangc = 1;
    return 1;
  } else {
    sol->tangv[0] = x * (1.0 - alpha) / (1.0 - alpha_p);
  }

  x += 0.5; //检测是否只有一个切点
  s = Sqrt((x - x0) * (x - x0) + y0 * y0);
  p = (s - ka) / vp - cd;
  if (p < 0.0)
    p = 0.0;
  alpha_p = pow(alpha, p);
  f = 1.0 - alpha_p * (1 - x * (x - x0) * ln_alpha / (s * vp));
  if (f > 0.0) {
    sol->tangc = 1;
    return 1; //只有一个切点
  } else {
    do {
      x += 15.0;
      s = Sqrt((x - x0) * (x - x0) + y0 * y0);
      p = (s - ka) / vp - cd;
      if (p < 0.0)
        p = 0.0;
      alpha_p = pow(alpha, p);
      f = 1.0 - alpha_p * (1 - x * (x - x0) * ln_alpha / (s * vp));
    } while (f < 0.0);
    dfdx =
        ln_alpha / vp *
        ((x - x0) * (f - 1.0) / s +
         alpha_p * ((x + x - x0) / s - x * (x - x0) * (x - x0) / (s * s * s)));
    dfdx = fabs(dfdx) < FLOAT_EPS ? (Sign(dfdx) * FLOAT_EPS) : dfdx;
    x = x - f / dfdx;

    iteration_cycle = 0;
    while (fabs(f) > MINERROR) {
      iteration_cycle += 1;
      if (iteration_cycle > 10) {
        break;
      }
      s = Sqrt((x - x0) * (x - x0) + y0 * y0);
      p = (s - ka) / vp - cd;
      if (p < 0.0)
        p = 0.0;
      alpha_p = pow(alpha, p);
      f = 1.0 - alpha_p * (1 - x * (x - x0) * ln_alpha / (s * vp));
      dfdx = ln_alpha / vp *
             ((x - x0) * (f - 1.0) / s +
              alpha_p *
                  ((x + x - x0) / s - x * (x - x0) * (x - x0) / (s * s * s)));
      dfdx = fabs(dfdx) < FLOAT_EPS ? (Sign(dfdx) * FLOAT_EPS) : dfdx;
      x = x - f / dfdx;
    }

    sol->tangp[1] = x;
    s = Sqrt((x - x0) * (x - x0) + y0 * y0);
    p = (s - ka) / vp - cd;
    if (p < 0.0)
      p = 0.0;
    alpha_p = pow(alpha, p);
    if (1.0 - alpha_p < FLOAT_EPS) {
      sol->tangv[1] = 1000.0;
    } else {
      sol->tangv[1] = x * (1.0 - alpha) / (1.0 - alpha_p);
    }
    sol->tangc = 2;
    return 2; //有两个切点
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rsi, %rbx
movsd %xmm4, -0x40(%rbp)
movsd %xmm3, -0x38(%rbp)
movsd %xmm2, -0x58(%rbp)
movaps %xmm1, -0x80(%rbp)
movsd %xmm0, -0x50(%rbp)
callq 0x49360
movq %rax, %r14
callq 0x49360
movapd -0x80(%rbp), %xmm1
movapd 0x3d302(%rip), %xmm0    # 0x69010
andpd %xmm1, %xmm0
xorl %r12d, %r12d
movsd 0x3d323(%rip), %xmm2    # 0x69040
ucomisd %xmm0, %xmm2
ja 0x2c3eb
movq %rax, %r15
movq %rbx, -0x88(%rbp)
mulsd %xmm1, %xmm1
movsd 0x3ea8b(%rip), %xmm0    # 0x6a7c8
movl $0xb, %ebx
leaq 0x3e867(%rip), %r13     # 0x6a5b0
movsd -0x50(%rbp), %xmm3
movapd %xmm3, %xmm9
movsd -0x40(%rbp), %xmm2
movsd -0x58(%rbp), %xmm8
movapd %xmm1, -0x80(%rbp)
decl %ebx
je 0x2beff
movapd %xmm9, %xmm4
subsd %xmm3, %xmm4
movsd %xmm4, -0x48(%rbp)
movapd %xmm0, -0x70(%rbp)
movapd %xmm4, %xmm0
mulsd %xmm4, %xmm0
addsd %xmm1, %xmm0
sqrtsd %xmm0, %xmm0
movsd %xmm0, -0x90(%rbp)
subsd -0x38(%rbp), %xmm0
divsd %xmm8, %xmm0
subsd %xmm2, %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
movsd %xmm9, -0x30(%rbp)
callq 0x98a0
movsd -0x90(%rbp), %xmm11
movsd -0x48(%rbp), %xmm7
movsd -0x30(%rbp), %xmm9
movsd -0x58(%rbp), %xmm8
movsd 0x3d276(%rip), %xmm5    # 0x69058
movapd %xmm9, %xmm4
mulsd %xmm7, %xmm4
movsd 0x3468(%r15), %xmm3
movapd %xmm4, %xmm1
mulsd %xmm3, %xmm1
movapd %xmm11, %xmm2
mulsd %xmm8, %xmm2
divsd %xmm2, %xmm1
movapd %xmm5, %xmm2
subsd %xmm1, %xmm2
mulsd %xmm0, %xmm2
movapd %xmm5, %xmm1
subsd %xmm2, %xmm1
movapd %xmm1, %xmm2
movapd 0x3d1e6(%rip), %xmm5    # 0x69010
andpd %xmm5, %xmm2
movapd -0x70(%rbp), %xmm6
andpd %xmm5, %xmm6
ucomisd %xmm6, %xmm2
ja 0x2c1cc
movapd %xmm1, %xmm5
addsd 0x3d24b(%rip), %xmm5    # 0x69098
mulsd %xmm7, %xmm5
divsd %xmm11, %xmm5
movapd %xmm9, %xmm6
addsd %xmm9, %xmm6
movsd -0x50(%rbp), %xmm10
subsd %xmm10, %xmm6
divsd %xmm11, %xmm6
mulsd %xmm7, %xmm4
movapd %xmm11, %xmm7
mulsd %xmm11, %xmm7
mulsd %xmm11, %xmm7
divsd %xmm7, %xmm4
subsd %xmm4, %xmm6
mulsd %xmm6, %xmm0
divsd %xmm8, %xmm3
addsd %xmm5, %xmm0
mulsd %xmm3, %xmm0
xorl %eax, %eax
ucomisd 0x3d1ea(%rip), %xmm0    # 0x69090
setae %al
movapd %xmm0, %xmm3
andpd 0x3d15b(%rip), %xmm3    # 0x69010
movsd (%r13,%rax,8), %xmm4
cmpltsd 0x3d17b(%rip), %xmm3    # 0x69040
andpd %xmm3, %xmm4
andnpd %xmm0, %xmm3
orpd %xmm4, %xmm3
movapd %xmm1, %xmm0
divsd %xmm3, %xmm0
subsd %xmm0, %xmm9
ucomisd 0x3d85a(%rip), %xmm2    # 0x69740
movapd %xmm1, %xmm0
movsd -0x40(%rbp), %xmm2
movapd -0x80(%rbp), %xmm1
movapd %xmm10, %xmm3
ja 0x2bd63
movsd %xmm9, -0x30(%rbp)
movq -0x88(%rbp), %rbx
movsd %xmm9, 0x8(%rbx)
movapd %xmm9, %xmm0
subsd %xmm3, %xmm0
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
sqrtsd %xmm0, %xmm0
subsd -0x38(%rbp), %xmm0
divsd %xmm8, %xmm0
subsd %xmm2, %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd 0x3d105(%rip), %xmm2    # 0x69058
movapd %xmm2, %xmm1
subsd %xmm0, %xmm1
movsd 0x3d0dd(%rip), %xmm0    # 0x69040
ucomisd %xmm1, %xmm0
jbe 0x2bf81
movl $0x1, %r12d
movsd 0x3e851(%rip), %xmm0    # 0x6a7c8
movl $0x18, %eax
jmp 0x2c3e6
movapd %xmm2, %xmm0
subsd 0x30e0(%r14), %xmm0
movsd -0x30(%rbp), %xmm2
mulsd %xmm2, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rbx)
addsd 0x3d8d0(%rip), %xmm2    # 0x69878
movsd %xmm2, -0x30(%rbp)
movapd %xmm2, %xmm0
subsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
sqrtsd %xmm0, %xmm0
movsd %xmm0, -0x48(%rbp)
subsd -0x38(%rbp), %xmm0
divsd -0x58(%rbp), %xmm0
subsd -0x40(%rbp), %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd 0x3d05e(%rip), %xmm2    # 0x69058
movsd -0x30(%rbp), %xmm9
movsd -0x70(%rbp), %xmm1
mulsd %xmm9, %xmm1
mulsd 0x3468(%r15), %xmm1
movsd -0x58(%rbp), %xmm7
movsd -0x48(%rbp), %xmm3
mulsd %xmm7, %xmm3
divsd %xmm3, %xmm1
movapd %xmm1, %xmm3
movapd %xmm2, %xmm1
subsd %xmm3, %xmm1
mulsd %xmm0, %xmm1
movapd %xmm2, %xmm0
subsd %xmm1, %xmm0
movl $0x1, %r12d
ucomisd 0x3d045(%rip), %xmm0    # 0x69090
ja 0x2c3eb
addsd 0x3d6fe(%rip), %xmm9    # 0x69758
movsd %xmm9, -0x30(%rbp)
movapd %xmm9, %xmm0
subsd -0x50(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
xorps %xmm2, %xmm2
sqrtsd %xmm0, %xmm2
movsd %xmm2, -0x48(%rbp)
subsd -0x38(%rbp), %xmm2
divsd %xmm7, %xmm2
subsd -0x40(%rbp), %xmm2
xorpd %xmm1, %xmm1
movsd 0x30e0(%r14), %xmm0
maxsd %xmm2, %xmm1
callq 0x98a0
movsd -0x48(%rbp), %xmm10
movsd -0x70(%rbp), %xmm6
movsd -0x30(%rbp), %xmm9
movsd -0x58(%rbp), %xmm7
movsd 0x3cf92(%rip), %xmm5    # 0x69058
movapd %xmm9, %xmm3
mulsd %xmm6, %xmm3
movsd 0x3468(%r15), %xmm2
movapd %xmm3, %xmm1
mulsd %xmm2, %xmm1
movapd %xmm10, %xmm4
mulsd %xmm7, %xmm4
divsd %xmm4, %xmm1
movapd %xmm5, %xmm4
subsd %xmm1, %xmm4
mulsd %xmm0, %xmm4
movapd %xmm5, %xmm1
subsd %xmm4, %xmm1
xorpd %xmm4, %xmm4
ucomisd %xmm1, %xmm4
ja 0x2c051
divsd %xmm7, %xmm2
movsd 0x3cf7d(%rip), %xmm4    # 0x69098
addsd %xmm1, %xmm4
mulsd %xmm6, %xmm4
divsd %xmm10, %xmm4
movapd %xmm9, %xmm5
addsd %xmm9, %xmm5
movsd -0x50(%rbp), %xmm8
subsd %xmm8, %xmm5
divsd %xmm10, %xmm5
mulsd %xmm6, %xmm3
movapd %xmm10, %xmm6
mulsd %xmm10, %xmm6
mulsd %xmm10, %xmm6
divsd %xmm6, %xmm3
subsd %xmm3, %xmm5
mulsd %xmm5, %xmm0
addsd %xmm4, %xmm0
mulsd %xmm2, %xmm0
xorpd %xmm2, %xmm2
xorl %eax, %eax
ucomisd %xmm2, %xmm0
setae %al
movapd %xmm0, %xmm2
movapd 0x3ce8e(%rip), %xmm4    # 0x69010
andpd %xmm4, %xmm2
movsd (%r13,%rax,8), %xmm3
cmpltsd 0x3ceaa(%rip), %xmm2    # 0x69040
andpd %xmm2, %xmm3
andnpd %xmm0, %xmm2
orpd %xmm3, %xmm2
movapd %xmm1, %xmm0
divsd %xmm2, %xmm0
subsd %xmm0, %xmm9
andpd %xmm4, %xmm1
ucomisd 0x3d585(%rip), %xmm1    # 0x69740
ja 0x2c1d8
movsd -0x40(%rbp), %xmm1
movsd -0x38(%rbp), %xmm2
jmp 0x2c350
movq -0x88(%rbp), %rbx
jmp 0x2c3eb
xorl %ebx, %ebx
movsd -0x40(%rbp), %xmm1
movsd -0x38(%rbp), %xmm2
movsd %xmm9, -0x30(%rbp)
movapd %xmm9, %xmm0
subsd %xmm8, %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
sqrtsd %xmm0, %xmm0
movsd %xmm0, -0x48(%rbp)
subsd %xmm2, %xmm0
divsd %xmm7, %xmm0
subsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd -0x30(%rbp), %xmm9
movsd -0x50(%rbp), %xmm8
movsd -0x58(%rbp), %xmm7
movapd %xmm9, %xmm4
movsd -0x70(%rbp), %xmm6
mulsd %xmm6, %xmm4
movsd 0x3468(%r15), %xmm2
movapd %xmm4, %xmm1
mulsd %xmm2, %xmm1
movsd -0x48(%rbp), %xmm10
movapd %xmm10, %xmm3
mulsd %xmm7, %xmm3
divsd %xmm3, %xmm1
movsd 0x3cde0(%rip), %xmm5    # 0x69058
movapd %xmm5, %xmm3
subsd %xmm1, %xmm3
mulsd %xmm0, %xmm3
movapd %xmm5, %xmm1
subsd %xmm3, %xmm1
movapd %xmm1, %xmm5
addsd 0x3ce00(%rip), %xmm5    # 0x69098
mulsd %xmm6, %xmm5
divsd %xmm10, %xmm5
movapd %xmm9, %xmm3
addsd %xmm9, %xmm3
subsd %xmm8, %xmm3
divsd %xmm10, %xmm3
mulsd %xmm6, %xmm4
movapd %xmm10, %xmm6
mulsd %xmm10, %xmm6
mulsd %xmm10, %xmm6
divsd %xmm6, %xmm4
subsd %xmm4, %xmm3
mulsd %xmm0, %xmm3
divsd %xmm7, %xmm2
addsd %xmm5, %xmm3
mulsd %xmm2, %xmm3
xorl %eax, %eax
ucomisd 0x3cda6(%rip), %xmm3    # 0x69090
setae %al
movapd %xmm3, %xmm0
movapd 0x3cd17(%rip), %xmm4    # 0x69010
andpd %xmm4, %xmm0
movsd (%r13,%rax,8), %xmm2
cmpltsd 0x3cd33(%rip), %xmm0    # 0x69040
andpd %xmm0, %xmm2
andnpd %xmm3, %xmm0
orpd %xmm2, %xmm0
movapd %xmm1, %xmm2
divsd %xmm0, %xmm2
subsd %xmm2, %xmm9
andpd %xmm4, %xmm1
ucomisd 0x3d40e(%rip), %xmm1    # 0x69740
jbe 0x2c1bd
leal 0x1(%rbx), %eax
cmpl $0x9, %ebx
movl %eax, %ebx
movsd -0x40(%rbp), %xmm1
movsd -0x38(%rbp), %xmm2
jb 0x2c1e4
movsd %xmm9, -0x30(%rbp)
movq -0x88(%rbp), %rbx
movsd %xmm9, 0x10(%rbx)
movapd %xmm9, %xmm0
subsd %xmm8, %xmm0
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
sqrtsd %xmm0, %xmm0
subsd %xmm2, %xmm0
divsd %xmm7, %xmm0
subsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd 0x3ccb4(%rip), %xmm2    # 0x69058
movapd %xmm2, %xmm1
subsd %xmm0, %xmm1
subsd 0x30e0(%r14), %xmm2
mulsd -0x30(%rbp), %xmm2
divsd %xmm1, %xmm2
cmpltsd 0x3cc79(%rip), %xmm1    # 0x69040
movsd 0x3e3f9(%rip), %xmm0    # 0x6a7c8
andpd %xmm1, %xmm0
andnpd %xmm2, %xmm1
orpd %xmm1, %xmm0
movl $0x2, %r12d
movl $0x20, %eax
movsd %xmm0, (%rbx,%rax)
movl %r12d, (%rbx)
movl %r12d, %eax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq