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

  // 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;
      }
    }
  }

  // Return normal
  R2Vector vector = *pointB - *pointA;
  R2Vector n(vector[1], -vector[0]);
  n.Normalize();

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

  // Return normal
  return n;
}

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0x40(%rsp)
movq %rdi, %rax
movq %rax, 0x48(%rsp)
movq %rdi, 0xd0(%rsp)
movq %rsi, 0xc8(%rsp)
movl %edx, 0xc4(%rsp)
movsd %xmm0, 0xb8(%rsp)
movq 0xc8(%rsp), %rax
movq %rax, 0x50(%rsp)
cmpl $0x3, 0x10(%rax)
jge 0xbaced
movq 0x40(%rsp), %rdi
leaq 0x4c01b5(%rip), %rsi    # 0x57ae98
callq 0xc3c60
jmp 0xbb06d
movq 0x50(%rsp), %rcx
movq 0x8(%rcx), %rax
movq %rax, 0x38(%rsp)
movl 0xc4(%rsp), %eax
subl $0x1, %eax
addl 0x10(%rcx), %eax
cltd
idivl 0x10(%rcx)
movq 0x38(%rsp), %rax
movslq %edx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0xb0(%rsp)
movsd 0xb8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xbae68
movq 0x50(%rsp), %rax
movq 0xb0(%rsp), %rcx
movq %rcx, 0xa8(%rsp)
movq 0xb0(%rsp), %rdi
movq 0x8(%rax), %rsi
movslq 0xc4(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rsi
callq 0xcb540
movsd %xmm0, 0xa0(%rsp)
movsd 0xa0(%rsp), %xmm1
movsd 0xb8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xbae66
movl $0x2, 0x9c(%rsp)
movq 0x50(%rsp), %rax
movl 0x9c(%rsp), %ecx
movl %ecx, 0x34(%rsp)
movl 0x10(%rax), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x34(%rsp), %eax
cmpl %ecx, %eax
jge 0xbae64
movq 0x50(%rsp), %rcx
movq 0x8(%rcx), %rax
movq %rax, 0x28(%rsp)
movl 0xc4(%rsp), %eax
subl 0x9c(%rsp), %eax
addl 0x10(%rcx), %eax
cltd
idivl 0x10(%rcx)
movq 0x28(%rsp), %rax
movslq %edx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rdi
movq 0xa8(%rsp), %rsi
callq 0xcb540
addsd 0xa0(%rsp), %xmm0
movsd %xmm0, 0xa0(%rsp)
movsd 0xa0(%rsp), %xmm0
ucomisd 0xb8(%rsp), %xmm0
jb 0xbae3e
jmp 0xbae64
movq 0xb0(%rsp), %rax
movq %rax, 0xa8(%rsp)
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0xbad9e
jmp 0xbae66
jmp 0xbae68
movq 0x50(%rsp), %rcx
movq 0x8(%rcx), %rax
movq %rax, 0x20(%rsp)
movl 0xc4(%rsp), %eax
addl $0x1, %eax
cltd
idivl 0x10(%rcx)
movq 0x20(%rsp), %rax
movslq %edx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0x90(%rsp)
movsd 0xb8(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0xbafce
movq 0x50(%rsp), %rax
movq 0x90(%rsp), %rcx
movq %rcx, 0x88(%rsp)
movq 0x90(%rsp), %rdi
movq 0x8(%rax), %rsi
movslq 0xc4(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rsi
callq 0xcb540
movsd %xmm0, 0x80(%rsp)
movsd 0x80(%rsp), %xmm1
movsd 0xb8(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xbafcc
movl $0x2, 0x7c(%rsp)
movq 0x50(%rsp), %rax
movl 0x7c(%rsp), %ecx
movl %ecx, 0x1c(%rsp)
movl 0x10(%rax), %eax
movl $0x3, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl 0x1c(%rsp), %eax
cmpl %ecx, %eax
jge 0xbafca
movq 0x50(%rsp), %rcx
movq 0x8(%rcx), %rax
movq %rax, 0x10(%rsp)
movl 0xc4(%rsp), %eax
addl 0x7c(%rsp), %eax
cltd
idivl 0x10(%rcx)
movq 0x10(%rsp), %rax
movslq %edx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0x90(%rsp)
movq 0x90(%rsp), %rdi
movq 0x88(%rsp), %rsi
callq 0xcb540
addsd 0x80(%rsp), %xmm0
movsd %xmm0, 0x80(%rsp)
movsd 0x80(%rsp), %xmm0
ucomisd 0xb8(%rsp), %xmm0
jb 0xbafaa
jmp 0xbafca
movq 0x90(%rsp), %rax
movq %rax, 0x88(%rsp)
movl 0x7c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x7c(%rsp)
jmp 0xbaf13
jmp 0xbafcc
jmp 0xbafce
movq 0x90(%rsp), %rsi
movq 0xb0(%rsp), %rdx
leaq 0x68(%rsp), %rdi
callq 0xc3830
leaq 0x68(%rsp), %rdi
movl $0x1, %esi
callq 0xa5c10
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x68(%rsp), %rdi
xorl %esi, %esi
callq 0xa5c10
movsd 0x8(%rsp), %xmm0
movq 0x40(%rsp), %rdi
movsd (%rax), %xmm1
movq %xmm1, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm1
callq 0xc3c30
movq 0x40(%rsp), %rdi
callq 0xc4090
movq 0x50(%rsp), %rax
cmpl $0x0, 0x40(%rax)
je 0xbb06b
movq 0x40(%rsp), %rsi
leaq 0x58(%rsp), %rdi
callq 0xc4700
movq 0x40(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0xc4350
jmp 0xbb06d
movq 0x48(%rsp), %rax
addq $0xd8, %rsp
retq
nopw (%rax,%rax)