// File: /workspace/github_cpp_makefile_star2_O2/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movl 0x10(%rdi), %eax
testl %eax, %eax
je 0x5c2d6
movq %rsi, %r15
movq %rdi, %rbx
cmpl $0x1, %eax
jne 0x5c264
movq 0x8(%rbx), %rsi
movq %r15, %rdi
callq 0x63638
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jbe 0x5c2d6
leaq 0x18(%rbx), %rdi
leaq 0x480c86(%rip), %rsi    # 0x4dcee8
jmp 0x5c2ba
leaq 0x80(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x5e4ec
leaq 0x18(%rbx), %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x4feab
testl %eax, %eax
jne 0x5c2d6
leaq 0x58(%rsp), %r14
leaq 0x80(%rsp), %rsi
movq %r14, %rdi
callq 0x5c9dc
movq %r14, %rdi
movq %r13, %rsi
callq 0x4feab
testl %eax, %eax
je 0x5c2e8
leaq 0x480c31(%rip), %rsi    # 0x4dcee8
movq %r13, %rdi
callq 0x51550
movq 0x8(%rbx), %rdi
testq %rdi, %rdi
je 0x5c2cd
callq 0xe5d0
andq $0x0, 0x8(%rbx)
andl $0x0, 0x10(%rbx)
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r15, 0x28(%rsp)
movl 0x10(%rbx), %r12d
leal (,%r12,4), %eax
movslq %eax, %r15
shlq $0x4, %r15
testl %r12d, %r12d
pushq $-0x1
popq %rax
movq %r15, %r14
cmovsq %rax, %r14
movq %r14, %rdi
callq 0xe030
testl %r12d, %r12d
movq %r13, 0x30(%rsp)
movq %rax, 0x10(%rsp)
je 0x5c342
movq %rax, %rbp
xorl %r12d, %r12d
leaq (%r12,%rbp), %rdi
callq 0x5f58a
addq $0x10, %r12
cmpq %r12, %r15
jne 0x5c32a
movslq 0x10(%rbx), %rax
jmp 0x5c344
xorl %eax, %eax
movq 0x8(%rbx), %rcx
shlq $0x4, %rax
leaq (%rcx,%rax), %rbp
addq $-0x10, %rbp
movq 0x28(%rsp), %rdi
movq %rbp, %rsi
callq 0x63638
xorl %ecx, %ecx
xorl %r13d, %r13d
xorl %r14d, %r14d
movslq 0x10(%rbx), %rax
cmpq %rax, %r13
jge 0x5c4ea
movsd %xmm0, 0x8(%rsp)
movq 0x8(%rbx), %r12
movq %rcx, 0x20(%rsp)
addq %rcx, %r12
movq 0x28(%rsp), %rdi
movq %r12, %rsi
callq 0x63638
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movq %r14, %r15
movslq %r14d, %r14
jae 0x5c3bd
movsd 0x8(%rsp), %xmm2
ucomisd %xmm1, %xmm2
jae 0x5c43b
movq %r15, %r14
jmp 0x5c4ac
movsd 0x8(%rsp), %xmm2
ucomisd %xmm2, %xmm1
movsd %xmm0, 0x18(%rsp)
jbe 0x5c4b3
movapd %xmm0, %xmm1
subsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x38(%rsp), %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq 0x5f7c9
leaq 0x48(%rsp), %rbp
movq %rbp, %rdi
leaq 0x38(%rsp), %rsi
movsd 0x8(%rsp), %xmm0
callq 0x5fbe5
leaq 0x58(%rsp), %rdi
movq %r12, %rsi
movq %rbp, %rdx
callq 0x5f7b5
incl %r15d
shlq $0x4, %r14
movq 0x10(%rsp), %rbp
addq %rbp, %r14
movq %r14, %rdi
leaq 0x58(%rsp), %rsi
callq 0x5f6c4
jmp 0x5c4b8
movapd %xmm2, %xmm1
subsd %xmm0, %xmm1
divsd %xmm1, %xmm2
movsd %xmm2, 0x8(%rsp)
leaq 0x38(%rsp), %rdi
movq %r12, %rsi
movq %rbp, %rdx
movsd %xmm0, 0x18(%rsp)
callq 0x5f7c9
leaq 0x48(%rsp), %rdi
leaq 0x38(%rsp), %rsi
movsd 0x8(%rsp), %xmm0
callq 0x5fbe5
leaq 0x58(%rsp), %rdi
movq %rbp, %rsi
leaq 0x48(%rsp), %rdx
callq 0x5f7b5
incl %r15d
shlq $0x4, %r14
addq 0x10(%rsp), %r14
movq %r14, %rdi
movq %r15, %r14
leaq 0x58(%rsp), %rsi
callq 0x5f6c4
movsd 0x18(%rsp), %xmm0
movq 0x20(%rsp), %rcx
jmp 0x5c4db
movq 0x10(%rsp), %rbp
movslq %r15d, %rdi
incl %r15d
shlq $0x4, %rdi
addq %rbp, %rdi
movq %r12, %rsi
callq 0x5f6c4
movq %r15, %r14
movq 0x20(%rsp), %rcx
movsd 0x18(%rsp), %xmm0
incq %r13
addq $0x10, %rcx
movq %r12, %rbp
jmp 0x5c369
leaq 0x4809f7(%rip), %rsi    # 0x4dcee8
movq 0x30(%rsp), %r13
movq %r13, %rdi
callq 0x51550
movl %r14d, 0x10(%rbx)
movq 0x8(%rbx), %rdi
testq %rdi, %rdi
je 0x5c514
callq 0xe5d0
movl 0x10(%rbx), %r14d
movslq %r14d, %r12
movq %r12, %r15
shlq $0x4, %r15
testl %r12d, %r12d
pushq $-0x1
popq %rdi
cmovnsq %r15, %rdi
movq %rdi, 0x8(%rsp)
callq 0xe030
movq %rax, %r14
testl %r12d, %r12d
movq 0x10(%rsp), %rbp
je 0x5c554
xorl %r12d, %r12d
leaq (%r14,%r12), %rdi
callq 0x5f58a
addq $0x10, %r12
cmpq %r12, %r15
jne 0x5c542
movq %r14, 0x8(%rbx)
xorl %r14d, %r14d
xorl %r15d, %r15d
movslq 0x10(%rbx), %rax
cmpq %rax, %r15
jge 0x5c58f
leaq (%r14,%rbp), %rsi
movq 0x8(%rbx), %rdi
addq %r14, %rdi
callq 0x5f6c4
movq 0x8(%rbx), %rsi
addq %r14, %rsi
movq %r13, %rdi
callq 0x5d088
incq %r15
addq $0x10, %r14
jmp 0x5c55e
movq %rbp, %rdi
callq 0xe5d0
jmp 0x5c2d6
movq %rax, %rbx
movq %r14, %rdi
movq 0x8(%rsp), %rsi
jmp 0x5c5b2
movq %rax, %rbx
movq %rbp, %rdi
movq %r14, %rsi
callq 0xe8f0
movq %rbx, %rdi
callq 0xe810
nop