// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Polygon.cpp
// Function: gaps::R2Polygon::Curvature(int, double) const
RNScalar R2Polygon::
Curvature(int k, RNLength radius) const
{
  // Just checking
  if (npoints < 3) return 0;

  // Find first point
  R2Point *pointA = &points[(k - 1 + npoints) % npoints];
  if (radius > 0) {
    R2Point *prev = pointA;
    RNLength distance = R2Distance(*pointA, points[k]);
    if (distance < radius) {
      for (int i = 2;  i < npoints/3; i++) {
        pointA = &points[(k - i + npoints) % npoints];
        distance += R2Distance(*pointA, *prev);
        if (distance >= radius) break; 
        prev = pointA;
      }
    }
  }

  // Find second point
  R2Point *pointB = &points[(k + 1) % npoints];
  if (radius > 0) {
    R2Point *prev = pointB;
    RNLength distance = R2Distance(*pointB, points[k]);
    if (distance < radius) {
      for (int i = 2;  i < npoints/3; i++) {
        pointB = &points[(k + i) % npoints];
        distance += R2Distance(*pointB, *prev);
        if (distance >= radius) break;
        prev = pointB;
      }
    }
  }

  // Compute curvature
  R2Vector va = *pointA - points[k];
  R2Vector vb = *pointB - points[k];
  RNLength lena = va.Length();
  RNLength lenb = vb.Length();
  if (RNIsZero(lena) || RNIsZero(lenb)) return RN_UNKNOWN;
  RNScalar angle = R2InteriorAngle(va, vb);
  RNScalar cross = (va[0]*vb[1] - va[1]*vb[0]);
  RNScalar sign = (cross > 0) ? -1 : 1;
  RNScalar curvature = sign * (RN_PI - angle) / (lena + lenb);

  // Flip if polygon is clockwise
  if (clockwise) curvature = -curvature;

  // Return curvature
  return curvature;
}

// Assembly:
subq $0x108, %rsp            # imm = 0x108
movq %rdi, 0xf8(%rsp)
movl %esi, 0xf4(%rsp)
movsd %xmm0, 0xe8(%rsp)
movq 0xf8(%rsp), %rax
movq %rax, 0x50(%rsp)
cmpl $0x3, 0x10(%rax)
jge 0xbbaa3
xorps %xmm0, %xmm0
movsd %xmm0, 0x100(%rsp)
jmp 0xbbfb3
movq 0x50(%rsp), %rcx
movq 0x8(%rcx), %rax
movq %rax, 0x48(%rsp)
movl 0xf4(%rsp), %eax
subl $0x1, %eax
addl 0x10(%rcx), %eax
cltd
idivl 0x10(%rcx)
movq 0x48(%rsp), %rax
movslq %edx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0xe0(%rsp)
movsd 0xe8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xbbc1e
movq 0x50(%rsp), %rax
movq 0xe0(%rsp), %rcx
movq %rcx, 0xd8(%rsp)
movq 0xe0(%rsp), %rdi
movq 0x8(%rax), %rsi
movslq 0xf4(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rsi
callq 0xcb540
movsd %xmm0, 0xd0(%rsp)
movsd 0xd0(%rsp), %xmm1
movsd 0xe8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xbbc1c
movl $0x2, 0xcc(%rsp)
movq 0x50(%rsp), %rax
movl 0xcc(%rsp), %ecx
movl %ecx, 0x44(%rsp)
movl 0x10(%rax), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x44(%rsp), %eax
cmpl %ecx, %eax
jge 0xbbc1a
movq 0x50(%rsp), %rcx
movq 0x8(%rcx), %rax
movq %rax, 0x38(%rsp)
movl 0xf4(%rsp), %eax
subl 0xcc(%rsp), %eax
addl 0x10(%rcx), %eax
cltd
idivl 0x10(%rcx)
movq 0x38(%rsp), %rax
movslq %edx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rdi
movq 0xd8(%rsp), %rsi
callq 0xcb540
addsd 0xd0(%rsp), %xmm0
movsd %xmm0, 0xd0(%rsp)
movsd 0xd0(%rsp), %xmm0
ucomisd 0xe8(%rsp), %xmm0
jb 0xbbbf4
jmp 0xbbc1a
movq 0xe0(%rsp), %rax
movq %rax, 0xd8(%rsp)
movl 0xcc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xcc(%rsp)
jmp 0xbbb54
jmp 0xbbc1c
jmp 0xbbc1e
movq 0x50(%rsp), %rcx
movq 0x8(%rcx), %rax
movq %rax, 0x30(%rsp)
movl 0xf4(%rsp), %eax
addl $0x1, %eax
cltd
idivl 0x10(%rcx)
movq 0x30(%rsp), %rax
movslq %edx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0xc0(%rsp)
movsd 0xe8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xbbd93
movq 0x50(%rsp), %rax
movq 0xc0(%rsp), %rcx
movq %rcx, 0xb8(%rsp)
movq 0xc0(%rsp), %rdi
movq 0x8(%rax), %rsi
movslq 0xf4(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rsi
callq 0xcb540
movsd %xmm0, 0xb0(%rsp)
movsd 0xb0(%rsp), %xmm1
movsd 0xe8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xbbd91
movl $0x2, 0xac(%rsp)
movq 0x50(%rsp), %rax
movl 0xac(%rsp), %ecx
movl %ecx, 0x2c(%rsp)
movl 0x10(%rax), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0xbbd8f
movq 0x50(%rsp), %rcx
movq 0x8(%rcx), %rax
movq %rax, 0x20(%rsp)
movl 0xf4(%rsp), %eax
addl 0xac(%rsp), %eax
cltd
idivl 0x10(%rcx)
movq 0x20(%rsp), %rax
movslq %edx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rdi
movq 0xb8(%rsp), %rsi
callq 0xcb540
addsd 0xb0(%rsp), %xmm0
movsd %xmm0, 0xb0(%rsp)
movsd 0xb0(%rsp), %xmm0
ucomisd 0xe8(%rsp), %xmm0
jb 0xbbd69
jmp 0xbbd8f
movq 0xc0(%rsp), %rax
movq %rax, 0xb8(%rsp)
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0xbbccc
jmp 0xbbd91
jmp 0xbbd93
movq 0x50(%rsp), %rax
movq 0xe0(%rsp), %rsi
movq 0x8(%rax), %rdx
movslq 0xf4(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rdx
leaq 0x98(%rsp), %rdi
callq 0xc3830
movq 0x50(%rsp), %rax
movq 0xc0(%rsp), %rsi
movq 0x8(%rax), %rdx
movslq 0xf4(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rdx
leaq 0x88(%rsp), %rdi
callq 0xc3830
leaq 0x98(%rsp), %rdi
callq 0xc3d60
movsd %xmm0, 0x80(%rsp)
leaq 0x88(%rsp), %rdi
callq 0xc3d60
movsd %xmm0, 0x78(%rsp)
movsd 0x80(%rsp), %xmm0
leaq 0xbc6ba(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
jne 0xbbe4f
movsd 0x78(%rsp), %xmm0
leaq 0xbc69f(%rip), %rax     # 0x1784e0
movsd (%rax), %xmm1
callq 0x36b80
cmpl $0x0, %eax
je 0xbbe65
movsd 0x771c1(%rip), %xmm0    # 0x133018
movsd %xmm0, 0x100(%rsp)
jmp 0xbbfb3
leaq 0x98(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0xcd240
movsd %xmm0, 0x70(%rsp)
leaq 0x98(%rsp), %rdi
xorl %esi, %esi
callq 0xa5c10
movsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x88(%rsp), %rdi
movl $0x1, %esi
callq 0xa5c10
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
leaq 0x98(%rsp), %rdi
movl $0x1, %esi
callq 0xa5c10
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x88(%rsp), %rdi
xorl %esi, %esi
callq 0xa5c10
movsd 0x8(%rsp), %xmm1
movsd 0x10(%rsp), %xmm0
movsd 0x18(%rsp), %xmm2
movq %rax, %rcx
movq 0x50(%rsp), %rax
mulsd (%rcx), %xmm1
movq %xmm1, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x68(%rsp)
movsd 0x68(%rsp), %xmm0
xorps %xmm1, %xmm1
movl $0x1, %ecx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
ucomisd %xmm1, %xmm0
cmoval %edx, %ecx
cvtsi2sd %ecx, %xmm0
movsd %xmm0, 0x60(%rsp)
movsd 0x60(%rsp), %xmm0
leaq 0x7a984(%rip), %rcx     # 0x1368d8
movsd (%rcx), %xmm1
subsd 0x70(%rsp), %xmm1
mulsd %xmm1, %xmm0
movsd 0x80(%rsp), %xmm1
addsd 0x78(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x58(%rsp)
cmpl $0x0, 0x40(%rax)
je 0xbbfa4
movsd 0x58(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, 0x58(%rsp)
movsd 0x58(%rsp), %xmm0
movsd %xmm0, 0x100(%rsp)
movsd 0x100(%rsp), %xmm0
addq $0x108, %rsp            # imm = 0x108
retq
nopw %cs:(%rax,%rax)