// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Relate.cpp
// Function: gaps::R2IntersectionArea(gaps::R2Circle const&, gaps::R2Circle const&)
RNArea 
R2IntersectionArea(const R2Circle& circle1, const R2Circle& circle2)
{
  RNArea area = 0;
  RNLength r1 = circle1.Radius();
  if (RNIsZero(r1)) return 0;
  RNLength r2 = circle2.Radius();
  if (RNIsZero(r2)) return 0;
  RNLength d = R2Distance(circle1.Center(), circle2.Center());
  RNLength rmin = (r1 < r2) ? r1 : r2;
  RNLength rmax = (r1 > r2) ? r1 : r2;
  if (RNIsLessOrEqual(d + rmin, rmax)) {
    // Compute area of smaller circle
    area = RN_PI * rmin * rmin;
  }
  else if (RNIsLessOrEqual(d, r1 + r2)) {
    // Compute area of "asymmetric lens"
    // http://mathworld.wolfram.com/Circle-CircleIntersection.html
    RNScalar a1 = r1*r1*acos((d*d + r1*r1 - r2*r2) / (2*d*r1));
    RNScalar a2 = r2*r2*acos((d*d + r2*r2 - r1*r1) / (2*d*r2));
    RNScalar a3 = (-d + r1 + r2) * (d + r1 - r2) * (d - r1 + r2) * (d + r1 + r2);
    if (a3 > 0) area = a1 + a2 - 0.5 * sqrt(a3);
  }

  // Return area
  return area;
}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x78(%rsp)
movq 0x88(%rsp), %rdi
callq 0xa36b0
movsd %xmm0, 0x70(%rsp)
movsd 0x70(%rsp), %xmm0
leaq 0xaafe0(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0xcd51f
xorps %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
jmp 0xcd856
movq 0x80(%rsp), %rdi
callq 0xa36b0
movsd %xmm0, 0x68(%rsp)
movsd 0x68(%rsp), %xmm0
leaq 0xaafa1(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0xcd55e
xorps %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
jmp 0xcd856
movq 0x88(%rsp), %rdi
callq 0xa3530
movq %rax, 0x30(%rsp)
movq 0x80(%rsp), %rdi
callq 0xa3530
movq 0x30(%rsp), %rdi
movq %rax, %rsi
callq 0xcb540
movsd %xmm0, 0x60(%rsp)
movsd 0x70(%rsp), %xmm1
movsd 0x68(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xcd5b0
movsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
jmp 0xcd5bc
movsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x28(%rsp), %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x70(%rsp), %xmm0
ucomisd 0x68(%rsp), %xmm0
jbe 0xcd5e4
movsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
jmp 0xcd5f0
movsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x20(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movsd 0x60(%rsp), %xmm0
addsd 0x58(%rsp), %xmm0
movsd 0x50(%rsp), %xmm1
leaq 0xaaecb(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x81b50
cmpl $0x0, %eax
je 0xcd645
leaq 0x692ae(%rip), %rax     # 0x1368d8
movsd (%rax), %xmm0
mulsd 0x58(%rsp), %xmm0
mulsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x78(%rsp)
jmp 0xcd847
movsd 0x60(%rsp), %xmm0
movsd 0x70(%rsp), %xmm1
addsd 0x68(%rsp), %xmm1
leaq 0xaae82(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm2
callq 0x81b50
cmpl $0x0, %eax
je 0xcd845
movsd 0x70(%rsp), %xmm0
mulsd 0x70(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x60(%rsp), %xmm1
movsd 0x60(%rsp), %xmm2
movsd 0x70(%rsp), %xmm0
mulsd 0x70(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd 0x68(%rsp), %xmm0
movsd 0x68(%rsp), %xmm2
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x65b2b(%rip), %xmm1    # 0x133200
mulsd 0x60(%rsp), %xmm1
mulsd 0x70(%rsp), %xmm1
divsd %xmm1, %xmm0
callq 0xf470
movaps %xmm0, %xmm1
movsd 0x10(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x48(%rsp)
movsd 0x68(%rsp), %xmm0
mulsd 0x68(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x60(%rsp), %xmm1
movsd 0x60(%rsp), %xmm2
movsd 0x68(%rsp), %xmm0
mulsd 0x68(%rsp), %xmm0
mulsd %xmm2, %xmm1
addsd %xmm0, %xmm1
movsd 0x70(%rsp), %xmm0
movsd 0x70(%rsp), %xmm2
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd 0x65a9e(%rip), %xmm1    # 0x133200
mulsd 0x60(%rsp), %xmm1
mulsd 0x68(%rsp), %xmm1
divsd %xmm1, %xmm0
callq 0xf470
movaps %xmm0, %xmm1
movsd 0x18(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd %xmm0, 0x40(%rsp)
movsd 0x60(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
addsd 0x70(%rsp), %xmm0
addsd 0x68(%rsp), %xmm0
movsd 0x60(%rsp), %xmm1
addsd 0x70(%rsp), %xmm1
subsd 0x68(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0x60(%rsp), %xmm1
subsd 0x70(%rsp), %xmm1
addsd 0x68(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0x60(%rsp), %xmm1
addsd 0x70(%rsp), %xmm1
addsd 0x68(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x38(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xcd843
movsd 0x48(%rsp), %xmm0
addsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x38(%rsp), %xmm0
callq 0xf390
movsd 0x8(%rsp), %xmm1
movsd 0x65a2b(%rip), %xmm2    # 0x133260
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x78(%rsp)
jmp 0xcd845
jmp 0xcd847
movsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x90(%rsp)
movsd 0x90(%rsp), %xmm0
addq $0x98, %rsp
retq
nopw (%rax,%rax)