// File: tomfunkhouser[P]gaps/pkgs/R2Shapes/R2Polygon.cpp
// Function: gaps::R2Polygon::Clip(gaps::R2Line const&)
void R2Polygon::
Clip(const R2Line& line) 
{
  // Check number of points
  if (npoints == 0) {
    return;
  }
  else if (npoints == 1) {
    if (R2SignedDistance(line, points[0]) < 0) {
      bbox = R2null_box;
      delete [] points;
      points = NULL;
      npoints = 0;
    }
  }
  else {
    // Check bounding box
    R2Halfspace halfspace(line, 0);

    // Check if bounding box is entirely on positive side of line
    if (R2Contains(halfspace, bbox)) {
      return;
    }

    // Check if bounding box is entirely on negative side of line
    if (R2Contains(-halfspace, bbox)) {
      bbox = R2null_box;
      delete [] points;
      points = NULL;
      npoints = 0;
      return;
    }

    // Create new array for points
    int nbuffer = 0;
    R2Point *buffer = new R2Point [ 4 * npoints ];
    if (!buffer) RNAbort("Unable to allocate points during clip");

    // Build buffer with clipped points
    const R2Point *p1 = &points[npoints-1];
    RNScalar d1 = R2SignedDistance(line, *p1);
    for (int i = 0; i < npoints; i++) {
      const R2Point *p2 = &points[i];
      RNScalar d2 = R2SignedDistance(line, *p2);
      if (d2 >= 0) {
        // Insert crossing from negative to positive
        if (d1 < 0) {
          RNScalar t = d2 / (d2 - d1);
          buffer[nbuffer++] = *p2 + t * (*p1 - *p2);
        }

        // Insert point on positive side
        buffer[nbuffer++] = *p2;
      }
      else {
        // Insert crossing from positive to negative
        if (d1 >= 0) {
          RNScalar t = d1 / (d1 - d2);
          buffer[nbuffer++] = *p1 + t * (*p2 - *p1);
        }
      }

      // Remember previous point
      p1 = p2;
      d1 = d2;
    }

    // Copy points
    bbox = R2null_box;
    npoints = nbuffer;
    delete [] points;
    points = new R2Point [ npoints ];
    for (int i = 0; i < npoints; i++) {
      points[i] = buffer[i];
      bbox.Union(points[i]);
    }

    // Delete the buffer of points
    delete [] buffer;
  }
}

// Assembly:
subq $0x1c8, %rsp            # imm = 0x1C8
movq %rdi, 0x1c0(%rsp)
movq %rsi, 0x1b8(%rsp)
movq 0x1c0(%rsp), %rax
movq %rax, 0xa0(%rsp)
cmpl $0x0, 0x10(%rax)
jne 0xbc3c2
jmp 0xbcac3
movq 0xa0(%rsp), %rax
cmpl $0x1, 0x10(%rax)
jne 0xbc454
movq 0xa0(%rsp), %rax
movq 0x1b8(%rsp), %rdi
movq 0x8(%rax), %rsi
callq 0xcb900
movaps %xmm0, %xmm1
xorps %xmm0, %xmm0
ucomisd %xmm1, %xmm0
jbe 0xbc44f
movq 0xa0(%rsp), %rdi
addq $0x18, %rdi
leaq 0x4be5dc(%rip), %rsi    # 0x57a9e8
callq 0xa5da0
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x98(%rsp)
cmpq $0x0, %rax
je 0xbc438
movq 0x98(%rsp), %rdi
callq 0xf670
movq 0xa0(%rsp), %rax
movq $0x0, 0x8(%rax)
movl $0x0, 0x10(%rax)
jmp 0xbcac1
movq 0x1b8(%rsp), %rsi
leaq 0x190(%rsp), %rdi
xorl %edx, %edx
callq 0xc1260
movq 0xa0(%rsp), %rsi
addq $0x18, %rsi
leaq 0x190(%rsp), %rdi
callq 0xa2500
cmpl $0x0, %eax
je 0xbc48e
jmp 0xbcac3
leaq 0x168(%rsp), %rdi
leaq 0x190(%rsp), %rsi
callq 0xbd270
movq 0xa0(%rsp), %rsi
addq $0x18, %rsi
leaq 0x168(%rsp), %rdi
callq 0xa2500
cmpl $0x0, %eax
je 0xbc51c
movq 0xa0(%rsp), %rdi
addq $0x18, %rdi
leaq 0x4be514(%rip), %rsi    # 0x57a9e8
callq 0xa5da0
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x90(%rsp)
cmpq $0x0, %rax
je 0xbc500
movq 0x90(%rsp), %rdi
callq 0xf670
movq 0xa0(%rsp), %rax
movq $0x0, 0x8(%rax)
movl $0x0, 0x10(%rax)
jmp 0xbcac3
movq 0xa0(%rsp), %rax
movl $0x0, 0x164(%rsp)
movl 0x10(%rax), %eax
shll $0x2, %eax
cltq
movq %rax, 0x80(%rsp)
movl $0x10, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, 0x78(%rsp)
callq 0xf030
movq %rax, %rcx
movq 0x80(%rsp), %rax
movq %rcx, 0x88(%rsp)
cmpq $0x0, %rax
je 0xbc5cb
movq 0x88(%rsp), %rax
movq 0x80(%rsp), %rdx
shlq $0x4, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x68(%rsp)
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0xc3130
jmp 0xbc5b3
movq 0x68(%rsp), %rcx
movq 0x60(%rsp), %rax
addq $0x10, %rax
cmpq %rcx, %rax
movq %rax, 0x70(%rsp)
jne 0xbc5a2
movq 0x88(%rsp), %rax
movq %rax, 0x158(%rsp)
cmpq $0x0, 0x158(%rsp)
jne 0xbc621
leaq 0x79be3(%rip), %rdi     # 0x1361d0
movb $0x0, %al
callq 0xd4e20
jmp 0xbc621
movq 0x78(%rsp), %rsi
movq 0x88(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
callq 0xf990
jmp 0xbcacb
movq 0xa0(%rsp), %rcx
movq 0x8(%rcx), %rax
movl 0x10(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0x140(%rsp)
movq 0x1b8(%rsp), %rdi
movq 0x140(%rsp), %rsi
callq 0xcb900
movsd %xmm0, 0x138(%rsp)
movl $0x0, 0x134(%rsp)
movq 0xa0(%rsp), %rcx
movl 0x134(%rsp), %eax
cmpl 0x10(%rcx), %eax
jge 0xbc903
movq 0xa0(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0x134(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, 0x128(%rsp)
movq 0x1b8(%rsp), %rdi
movq 0x128(%rsp), %rsi
callq 0xcb900
movsd %xmm0, 0x120(%rsp)
movsd 0x120(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0xbc7ec
xorps %xmm0, %xmm0
ucomisd 0x138(%rsp), %xmm0
jbe 0xbc7b6
movsd 0x120(%rsp), %xmm0
movsd 0x120(%rsp), %xmm1
subsd 0x138(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x118(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x58(%rsp)
movsd 0x118(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0x140(%rsp), %rsi
movq 0x128(%rsp), %rdx
leaq 0xe8(%rsp), %rdi
callq 0xc3830
movsd 0x50(%rsp), %xmm0
leaq 0xf8(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0xa5c30
movq 0x58(%rsp), %rsi
leaq 0x108(%rsp), %rdi
leaq 0xf8(%rsp), %rdx
callq 0xc37a0
movq 0x158(%rsp), %rdi
movl 0x164(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x164(%rsp)
cltq
shlq $0x4, %rax
addq %rax, %rdi
leaq 0x108(%rsp), %rsi
callq 0xc33e0
movq 0x128(%rsp), %rsi
movq 0x158(%rsp), %rdi
movl 0x164(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x164(%rsp)
cltq
shlq $0x4, %rax
addq %rax, %rdi
callq 0xc33e0
jmp 0xbc8cb
movsd 0x138(%rsp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jb 0xbc8c9
movsd 0x138(%rsp), %xmm0
movsd 0x138(%rsp), %xmm1
subsd 0x120(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0xe0(%rsp)
movq 0x140(%rsp), %rax
movq %rax, 0x48(%rsp)
movsd 0xe0(%rsp), %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0x128(%rsp), %rsi
movq 0x140(%rsp), %rdx
leaq 0xb0(%rsp), %rdi
callq 0xc3830
movsd 0x40(%rsp), %xmm0
leaq 0xc0(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
callq 0xa5c30
movq 0x48(%rsp), %rsi
leaq 0xd0(%rsp), %rdi
leaq 0xc0(%rsp), %rdx
callq 0xc37a0
movq 0x158(%rsp), %rdi
movl 0x164(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x164(%rsp)
cltq
shlq $0x4, %rax
addq %rax, %rdi
leaq 0xd0(%rsp), %rsi
callq 0xc33e0
jmp 0xbc8cb
movq 0x128(%rsp), %rax
movq %rax, 0x140(%rsp)
movsd 0x120(%rsp), %xmm0
movsd %xmm0, 0x138(%rsp)
movl 0x134(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x134(%rsp)
jmp 0xbc66e
movq 0xa0(%rsp), %rdi
addq $0x18, %rdi
leaq 0x4be0d2(%rip), %rsi    # 0x57a9e8
callq 0xa5da0
movq 0xa0(%rsp), %rax
movl 0x164(%rsp), %ecx
movl %ecx, 0x10(%rax)
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, %rax
je 0xbc946
movq 0x38(%rsp), %rdi
callq 0xf670
movq 0xa0(%rsp), %rax
movslq 0x10(%rax), %rax
movq %rax, 0x28(%rsp)
movl $0x10, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, 0x20(%rsp)
callq 0xf030
movq %rax, %rcx
movq 0x28(%rsp), %rax
movq %rcx, 0x30(%rsp)
cmpq $0x0, %rax
je 0xbc9d7
movq 0x30(%rsp), %rax
movq 0x28(%rsp), %rdx
shlq $0x4, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0xc3130
jmp 0xbc9bf
movq 0x10(%rsp), %rcx
movq 0x8(%rsp), %rax
addq $0x10, %rax
cmpq %rcx, %rax
movq %rax, 0x18(%rsp)
jne 0xbc9ae
movq 0xa0(%rsp), %rax
movq 0x30(%rsp), %rcx
movq %rcx, 0x8(%rax)
movl $0x0, 0xac(%rsp)
movq 0xa0(%rsp), %rcx
movl 0xac(%rsp), %eax
cmpl 0x10(%rcx), %eax
jge 0xbcaa4
movq 0xa0(%rsp), %rax
movq 0x158(%rsp), %rsi
movslq 0xac(%rsp), %rcx
shlq $0x4, %rcx
addq %rcx, %rsi
movq 0x8(%rax), %rdi
movslq 0xac(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rdi
callq 0xc33e0
movq 0xa0(%rsp), %rax
movq %rax, %rdi
addq $0x18, %rdi
movq 0x8(%rax), %rsi
movslq 0xac(%rsp), %rax
shlq $0x4, %rax
addq %rax, %rsi
callq 0xbe470
movl 0xac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xac(%rsp)
jmp 0xbc9f3
movq 0x20(%rsp), %rsi
movq 0x30(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x150(%rsp)
movl %eax, 0x14c(%rsp)
callq 0xf990
jmp 0xbcacb
movq 0x158(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0xbcabf
movq (%rsp), %rdi
callq 0xf670
jmp 0xbcac1
jmp 0xbcac3
addq $0x1c8, %rsp            # imm = 0x1C8
retq
movq 0x150(%rsp), %rdi
callq 0xf890
nopl (%rax,%rax)