// File: /workspace/github_cpp_makefile_star2_O2/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, -0x58(%rbp)
movsd %xmm3, -0x48(%rbp)
movsd %xmm2, -0x50(%rbp)
movaps %xmm1, -0x80(%rbp)
movsd %xmm0, -0x40(%rbp)
callq 0x3db2c
movq %rax, %r14
callq 0x3db2c
movapd -0x80(%rbp), %xmm1
movapd 0x3157e(%rip), %xmm0    # 0x57010
andpd %xmm1, %xmm0
xorl %r12d, %r12d
movsd 0x3159f(%rip), %xmm2    # 0x57040
ucomisd %xmm0, %xmm2
ja 0x260f8
movq %rax, %r15
movq %rbx, -0x88(%rbp)
mulsd %xmm1, %xmm1
movsd 0x32cd7(%rip), %xmm0    # 0x58798
pushq $0xb
popq %rbx
leaq 0x32aa5(%rip), %r13     # 0x58570
movsd -0x40(%rbp), %xmm3
movapd %xmm3, %xmm9
movsd -0x58(%rbp), %xmm2
movsd -0x50(%rbp), %xmm8
movapd %xmm1, -0x80(%rbp)
decl %ebx
je 0x25c81
movapd %xmm9, %xmm4
subsd %xmm3, %xmm4
movsd %xmm4, -0x38(%rbp)
movapd %xmm0, -0x70(%rbp)
movapd %xmm4, %xmm0
mulsd %xmm4, %xmm0
addsd %xmm1, %xmm0
sqrtsd %xmm0, %xmm0
movsd %xmm0, -0x90(%rbp)
subsd -0x48(%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 -0x38(%rbp), %xmm7
movsd -0x30(%rbp), %xmm9
movsd -0x50(%rbp), %xmm8
movsd 0x314e4(%rip), %xmm5    # 0x57048
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 0x31464(%rip), %xmm5    # 0x57010
andpd %xmm5, %xmm2
movapd -0x70(%rbp), %xmm6
andpd %xmm5, %xmm6
ucomisd %xmm6, %xmm2
ja 0x2605a
movapd %xmm1, %xmm5
addsd 0x314a1(%rip), %xmm5    # 0x57070
mulsd %xmm7, %xmm5
divsd %xmm11, %xmm5
movapd %xmm9, %xmm6
addsd %xmm9, %xmm6
movsd -0x40(%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 0x326b8(%rip), %xmm0    # 0x582e0
setae %al
movapd %xmm0, %xmm3
andpd 0x313d9(%rip), %xmm3    # 0x57010
movsd (%r13,%rax,8), %xmm4
cmpltsd 0x313f9(%rip), %xmm3    # 0x57040
andpd %xmm3, %xmm4
andnpd %xmm0, %xmm3
orpd %xmm4, %xmm3
movapd %xmm1, %xmm0
divsd %xmm3, %xmm0
subsd %xmm0, %xmm9
ucomisd 0x31ab0(%rip), %xmm2    # 0x57718
movapd %xmm1, %xmm0
movsd -0x58(%rbp), %xmm2
movapd -0x80(%rbp), %xmm1
movapd %xmm10, %xmm3
ja 0x25ae5
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 -0x48(%rbp), %xmm0
divsd %xmm8, %xmm0
subsd %xmm2, %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd 0x31373(%rip), %xmm2    # 0x57048
movapd %xmm2, %xmm1
subsd %xmm0, %xmm1
movsd 0x3135b(%rip), %xmm0    # 0x57040
ucomisd %xmm1, %xmm0
jbe 0x25cfe
pushq $0x1
popq %r12
movsd 0x32aa1(%rip), %xmm0    # 0x58798
pushq $0x18
jmp 0x260f2
movapd %xmm2, %xmm0
subsd 0x30e0(%r14), %xmm0
movsd -0x30(%rbp), %xmm2
mulsd %xmm2, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rbx)
addsd 0x31b23(%rip), %xmm2    # 0x57848
movsd %xmm2, -0x30(%rbp)
movapd %xmm2, %xmm0
subsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
sqrtsd %xmm0, %xmm0
movsd %xmm0, -0x38(%rbp)
subsd -0x48(%rbp), %xmm0
divsd -0x50(%rbp), %xmm0
subsd -0x58(%rbp), %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd 0x312d1(%rip), %xmm2    # 0x57048
movsd -0x30(%rbp), %xmm10
movsd -0x70(%rbp), %xmm1
mulsd %xmm10, %xmm1
mulsd 0x3468(%r15), %xmm1
movsd -0x50(%rbp), %xmm7
movsd -0x38(%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
ucomisd 0x3251e(%rip), %xmm0    # 0x582e0
jbe 0x25dcd
pushq $0x1
popq %r12
jmp 0x260f8
addsd 0x3197a(%rip), %xmm10   # 0x57750
movsd %xmm10, -0x30(%rbp)
movapd %xmm10, %xmm0
subsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
sqrtsd %xmm0, %xmm2
movsd %xmm2, -0x38(%rbp)
subsd -0x48(%rbp), %xmm2
divsd %xmm7, %xmm2
subsd -0x58(%rbp), %xmm2
xorpd %xmm1, %xmm1
movsd 0x30e0(%r14), %xmm0
maxsd %xmm2, %xmm1
callq 0x98a0
movsd -0x38(%rbp), %xmm8
movsd -0x70(%rbp), %xmm6
movsd -0x30(%rbp), %xmm10
movsd -0x50(%rbp), %xmm7
movapd %xmm10, %xmm3
mulsd %xmm6, %xmm3
movsd 0x3468(%r15), %xmm1
movapd %xmm3, %xmm2
mulsd %xmm1, %xmm2
movapd %xmm8, %xmm4
mulsd %xmm7, %xmm4
divsd %xmm4, %xmm2
movsd 0x311e2(%rip), %xmm5    # 0x57048
movapd %xmm5, %xmm4
subsd %xmm2, %xmm4
mulsd %xmm0, %xmm4
movapd %xmm5, %xmm2
subsd %xmm4, %xmm2
xorpd %xmm4, %xmm4
ucomisd %xmm2, %xmm4
ja 0x25dcd
divsd %xmm7, %xmm1
movsd 0x311dc(%rip), %xmm4    # 0x57070
addsd %xmm2, %xmm4
mulsd %xmm6, %xmm4
divsd %xmm8, %xmm4
movapd %xmm10, %xmm5
addsd %xmm10, %xmm5
movsd -0x40(%rbp), %xmm9
subsd %xmm9, %xmm5
divsd %xmm8, %xmm5
mulsd %xmm6, %xmm3
movapd %xmm8, %xmm6
mulsd %xmm8, %xmm6
mulsd %xmm8, %xmm6
divsd %xmm6, %xmm3
subsd %xmm3, %xmm5
mulsd %xmm5, %xmm0
addsd %xmm4, %xmm0
mulsd %xmm1, %xmm0
xorl %ebx, %ebx
movsd -0x48(%rbp), %xmm8
movapd %xmm0, %xmm1
movapd 0x3111a(%rip), %xmm4    # 0x57010
andpd %xmm4, %xmm1
xorl %eax, %eax
ucomisd 0x323dc(%rip), %xmm0    # 0x582e0
setae %al
movsd (%r13,%rax,8), %xmm3
cmpltsd 0x31129(%rip), %xmm1    # 0x57040
andpd %xmm1, %xmm3
andnpd %xmm0, %xmm1
orpd %xmm3, %xmm1
movapd %xmm2, %xmm0
divsd %xmm1, %xmm0
subsd %xmm0, %xmm10
andpd %xmm4, %xmm2
ucomisd 0x317dc(%rip), %xmm2    # 0x57718
movsd -0x58(%rbp), %xmm1
movsd %xmm10, -0x30(%rbp)
jbe 0x26066
cmpl $0x9, %ebx
ja 0x26066
incl %ebx
movapd %xmm10, %xmm0
subsd %xmm9, %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
sqrtsd %xmm0, %xmm0
movsd %xmm0, -0x38(%rbp)
subsd %xmm8, %xmm0
divsd %xmm7, %xmm0
subsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd -0x30(%rbp), %xmm10
movsd -0x40(%rbp), %xmm9
movsd -0x48(%rbp), %xmm8
movsd -0x50(%rbp), %xmm7
movapd %xmm0, %xmm1
movapd %xmm10, %xmm4
movsd -0x70(%rbp), %xmm6
mulsd %xmm6, %xmm4
movsd 0x3468(%r15), %xmm3
movapd %xmm4, %xmm0
mulsd %xmm3, %xmm0
movsd -0x38(%rbp), %xmm11
movapd %xmm11, %xmm2
mulsd %xmm7, %xmm2
divsd %xmm2, %xmm0
movsd 0x31057(%rip), %xmm2    # 0x57048
movapd %xmm2, %xmm5
subsd %xmm0, %xmm5
mulsd %xmm1, %xmm5
subsd %xmm5, %xmm2
divsd %xmm7, %xmm3
movapd %xmm2, %xmm5
addsd 0x3105f(%rip), %xmm5    # 0x57070
mulsd %xmm6, %xmm5
divsd %xmm11, %xmm5
movapd %xmm10, %xmm0
addsd %xmm10, %xmm0
subsd %xmm9, %xmm0
divsd %xmm11, %xmm0
mulsd %xmm6, %xmm4
movapd %xmm11, %xmm6
mulsd %xmm11, %xmm6
mulsd %xmm11, %xmm6
divsd %xmm6, %xmm4
subsd %xmm4, %xmm0
mulsd %xmm1, %xmm0
addsd %xmm5, %xmm0
mulsd %xmm3, %xmm0
jmp 0x25eea
movq -0x88(%rbp), %rbx
jmp 0x260f8
movq -0x88(%rbp), %rbx
movsd %xmm10, 0x10(%rbx)
movapd %xmm10, %xmm0
subsd %xmm9, %xmm0
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
sqrtsd %xmm0, %xmm0
subsd %xmm8, %xmm0
divsd %xmm7, %xmm0
subsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd 0x30f93(%rip), %xmm2    # 0x57048
movapd %xmm2, %xmm1
subsd %xmm0, %xmm1
subsd 0x30e0(%r14), %xmm2
mulsd -0x30(%rbp), %xmm2
divsd %xmm1, %xmm2
cmpltsd 0x30f68(%rip), %xmm1    # 0x57040
movsd 0x326b8(%rip), %xmm0    # 0x58798
andpd %xmm1, %xmm0
andnpd %xmm2, %xmm1
orpd %xmm1, %xmm0
pushq $0x2
popq %r12
pushq $0x20
popq %rax
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
nop