// File: tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Plane.cpp
// Function: gaps::R3Plane::R3Plane(gaps::R3Point const*, int, int)
R3Plane::
R3Plane(const R3Point *points, int npoints, RNBoolean polygon_vertices)
{
    // Initialize plane
    v = R3null_vector;
    d = 0;

    // Check number of points
    if (npoints < 3) {
      *this = R3null_plane;
      return;
    }

    // Compute centroid
    R3Point c = R3Centroid(npoints, points);

    // Check if points form (counter-clockwise) boundary of polygon
    if (polygon_vertices) {
        // Compute best normal for counter-clockwise array of points using newell's method 
        const R3Point *p1 = &points[npoints-1];
        for (int i = 0; i < npoints; i++) {
            const R3Point *p2 = &points[i];
            v[0] += (p1->Y() - p2->Y()) * (p1->Z() + p2->Z());
            v[1] += (p1->Z() - p2->Z()) * (p1->X() + p2->X());
            v[2] += (p1->X() - p2->X()) * (p1->Y() + p2->Y());
            p1 = p2;
        }

        // Normalize 
        v.Normalize();
    }
    else {
        // Compute principle axes
        R3Triad triad = R3PrincipleAxes(c, npoints, points);

        // Select direction of least variation
        v = triad[2];
    }

    // Compute d from centroid and normal
    d = -(v[0]*c[0] + v[1]*c[1] + v[2]*c[2]);
}

// Assembly:
subq $0x128, %rsp            # imm = 0x128
movq %rdi, 0x120(%rsp)
movq %rsi, 0x118(%rsp)
movl %edx, 0x114(%rsp)
movl %ecx, 0x110(%rsp)
movq 0x120(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x6fca0
movq 0x90(%rsp), %rdi
leaq 0x50c9b7(%rip), %rsi    # 0x5795a0
callq 0x70970
movq 0x90(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x18(%rax)
cmpl $0x3, 0x114(%rsp)
jge 0x6cc21
movq 0x90(%rsp), %rdi
leaq 0x50c4c9(%rip), %rsi    # 0x5790e0
callq 0x3a4d0
jmp 0x6cfea
movl 0x114(%rsp), %esi
movq 0x118(%rsp), %rdx
leaq 0xf8(%rsp), %rdi
xorl %eax, %eax
movl %eax, %ecx
callq 0x8fea0
cmpl $0x0, 0x110(%rsp)
je 0x6ceab
movq 0x118(%rsp), %rax
movl 0x114(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0xf0(%rsp)
movl $0x0, 0xec(%rsp)
movl 0xec(%rsp), %eax
cmpl 0x114(%rsp), %eax
jge 0x6ce9c
movq 0x118(%rsp), %rax
movslq 0xec(%rsp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0xe0(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x37870
movsd %xmm0, 0x30(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x37870
movaps %xmm0, %xmm1
movsd 0x30(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x40(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x378c0
movsd %xmm0, 0x38(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x378c0
movq 0x90(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x38(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x48(%rsp)
xorl %esi, %esi
callq 0x36c00
movsd 0x40(%rsp), %xmm0
movsd 0x48(%rsp), %xmm2
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq 0xf0(%rsp), %rdi
callq 0x378c0
movsd %xmm0, 0x50(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x378c0
movaps %xmm0, %xmm1
movsd 0x50(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x60(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x37820
movsd %xmm0, 0x58(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x37820
movq 0x90(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x58(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x68(%rsp)
movl $0x1, %esi
callq 0x36c00
movsd 0x60(%rsp), %xmm0
movsd 0x68(%rsp), %xmm2
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq 0xf0(%rsp), %rdi
callq 0x37820
movsd %xmm0, 0x70(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x37820
movaps %xmm0, %xmm1
movsd 0x70(%rsp), %xmm0
subsd %xmm1, %xmm0
movsd %xmm0, 0x80(%rsp)
movq 0xf0(%rsp), %rdi
callq 0x37870
movsd %xmm0, 0x78(%rsp)
movq 0xe0(%rsp), %rdi
callq 0x37870
movq 0x90(%rsp), %rdi
movaps %xmm0, %xmm1
movsd 0x78(%rsp), %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x88(%rsp)
movl $0x2, %esi
callq 0x36c00
movsd 0x80(%rsp), %xmm0
movsd 0x88(%rsp), %xmm2
movsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax)
movq 0xe0(%rsp), %rax
movq %rax, 0xf0(%rsp)
movl 0xec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xec(%rsp)
jmp 0x6cc7e
movq 0x90(%rsp), %rdi
callq 0x70410
jmp 0x6cef9
movl 0x114(%rsp), %edx
movq 0x118(%rsp), %rcx
leaq 0x98(%rsp), %rdi
leaq 0xf8(%rsp), %rsi
xorl %eax, %eax
movl %eax, %r9d
movq %r9, %r8
callq 0x8ff60
leaq 0x98(%rsp), %rdi
movl $0x2, %esi
callq 0x39fb0
movq 0x90(%rsp), %rdi
movq %rax, %rsi
callq 0x70970
movq 0x90(%rsp), %rdi
xorl %esi, %esi
callq 0x36c00
movsd (%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0xf8(%rsp), %rdi
xorl %esi, %esi
callq 0x36be0
movq 0x90(%rsp), %rdi
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movl $0x1, %esi
callq 0x36c00
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0xf8(%rsp), %rdi
movl $0x1, %esi
callq 0x36be0
movsd 0x8(%rsp), %xmm1
movsd 0x10(%rsp), %xmm0
movsd 0x18(%rsp), %xmm2
movq 0x90(%rsp), %rdi
mulsd (%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x28(%rsp)
movl $0x2, %esi
callq 0x36c00
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
leaq 0xf8(%rsp), %rdi
movl $0x2, %esi
callq 0x36be0
movsd 0x20(%rsp), %xmm0
movsd 0x28(%rsp), %xmm1
movq %rax, %rcx
movq 0x90(%rsp), %rax
movsd (%rcx), %xmm2
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movq %xmm0, %rcx
movabsq $-0x8000000000000000, %rdx # imm = 0x8000000000000000
xorq %rdx, %rcx
movq %rcx, %xmm0
movsd %xmm0, 0x18(%rax)
addq $0x128, %rsp            # imm = 0x128
retq
nopw %cs:(%rax,%rax)