// File: /workspace/github_cpp_makefile_star2_O1/wrighteagle2d[P]wrighteaglebase/Debug/../src/InterceptModel.cpp
// Function: InterceptModel::CalcInterception(Vector const&, Vector const&, double, PlayerState const*, InterceptModel::InterceptSolution*)
void InterceptModel::CalcInterception(const Vector &ball_pos,
                                      const Vector &ball_vel,
                                      const double buffer,
                                      const PlayerState *player,
                                      InterceptSolution *sol) {
  const double &alpha = ServerParam::instance().ballDecay();
  const double &ln_alpha = ServerParam::instance().logBallDecay();

  Vector start_pt = (player->GetPos() - ball_pos).Rotate(-ball_vel.Dir());

  //取得模型输入
  const double x0 = start_pt.X();
  const double y0 = start_pt.Y();
  const double ball_spd = ball_vel.Mod();

  const double &player_spd = player->GetEffectiveSpeedMax();
  const double &kick_area = buffer;
  const double cycle_delay = double(player->GetPosDelay());

  const double max_x = ball_spd / (1.0 - alpha);

  //	if (Logger::instance().CurrentTime() == Time(205, 0) &&
  //player->GetUnum() == 4){ 		PlotInterceptCurve(x0, y0, ball_spd, player_spd,
  //kick_area, cycle_delay, max_x);
  //	}

  //特殊情况处理
  const double s = Sqrt(x0 * x0 + y0 * y0);
  const double self_fix = kick_area + cycle_delay * player_spd;

  if (s < self_fix) { //最好的情况已经可踢
    sol->tangc = 0;
    sol->interc = 1;
    sol->interp[0] = 0;
    sol->intert[0] = 0;
    return;
  }

  if (ball_spd < 0.1) {
    sol->tangc = 0;
    sol->interc = 1;
    sol->interp[0] = 0;

    double p = (s - kick_area) / player_spd - cycle_delay;
    if (p < 0.0)
      p = 0.0;
    sol->intert[0] = p;
    return;
  }

  //先判断切点个数 -- 根据切点个数得到解的个数，并依次选择迭代的初值
  int n = CalcTangPoint(x0, y0, player_spd, kick_area, cycle_delay, sol);

  if (n < 1) { //没有切点
    sol->interc = 1;

    sol->interp[0] = CalcInterPoint(max_x - 1.0, x0, y0, ball_spd, player_spd,
                                    kick_area, cycle_delay);
    sol->intert[0] =
        log(1.0 - sol->interp[0] * (1.0 - alpha) / ball_spd) / ln_alpha;
  } else if (n == 1) {
    /**
     * n = 1的情况对应只有一个切点，即外切的时候同时内切
     **/
    sol->interc = 1;

    if (x0 < 0.0) {
      sol->interp[0] = CalcInterPoint(max_x - 1.0, x0, y0, ball_spd, player_spd,
                                      kick_area, cycle_delay);
    } else {
      sol->interp[0] = CalcInterPoint(x0, x0, y0, ball_spd, player_spd,
                                      kick_area, cycle_delay);
    }

    sol->intert[0] =
        log(1.0 - sol->interp[0] * (1.0 - alpha) / ball_spd) / ln_alpha;
  } else {
    if (ball_spd < sol->tangv[1]) { //没有最佳截球区间，早期就可截
      sol->interc = 1;

      sol->interp[0] = CalcInterPoint(x0, x0, y0, ball_spd, player_spd,
                                      kick_area, cycle_delay);
      sol->intert[0] =
          log(1.0 - sol->interp[0] * (1.0 - alpha) / ball_spd) / ln_alpha;
    } else if (ball_spd < sol->tangv[0]) { //有最佳截球区间
      sol->interc = 3;

      sol->interp[0] = CalcInterPoint(x0, x0, y0, ball_spd, player_spd,
                                      kick_area, cycle_delay);
      sol->intert[0] =
          log(1.0 - sol->interp[0] * (1.0 - alpha) / ball_spd) / ln_alpha;

      sol->interp[1] =
          CalcInterPoint((sol->tangp[0] + sol->tangp[1]) * 0.5, x0, y0,
                         ball_spd, player_spd, kick_area, cycle_delay);
      sol->intert[1] =
          log(1.0 - sol->interp[1] * (1.0 - alpha) / ball_spd) / ln_alpha;

      sol->interp[2] =
          CalcInterPoint((sol->tangp[1] + max_x) * 0.5, x0, y0, ball_spd,
                         player_spd, kick_area, cycle_delay);
      sol->intert[2] =
          log(1.0 - sol->interp[2] * (1.0 - alpha) / ball_spd) / ln_alpha;
    } else { //没有最佳截球区间，只有后期才可截
      sol->interc = 1;

      sol->interp[0] = CalcInterPoint(max_x - 1.0, x0, y0, ball_spd, player_spd,
                                      kick_area, cycle_delay);
      sol->intert[0] =
          log(1.0 - sol->interp[0] * (1.0 - alpha) / ball_spd) / ln_alpha;
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %r8, -0x88(%rbp)
movq %rcx, %r12
movsd %xmm0, -0x48(%rbp)
movq %rdx, %r13
movq %rsi, %r14
callq 0x4a75c
movq %rax, %rbx
callq 0x4a75c
movq %rax, -0x68(%rbp)
movsd 0x8(%r12), %xmm1
movsd 0x10(%r12), %xmm0
subsd (%r14), %xmm1
movsd %xmm1, -0x60(%rbp)
subsd 0x8(%r14), %xmm0
movsd %xmm0, -0x38(%rbp)
movq %r13, %rdi
callq 0xe804
mulsd 0x3eeba(%rip), %xmm0    # 0x6b0a0
divsd 0x3ee5a(%rip), %xmm0    # 0x6b048
leaq -0x98(%rbp), %r14
leaq -0x90(%rbp), %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x92d0
movsd (%r14), %xmm0
movsd (%r15), %xmm1
movsd -0x60(%rbp), %xmm3
movapd %xmm3, %xmm2
mulsd %xmm0, %xmm3
movsd -0x38(%rbp), %xmm4
mulsd %xmm4, %xmm0
mulsd %xmm1, %xmm2
subsd %xmm0, %xmm2
movapd %xmm2, -0x60(%rbp)
mulsd %xmm1, %xmm4
addsd %xmm3, %xmm4
movsd %xmm4, -0x38(%rbp)
movsd (%r13), %xmm0
movsd 0x8(%r13), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jb 0x2c269
sqrtsd %xmm0, %xmm5
jmp 0x2c276
callq 0x93c0
xorpd %xmm2, %xmm2
movapd %xmm0, %xmm5
xorps %xmm4, %xmm4
cvtsi2sdl 0x18(%r12), %xmm4
movsd 0x3edd0(%rip), %xmm6    # 0x6b058
subsd 0x30e0(%rbx), %xmm6
movsd -0x38(%rbp), %xmm1
mulsd %xmm1, %xmm1
movapd -0x60(%rbp), %xmm0
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
ucomisd %xmm2, %xmm0
movq -0x88(%rbp), %r15
jb 0x2c2bc
xorps %xmm1, %xmm1
sqrtsd %xmm0, %xmm1
jmp 0x2c2e3
movsd %xmm5, -0x30(%rbp)
movsd %xmm4, -0x40(%rbp)
movsd %xmm6, -0x80(%rbp)
callq 0x93c0
movsd -0x80(%rbp), %xmm6
movsd -0x40(%rbp), %xmm4
movsd -0x30(%rbp), %xmm5
movapd %xmm0, %xmm1
movsd -0x48(%rbp), %xmm3
movsd 0x60(%r12), %xmm2
movapd %xmm4, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm3, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x2c31f
movabsq $0x100000000, %rax      # imm = 0x100000000
movq %rax, (%r15)
movq $0x0, 0x28(%r15)
xorpd %xmm0, %xmm0
jmp 0x2c60b
movsd 0x402a9(%rip), %xmm0    # 0x6c5d0
ucomisd %xmm5, %xmm0
jbe 0x2c35e
movabsq $0x100000000, %rax      # imm = 0x100000000
movq %rax, (%r15)
movq $0x0, 0x28(%r15)
subsd %xmm3, %xmm1
divsd 0x60(%r12), %xmm1
subsd %xmm4, %xmm1
xorpd %xmm0, %xmm0
maxsd %xmm1, %xmm0
jmp 0x2c60b
movsd %xmm5, -0x30(%rbp)
divsd %xmm6, %xmm5
movapd %xmm5, -0x80(%rbp)
movaps -0x60(%rbp), %xmm0
movsd -0x38(%rbp), %xmm1
movsd %xmm4, -0x40(%rbp)
movq %r15, %rsi
callq 0x2c626
cmpl $0x1, %eax
je 0x2c3ae
testl %eax, %eax
jne 0x2c3f7
movl $0x1, 0x4(%r15)
movapd -0x80(%rbp), %xmm0
addsd 0x3ecf8(%rip), %xmm0    # 0x6b098
movsd 0x60(%r12), %xmm4
movapd -0x60(%rbp), %xmm1
jmp 0x2c3e8
movapd -0x80(%rbp), %xmm3
addsd 0x3ecdd(%rip), %xmm3    # 0x6b098
movl $0x1, 0x4(%r15)
xorpd %xmm2, %xmm2
movapd -0x60(%rbp), %xmm1
movapd %xmm1, %xmm0
cmpltsd %xmm2, %xmm0
andpd %xmm0, %xmm3
andnpd %xmm1, %xmm0
orpd %xmm3, %xmm0
movsd 0x60(%r12), %xmm4
movsd -0x38(%rbp), %xmm2
movsd -0x30(%rbp), %xmm3
jmp 0x2c5c0
movsd 0x20(%r15), %xmm0
movsd -0x30(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0x2c429
movl $0x1, 0x4(%r15)
movapd %xmm1, %xmm3
movsd 0x60(%r12), %xmm4
movapd -0x60(%rbp), %xmm0
movapd %xmm0, %xmm1
jmp 0x2c5bb
movsd 0x18(%r15), %xmm0
ucomisd %xmm1, %xmm0
movapd %xmm1, %xmm3
jbe 0x2c59a
movl $0x3, 0x4(%r15)
movsd 0x60(%r12), %xmm4
movapd -0x60(%rbp), %xmm0
movapd %xmm0, %xmm1
movsd -0x38(%rbp), %xmm2
movsd -0x48(%rbp), %xmm5
movsd -0x40(%rbp), %xmm6
callq 0x2cdac
movsd %xmm0, 0x28(%r15)
movsd 0x3ebe1(%rip), %xmm2    # 0x6b058
movapd %xmm2, %xmm1
subsd 0x30e0(%rbx), %xmm1
mulsd %xmm0, %xmm1
divsd -0x30(%rbp), %xmm1
movapd %xmm2, %xmm0
subsd %xmm1, %xmm0
callq 0x93d0
movq -0x68(%rbp), %r14
divsd 0x3468(%r14), %xmm0
movsd %xmm0, 0x40(%r15)
movsd 0x8(%r15), %xmm0
addsd 0x10(%r15), %xmm0
mulsd 0x3f3b8(%rip), %xmm0    # 0x6b878
movsd 0x60(%r12), %xmm4
movaps -0x60(%rbp), %xmm1
movsd -0x38(%rbp), %xmm2
movsd -0x30(%rbp), %xmm3
movsd -0x48(%rbp), %xmm5
movsd -0x40(%rbp), %xmm6
callq 0x2cdac
movsd %xmm0, 0x30(%r15)
movsd 0x3eb66(%rip), %xmm2    # 0x6b058
movapd %xmm2, %xmm1
subsd 0x30e0(%rbx), %xmm1
mulsd %xmm0, %xmm1
divsd -0x30(%rbp), %xmm1
movapd %xmm2, %xmm0
subsd %xmm1, %xmm0
callq 0x93d0
divsd 0x3468(%r14), %xmm0
movsd %xmm0, 0x48(%r15)
movapd -0x80(%rbp), %xmm0
addsd 0x10(%r15), %xmm0
mulsd 0x3f342(%rip), %xmm0    # 0x6b878
movsd 0x60(%r12), %xmm4
movaps -0x60(%rbp), %xmm1
movsd -0x38(%rbp), %xmm2
movsd -0x30(%rbp), %xmm3
movsd -0x48(%rbp), %xmm5
movsd -0x40(%rbp), %xmm6
callq 0x2cdac
movsd %xmm0, 0x38(%r15)
movsd 0x3eaf0(%rip), %xmm2    # 0x6b058
movapd %xmm2, %xmm1
subsd 0x30e0(%rbx), %xmm1
mulsd %xmm0, %xmm1
divsd -0x30(%rbp), %xmm1
subsd %xmm1, %xmm2
movapd %xmm2, %xmm0
callq 0x93d0
divsd 0x3468(%r14), %xmm0
movl $0x50, %eax
jmp 0x2c610
movl $0x1, 0x4(%r15)
movapd -0x80(%rbp), %xmm0
addsd 0x3eae9(%rip), %xmm0    # 0x6b098
movsd 0x60(%r12), %xmm4
movapd -0x60(%rbp), %xmm1
movsd -0x38(%rbp), %xmm2
movsd -0x48(%rbp), %xmm5
movsd -0x40(%rbp), %xmm6
callq 0x2cdac
movsd %xmm0, 0x28(%r15)
movsd 0x3ea7b(%rip), %xmm2    # 0x6b058
movapd %xmm2, %xmm1
subsd 0x30e0(%rbx), %xmm1
mulsd %xmm0, %xmm1
divsd -0x30(%rbp), %xmm1
subsd %xmm1, %xmm2
movapd %xmm2, %xmm0
callq 0x93d0
movq -0x68(%rbp), %rax
divsd 0x3468(%rax), %xmm0
movl $0x40, %eax
movsd %xmm0, (%r15,%rax)
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop