// File: /workspace/github_cpp_makefile_star2_O1/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, -0x50(%rbp)
movsd %xmm3, -0x48(%rbp)
movsd %xmm2, -0x30(%rbp)
movaps %xmm1, -0x80(%rbp)
movsd %xmm0, -0x40(%rbp)
callq 0x4a75c
movq %rax, %r14
callq 0x4a75c
movapd -0x80(%rbp), %xmm1
movapd 0x3e9a4(%rip), %xmm0    # 0x6b010
andpd %xmm1, %xmm0
xorl %r12d, %r12d
movsd 0x3e9c5(%rip), %xmm2    # 0x6b040
ucomisd %xmm0, %xmm2
ja 0x2cd96
movq %rax, %r15
movq %rbx, -0x88(%rbp)
mulsd %xmm1, %xmm1
movsd 0x4013d(%rip), %xmm0    # 0x6c7d8
movl $0xb, %ebx
xorpd %xmm5, %xmm5
leaq 0x3ff15(%rip), %r13     # 0x6c5c0
movsd -0x40(%rbp), %xmm10
movapd %xmm10, %xmm9
movsd -0x30(%rbp), %xmm8
movapd %xmm1, -0x80(%rbp)
decl %ebx
je 0x2c864
movapd %xmm0, -0x70(%rbp)
movapd %xmm9, -0x60(%rbp)
movapd %xmm9, %xmm0
subsd %xmm10, %xmm0
movsd %xmm0, -0x38(%rbp)
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
ucomisd %xmm5, %xmm0
jb 0x2c6f7
sqrtsd %xmm0, %xmm0
jmp 0x2c702
callq 0x93c0
movsd -0x30(%rbp), %xmm8
movsd %xmm0, -0x90(%rbp)
subsd -0x48(%rbp), %xmm0
divsd %xmm8, %xmm0
subsd -0x50(%rbp), %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd -0x90(%rbp), %xmm11
movsd -0x30(%rbp), %xmm8
movapd -0x60(%rbp), %xmm9
movapd %xmm9, %xmm4
movsd -0x38(%rbp), %xmm7
mulsd %xmm7, %xmm4
movsd 0x3468(%r15), %xmm3
movapd %xmm4, %xmm1
mulsd %xmm3, %xmm1
movapd %xmm11, %xmm2
mulsd %xmm8, %xmm2
divsd %xmm2, %xmm1
movsd 0x3e8df(%rip), %xmm5    # 0x6b058
movapd %xmm5, %xmm2
subsd %xmm1, %xmm2
mulsd %xmm0, %xmm2
movapd %xmm5, %xmm1
subsd %xmm2, %xmm1
movapd %xmm1, %xmm2
movapd 0x3e877(%rip), %xmm5    # 0x6b010
andpd %xmm5, %xmm2
movapd -0x70(%rbp), %xmm6
andpd %xmm5, %xmm6
ucomisd %xmm6, %xmm2
ja 0x2c952
movapd %xmm1, %xmm5
addsd 0x3e8dc(%rip), %xmm5    # 0x6b098
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
xorpd %xmm5, %xmm5
ucomisd %xmm5, %xmm0
setae %al
movapd %xmm0, %xmm3
andpd 0x3e7ec(%rip), %xmm3    # 0x6b010
movsd (%r13,%rax,8), %xmm4
cmpltsd 0x3e80c(%rip), %xmm3    # 0x6b040
andpd %xmm3, %xmm4
andnpd %xmm0, %xmm3
orpd %xmm4, %xmm3
movapd %xmm1, %xmm0
divsd %xmm3, %xmm0
subsd %xmm0, %xmm9
ucomisd 0x3eeeb(%rip), %xmm2    # 0x6b740
movapd %xmm1, %xmm0
movapd -0x80(%rbp), %xmm1
ja 0x2c6c1
movq -0x88(%rbp), %rbx
movsd %xmm9, 0x8(%rbx)
movapd %xmm9, -0x60(%rbp)
movapd %xmm9, %xmm0
subsd %xmm10, %xmm0
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2c899
sqrtsd %xmm0, %xmm0
jmp 0x2c8a8
callq 0x93c0
xorpd %xmm1, %xmm1
movsd -0x30(%rbp), %xmm8
subsd -0x48(%rbp), %xmm0
divsd %xmm8, %xmm0
subsd -0x50(%rbp), %xmm0
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd 0x3e787(%rip), %xmm2    # 0x6b058
movapd %xmm2, %xmm1
subsd %xmm0, %xmm1
movsd 0x3e75f(%rip), %xmm0    # 0x6b040
ucomisd %xmm1, %xmm0
jbe 0x2c8ff
movl $0x1, %r12d
movsd 0x3fee3(%rip), %xmm0    # 0x6c7d8
movl $0x18, %eax
jmp 0x2cd91
movapd %xmm2, %xmm0
subsd 0x30e0(%r14), %xmm0
movapd -0x60(%rbp), %xmm2
mulsd %xmm2, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rbx)
addsd 0x3ef52(%rip), %xmm2    # 0x6b878
movapd %xmm2, -0x60(%rbp)
movapd %xmm2, %xmm0
subsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0x2c95e
sqrtsd %xmm0, %xmm0
jmp 0x2c963
movq -0x88(%rbp), %rbx
jmp 0x2cd96
callq 0x93c0
movsd -0x30(%rbp), %xmm1
movsd %xmm0, -0x38(%rbp)
subsd -0x48(%rbp), %xmm0
divsd %xmm1, %xmm0
subsd -0x50(%rbp), %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd -0x30(%rbp), %xmm7
movapd -0x60(%rbp), %xmm8
movsd -0x70(%rbp), %xmm3
mulsd %xmm8, %xmm3
mulsd 0x3468(%r15), %xmm3
movsd -0x38(%rbp), %xmm1
mulsd %xmm7, %xmm1
divsd %xmm1, %xmm3
movsd 0x3e694(%rip), %xmm2    # 0x6b058
movapd %xmm2, %xmm1
subsd %xmm3, %xmm1
mulsd %xmm0, %xmm1
movapd %xmm2, %xmm0
subsd %xmm1, %xmm0
movl $0x1, %r12d
ucomisd 0x3e6aa(%rip), %xmm0    # 0x6b090
ja 0x2cd96
xorpd %xmm4, %xmm4
addsd 0x3ed5f(%rip), %xmm8    # 0x6b758
movapd %xmm8, -0x60(%rbp)
movapd %xmm8, %xmm0
subsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
ucomisd %xmm4, %xmm0
jb 0x2ca23
sqrtsd %xmm0, %xmm0
jmp 0x2ca2d
callq 0x93c0
movsd -0x30(%rbp), %xmm7
movsd %xmm0, -0x38(%rbp)
subsd -0x48(%rbp), %xmm0
divsd %xmm7, %xmm0
subsd -0x50(%rbp), %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd -0x38(%rbp), %xmm10
movsd -0x30(%rbp), %xmm7
movapd -0x60(%rbp), %xmm8
movapd %xmm8, %xmm3
movsd -0x70(%rbp), %xmm6
mulsd %xmm6, %xmm3
movsd 0x3468(%r15), %xmm2
movapd %xmm3, %xmm1
mulsd %xmm2, %xmm1
movapd %xmm10, %xmm4
mulsd %xmm7, %xmm4
divsd %xmm4, %xmm1
movsd 0x3e5bd(%rip), %xmm5    # 0x6b058
movapd %xmm5, %xmm4
subsd %xmm1, %xmm4
mulsd %xmm0, %xmm4
movapd %xmm5, %xmm1
subsd %xmm4, %xmm1
xorpd %xmm4, %xmm4
ucomisd %xmm1, %xmm4
ja 0x2c9f0
divsd %xmm7, %xmm2
movsd 0x3e5cf(%rip), %xmm4    # 0x6b098
addsd %xmm1, %xmm4
mulsd %xmm6, %xmm4
divsd %xmm10, %xmm4
movapd %xmm8, %xmm5
addsd %xmm8, %xmm5
movsd -0x40(%rbp), %xmm9
subsd %xmm9, %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 %xmm5, %xmm5
xorl %eax, %eax
ucomisd %xmm5, %xmm0
setae %al
movapd %xmm0, %xmm2
movapd 0x3e4e0(%rip), %xmm4    # 0x6b010
andpd %xmm4, %xmm2
movsd (%r13,%rax,8), %xmm3
cmpltsd 0x3e4fc(%rip), %xmm2    # 0x6b040
andpd %xmm2, %xmm3
andnpd %xmm0, %xmm2
orpd %xmm3, %xmm2
movapd %xmm1, %xmm0
divsd %xmm2, %xmm0
subsd %xmm0, %xmm8
andpd %xmm4, %xmm1
ucomisd 0x3ebd7(%rip), %xmm1    # 0x6b740
jbe 0x2cce3
xorl %ebx, %ebx
movapd %xmm8, -0x60(%rbp)
movapd %xmm8, %xmm0
subsd %xmm9, %xmm0
movsd %xmm0, -0x70(%rbp)
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
ucomisd %xmm5, %xmm0
jb 0x2cb9b
sqrtsd %xmm0, %xmm0
jmp 0x2cba5
callq 0x93c0
movsd -0x30(%rbp), %xmm7
movsd %xmm0, -0x38(%rbp)
subsd -0x48(%rbp), %xmm0
divsd %xmm7, %xmm0
subsd -0x50(%rbp), %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd -0x30(%rbp), %xmm7
movapd -0x60(%rbp), %xmm8
movapd %xmm8, %xmm4
movsd -0x70(%rbp), %xmm6
mulsd %xmm6, %xmm4
movsd 0x3468(%r15), %xmm2
movapd %xmm4, %xmm1
mulsd %xmm2, %xmm1
movsd -0x38(%rbp), %xmm10
movapd %xmm10, %xmm3
mulsd %xmm7, %xmm3
divsd %xmm3, %xmm1
movsd 0x3e445(%rip), %xmm5    # 0x6b058
movapd %xmm5, %xmm3
subsd %xmm1, %xmm3
mulsd %xmm0, %xmm3
movapd %xmm5, %xmm1
subsd %xmm3, %xmm1
movapd %xmm1, %xmm5
addsd 0x3e465(%rip), %xmm5    # 0x6b098
mulsd %xmm6, %xmm5
divsd %xmm10, %xmm5
movapd %xmm8, %xmm3
addsd %xmm8, %xmm3
movsd -0x40(%rbp), %xmm9
subsd %xmm9, %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
xorpd %xmm5, %xmm5
ucomisd %xmm5, %xmm3
setae %al
movapd %xmm3, %xmm0
movapd 0x3e376(%rip), %xmm4    # 0x6b010
andpd %xmm4, %xmm0
movsd (%r13,%rax,8), %xmm2
cmpltsd 0x3e392(%rip), %xmm0    # 0x6b040
andpd %xmm0, %xmm2
andnpd %xmm3, %xmm0
orpd %xmm2, %xmm0
movapd %xmm1, %xmm2
divsd %xmm0, %xmm2
subsd %xmm2, %xmm8
andpd %xmm4, %xmm1
ucomisd 0x3ea6d(%rip), %xmm1    # 0x6b740
jbe 0x2cce3
leal 0x1(%rbx), %eax
cmpl $0x9, %ebx
movl %eax, %ebx
jb 0x2cb71
movq -0x88(%rbp), %rbx
movsd %xmm8, 0x10(%rbx)
movapd %xmm8, -0x60(%rbp)
movapd %xmm8, %xmm0
subsd %xmm9, %xmm0
mulsd %xmm0, %xmm0
addsd -0x80(%rbp), %xmm0
ucomisd %xmm5, %xmm0
jb 0x2cd15
sqrtsd %xmm0, %xmm0
jmp 0x2cd1f
callq 0x93c0
movsd -0x30(%rbp), %xmm7
subsd -0x48(%rbp), %xmm0
divsd %xmm7, %xmm0
subsd -0x50(%rbp), %xmm0
xorpd %xmm1, %xmm1
maxsd %xmm0, %xmm1
movsd 0x30e0(%r14), %xmm0
callq 0x98a0
movsd 0x3e30d(%rip), %xmm3    # 0x6b058
movapd %xmm3, %xmm1
subsd %xmm0, %xmm1
subsd 0x30e0(%r14), %xmm3
movapd -0x60(%rbp), %xmm2
mulsd %xmm3, %xmm2
divsd %xmm1, %xmm2
cmpltsd 0x3e2ce(%rip), %xmm1    # 0x6b040
movsd 0x3fa5e(%rip), %xmm0    # 0x6c7d8
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
nop