// File: /workspace/github_cpp_makefile_star2_O1/thierry7100[P]CutOptim/src/Geometry.cpp
// Function: Polygon::enlarge(double)
Polygon *Polygon::enlarge(double Diff)
{
int First = 1;
Point OldA2 = Point(0, 0);
Point OldB2 = Point(0, 0);
Segment A2B2 = Segment(OldA2, OldB2);
Line OldLine(1, 1, 0);
Line FirstLine(1, 1, 0);
int newVertices = 0;
double a, b, c;

    //  Then create larger polygon.
    Polygon *LargePoly = new Polygon();

    for ( int i = 0; i < nVertices - 1; i++)
    {
        //  For each segment create a segment which is parallel to the original segment, but translated at distance Diff
        a = _Vertices[i].y - _Vertices[i+1].y;
        b = _Vertices[i+1].x - _Vertices[i].x;
        c = _Vertices[i].x * _Vertices[i+1].y - _Vertices[i+1].x * _Vertices[i].y;
        //  If equation of first segment is ax + by + c = 0, the translated segment has an equation like ax + by + C = 0 where C = c + Diff*sqrt(a*a + b*b)
        //  Here we will first build a segment which begins in A' and end in B' where A' is the point on the line perpendicular to the segment and which starts in A
        double C = c + Diff*sqrt(a*a+b*b);
        Line A1B1 = Line(a, b, C);
        //  Now the lines which are perpendicular in A or B to the segment
        Line AB_perpendicular_A = Line(-b, a, b*_Vertices[i].x - a*_Vertices[i].y);
        Line AB_perpendicular_B = Line(-b, a, b*_Vertices[i+1].x - a*_Vertices[i+1].y);
        // Compute intersection of AB_perpendicular_A and A1B1 (point A1)
        Point A1 = A1B1.Intersect(AB_perpendicular_A);
        Point B1 = A1B1.Intersect(AB_perpendicular_B);
        //  Now enlarge segment to reach A2 which is Diff further from A1 and B2 which is also Diff further from B1
        double distA1B1 = A1.Distance(B1);
        double Coeff = Diff/distA1B1;
        //  Now compute A2 and B2
        //  A2B1 = Coeff*A1B1
        Point A2 = A1 + Coeff*(A1-B1);
        Point B2 = B1 + Coeff*(B1-A1);
        A2B2 = Segment(A2, B2);
        //  Compute intersection between segment A2B2 and Old Segment A2B2 if not processing the first vertice
        if ( !First )
        {
            Point A3 = A1B1.Intersect(OldLine);
            //  If A3 is between A2 and B2, keep segment A3 - B2
            if (A2B2.InSegment(A3) )
            {
                //Change end of previous segment to A3, so change vertice of largePoly
                LargePoly->_Vertices[newVertices-1] = A3;
                //  And add new point B2
                LargePoly->addVertice(B2);
                newVertices = LargePoly->_Vertices.size();
#if DEBUG_CONSOLE > 1
                printf("Changing last point to A3 (%.3f,%.3f) and add one point (%d) B2 : (%.3f,%.3f)\n", A3.x, A3.y, newVertices, B2.x, B2.y);
#endif // DEBUG_CONSOLE
            }
            else
            {
                // Add vertice A2 and B2
                LargePoly->addVertice(A2);
                LargePoly->addVertice(B2);
                newVertices = LargePoly->_Vertices.size();
#if DEBUG_CONSOLE > 1
                printf("Add 2 points (%d and %d) A2 point (%.3f,%.3f) and B2 (%.3f,%.3f)\n", newVertices-1, newVertices, A2.x, A2.y, B2.x, B2.y);
#endif // DEBUG_CONSOLE
            }
        }
        else
        {
            LargePoly->addVertice(A2);
            LargePoly->addVertice(B2);
            newVertices = LargePoly->_Vertices.size();
            FirstLine = A1B1;
            First = 0;
#if DEBUG_CONSOLE > 1
            printf("Add First %d points : (%.3f, %.3f)   (%.3f,%.3f)\n", newVertices, A2.x, A2.y, B2.x, B2.y);
#endif // DEBUG_CONSOLE
        }
        OldA2 = A2;
        OldB2 = B2;
        OldLine = A1B1;
    }
    //  Now change first segment, compute intersection with OldLine
    Point A3;
    if ( OldLine.hasIntersect(&FirstLine, A3 ) )
    {
        //  If A3 is between A2 and B2, keep segment A3 - B2
        if (A2B2.InSegment(A3) )
        {
            //Change end of previous segment to A3, so change vertice of largePoly
            LargePoly->_Vertices[newVertices-1] = A3;
            //  And set First point of Poly to be the same
            LargePoly->_Vertices[0] = A3;
#if DEBUG_CONSOLE > 1
            printf("Changing first/last point (%d) A3 : (%.3f,%.3f)\n", newVertices, A3.x, A3.y);
    #endif // DEBUG_CONSOLE
        }
        else
        {
            // Add vertice between B2 and first point
            LargePoly->addVertice(LargePoly->_Vertices[0]);
            newVertices = LargePoly->_Vertices.size();
    #if DEBUG_CONSOLE > 1
            printf("Add 1 point (%d) (%3.f,%.3f) , closing polygon\n", newVertices, LargePoly->_Vertices[0].x, LargePoly->_Vertices[0].y);
    #endif // DEBUG_CONSOLE
        }
    }
    else
    {       //  No intersection, add point
            // Add vertice between B2 and first point
        LargePoly->addVertice(LargePoly->_Vertices[0]);
        newVertices = LargePoly->_Vertices.size();
#if DEBUG_CONSOLE > 1
        printf("NoIntersect, Add 1 point (%d) (%3.f,%.3f) , closing polygon\n", newVertices, LargePoly->_Vertices[0].x, LargePoly->_Vertices[0].y);
#endif // DEBUG_CONSOLE
    }
    LargePoly->CheckClosed();
    LargePoly->ReCalcBoundingBox();

    //  Now check that all edges of the enlarged polygon dont intersect
    //  If edge I (_Vertice[i] --> _Vertice[i+1]) intersect edge j (_Vertice[j] --> _Vertice[j+1] ) in point Ai with j > i
    //  1) Change _Vertice[i+1] to Ai
    //  2) Delete All vertices from i+2 to j
    //  The resulting polygon will have an edge from _Vertice[i] --> Ai and Ai --> Vertice[j] (with old indexes i and j).
#if DEBUG_CONSOLE > 0
    printf("Large Poly before post processing with %d (%zu) vertices\n", newVertices, LargePoly->_Vertices.size());
    for (int v = 0; v < newVertices; v++)
    {
        printf("Vertex %d : (%.3f,%.3f)\n", v, LargePoly->_Vertices[v].x, LargePoly->_Vertices[v].y);
    }
#endif
    //  After this step, remove vertices which are inside the polygon.
    //  The edges should never intersect
    int modified = true;
    Point Intersection;
    while ( modified )
    {
        modified = false;
        for (int i = 0; i < newVertices - 2; i++)
        {
            Segment AiBi = Segment(LargePoly->_Vertices[i], LargePoly->_Vertices[i+1]);
            for ( int j = i+2; j < newVertices - 1; j++)
            {
                if ( j == newVertices-2 && i == 0 ) break;      //  Do not check this case, last segment will always intersect first one !
                Segment AjBj = Segment(LargePoly->_Vertices[j],LargePoly->_Vertices[j+1]);
                if ( AiBi.isCrossing(&AjBj, &Intersection))
                {
                //  The two segments are crossing
                //  First change Bi to Intersection
#if DEBUG_CONSOLE > 0
                    printf("Intersection detected between segment %d (%.3f,%.3f -- %.3f,%.3f) and segment %d (%.3f,%.3f -- %.3f,%.3f)\n",
                                i, LargePoly->_Vertices[i].x, LargePoly->_Vertices[i].y, LargePoly->_Vertices[i+1].x, LargePoly->_Vertices[i+1].y,
                                j, LargePoly->_Vertices[j].x, LargePoly->_Vertices[j].y, LargePoly->_Vertices[j+1].x, LargePoly->_Vertices[j+1].y);
                    printf("Changing end of segment to intersection point (%.3f,%.3f)\n", Intersection.x, Intersection.y);
#endif
                //  Build 2 polygons, first one contains segments between i+1 (modified to intersection) and j also modified as intersection
                //  The second one contains all other points
                    Polygon *Poly1 = new Polygon;
                    Polygon *Poly2 = new Polygon;
                    for ( int k = 0; k < newVertices; k++)
                    {
                        if ( k < i || k > j )
                        {
                            Poly1->addVertice(LargePoly->_Vertices[k]);
                        }
                        else if ( k == i )
                        {
                            Poly1->addVertice(LargePoly->_Vertices[k]);
                            Poly1->addVertice(Intersection);
                        }
                        else if ( k == i+1 )
                        {
                            Poly2->addVertice(Intersection);
                            Poly2->addVertice(LargePoly->_Vertices[k]);
                        }
                        else if ( k < j )
                        {
                            Poly2->addVertice(LargePoly->_Vertices[k]);
                        }
                        else
                        {
                            Poly2->addVertice(LargePoly->_Vertices[k]);
                            Poly2->addVertice(Intersection);
                        }
                    }
                    //  Keep the largest one
                    double area1 = fabs(Poly1->area());
                    double area2 = fabs(Poly2->area());
                    if ( area1 > area2 )
                    {
#if DEBUG_CONSOLE > 0
                        printf("Area1 = %.3f, Area2 = %.3f, keep polygon1", area1, area2);
#endif
                        delete Poly2;
                        delete LargePoly;
                        LargePoly = Poly1;
                    }
                    else
                    {
#if DEBUG_CONSOLE > 0
                        printf("Area1 = %.3f, Area2 = %.3f, keep polygon2", area1, area2);
#endif
                        delete Poly1;
                        delete LargePoly;
                        LargePoly = Poly2;
                    }
                    newVertices = LargePoly->_Vertices.size();
                    modified = true;
                    break;
                }
            }
            if ( modified ) break;
        }

    }
    for (int i = 0; i < newVertices; i++)
    {
        if ( isInPoly(&LargePoly->_Vertices[i]) > 0 || distance(LargePoly->_Vertices[i]) < Diff - precision )
        {
            // Inside poly or too close, delete vertex
            LargePoly->delVertex(i);
            newVertices = LargePoly->nVertices;
        }
    }

    LargePoly->CheckClosed();
    LargePoly->ReCalcArea();
#if DEBUG_CONSOLE > 0
    Rectangle BBox = LargePoly->GetBoundingBox();
    printf("After postprocessing, %d vertices, area = %.3f, Bounding box (%.3f,%.3f) - (%.3f,%.3f), closed = %d\n",
        LargePoly->nVertices, LargePoly->area(), BBox.A.x, BBox.A.y, BBox.B.x, BBox.B.y, LargePoly->isClosed());
#endif
    return(LargePoly);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x138, %rsp            # imm = 0x138
movsd %xmm0, 0xb8(%rsp)
movq %rdi, %rbx
movl $0xc0, %edi
callq 0x7430
movq %rax, %r13
leaq 0x2af3f(%rip), %rax     # 0x51ca0
movq %rax, (%r13)
leaq 0x10(%r13), %rdi
xorl %ebp, %ebp
movl %ebp, 0x8(%r13)
movl $0x8c, %edx
movq %rdi, 0xe0(%rsp)
xorl %esi, %esi
callq 0x7270
xorpd %xmm0, %xmm0
movupd %xmm0, 0xb0(%r13)
movl $0x1, 0x9c(%r13)
movq $0x0, 0xa8(%r13)
movabsq $0x3f1a36e2eb1c432d, %rax # imm = 0x3F1A36E2EB1C432D
movq %rax, 0xa0(%r13)
incq 0x2bc42(%rip)           # 0x52a00
movl %ebp, 0xc(%r13)
incq 0x2bc67(%rip)           # 0x52a30
movsd 0x182f7(%rip), %xmm3    # 0x3f0c8
xorpd %xmm0, %xmm0
movsd %xmm0, 0x58(%rsp)
cmpl $0x2, 0x8(%rbx)
movq %rbx, 0x60(%rsp)
jl 0x27434
movq %r13, %r15
movsd 0x16213(%rip), %xmm1    # 0x3d008
movl $0x18, %r14d
xorl %r13d, %r13d
xorl %ebp, %ebp
xorl %r12d, %r12d
xorpd %xmm8, %xmm8
movapd %xmm1, %xmm7
movsd %xmm0, 0xb0(%rsp)
movsd %xmm1, 0xe8(%rsp)
movapd %xmm1, %xmm6
movapd %xmm1, %xmm3
movsd %xmm8, 0x110(%rsp)
movq 0x10(%rbx), %rax
movsd -0x18(%rax,%r14), %xmm5
movsd -0x10(%rax,%r14), %xmm9
movsd (%rax,%r14), %xmm10
movapd %xmm9, %xmm2
subsd %xmm10, %xmm2
movsd -0x8(%rax,%r14), %xmm11
movapd %xmm11, %xmm1
subsd %xmm5, %xmm1
movapd %xmm1, %xmm0
mulsd %xmm1, %xmm0
movapd %xmm2, %xmm8
mulsd %xmm2, %xmm8
addsd %xmm8, %xmm0
ucomisd 0x18257(%rip), %xmm0    # 0x3f0d8
movapd %xmm1, 0xa0(%rsp)
movapd %xmm2, 0x90(%rsp)
movsd %xmm6, 0xc0(%rsp)
movsd %xmm3, 0x38(%rsp)
movsd %xmm7, 0x68(%rsp)
jb 0x26eb3
xorps %xmm3, %xmm3
sqrtsd %xmm0, %xmm3
jmp 0x26f21
movapd %xmm8, 0x80(%rsp)
movsd %xmm5, 0x10(%rsp)
movsd %xmm9, (%rsp)
movsd %xmm10, 0x20(%rsp)
movsd %xmm11, 0xd0(%rsp)
callq 0x7370
movsd 0xd0(%rsp), %xmm11
movsd 0x20(%rsp), %xmm10
movsd (%rsp), %xmm9
movsd 0x10(%rsp), %xmm5
movapd 0x80(%rsp), %xmm8
movapd 0x90(%rsp), %xmm2
movapd 0xa0(%rsp), %xmm1
movq 0x60(%rsp), %rbx
movapd %xmm0, %xmm3
movsd 0x1819f(%rip), %xmm4    # 0x3f0c8
mulsd %xmm11, %xmm9
mulsd %xmm10, %xmm5
subsd %xmm9, %xmm5
mulsd 0xb8(%rsp), %xmm3
addsd %xmm5, %xmm3
movapd %xmm1, %xmm6
movapd 0x1812f(%rip), %xmm0    # 0x3f080
xorpd %xmm0, %xmm6
movq 0x10(%rbx), %rax
movapd %xmm2, %xmm5
xorpd %xmm0, %xmm5
movsd (%rax,%r14), %xmm10
mulsd %xmm2, %xmm10
movsd -0x8(%rax,%r14), %xmm7
mulsd %xmm1, %xmm7
mulsd %xmm1, %xmm6
subsd %xmm8, %xmm6
movapd %xmm6, %xmm11
andpd 0x180a2(%rip), %xmm11   # 0x3f030
ucomisd %xmm11, %xmm4
movsd %xmm3, 0x80(%rsp)
movapd %xmm5, 0xd0(%rsp)
jbe 0x27014
leaq 0x19283(%rip), %rdi     # 0x40231
movsd %xmm7, 0x10(%rsp)
movapd %xmm6, (%rsp)
movsd %xmm10, 0x20(%rsp)
movapd %xmm11, 0x70(%rsp)
callq 0x70b0
movapd 0x70(%rsp), %xmm11
movsd 0x20(%rsp), %xmm10
movapd (%rsp), %xmm6
movsd 0x10(%rsp), %xmm7
movsd 0x180db(%rip), %xmm4    # 0x3f0c8
movsd 0x80(%rsp), %xmm3
movapd 0x90(%rsp), %xmm2
movapd 0xa0(%rsp), %xmm1
movapd %xmm0, %xmm8
movapd %xmm0, %xmm9
jmp 0x27064
movsd -0x10(%rax,%r14), %xmm0
mulsd %xmm5, %xmm0
movsd -0x18(%rax,%r14), %xmm8
mulsd %xmm1, %xmm8
addsd %xmm0, %xmm8
movapd %xmm1, %xmm0
mulsd %xmm8, %xmm0
movapd %xmm2, %xmm9
mulsd %xmm3, %xmm9
subsd %xmm0, %xmm9
divsd %xmm6, %xmm9
movapd %xmm1, %xmm0
mulsd %xmm3, %xmm0
mulsd %xmm2, %xmm8
addsd %xmm0, %xmm8
divsd %xmm6, %xmm8
ucomisd %xmm11, %xmm4
movsd %xmm8, (%rsp)
movapd %xmm9, 0x20(%rsp)
jbe 0x2709c
leaq 0x191b2(%rip), %rdi     # 0x40231
callq 0x70b0
movapd 0x20(%rsp), %xmm9
movsd (%rsp), %xmm8
movapd %xmm0, %xmm7
movapd %xmm0, %xmm11
jmp 0x270d1
subsd %xmm10, %xmm7
movapd %xmm1, %xmm0
mulsd %xmm7, %xmm0
movapd %xmm2, %xmm11
mulsd %xmm3, %xmm11
subsd %xmm0, %xmm11
divsd %xmm6, %xmm11
movapd %xmm1, %xmm0
mulsd %xmm3, %xmm0
mulsd %xmm2, %xmm7
addsd %xmm0, %xmm7
divsd %xmm6, %xmm7
movapd %xmm9, %xmm4
subsd %xmm11, %xmm4
movapd %xmm8, %xmm10
subsd %xmm7, %xmm10
movapd %xmm10, %xmm1
mulsd %xmm10, %xmm1
movapd %xmm4, %xmm0
mulsd %xmm4, %xmm0
addsd %xmm1, %xmm0
ucomisd 0x17fd5(%rip), %xmm0    # 0x3f0d8
jb 0x2710b
sqrtsd %xmm0, %xmm0
jmp 0x2715d
movsd %xmm7, 0x10(%rsp)
movsd %xmm10, 0x70(%rsp)
movsd %xmm4, 0x100(%rsp)
movapd %xmm11, 0xf0(%rsp)
callq 0x7370
movapd 0xf0(%rsp), %xmm11
movsd 0x100(%rsp), %xmm4
movsd 0x70(%rsp), %xmm10
movapd 0x20(%rsp), %xmm9
movsd (%rsp), %xmm8
movsd 0x10(%rsp), %xmm7
movsd 0x17f63(%rip), %xmm3    # 0x3f0c8
movsd 0x38(%rsp), %xmm5
movsd 0x68(%rsp), %xmm6
movsd 0xb8(%rsp), %xmm2
divsd %xmm0, %xmm2
mulsd %xmm2, %xmm4
mulsd %xmm2, %xmm10
addsd %xmm9, %xmm4
addsd %xmm8, %xmm10
movsd %xmm4, 0x40(%rsp)
movsd %xmm10, 0x48(%rsp)
movapd %xmm11, %xmm1
subsd %xmm9, %xmm1
movapd %xmm7, %xmm0
subsd %xmm8, %xmm0
mulsd %xmm2, %xmm1
mulsd %xmm2, %xmm0
addsd %xmm11, %xmm1
addsd %xmm7, %xmm0
movsd %xmm1, 0x128(%rsp)
movsd %xmm0, 0x130(%rsp)
ucomisd %xmm4, %xmm4
movapd %xmm1, %xmm7
jp 0x271e6
movapd %xmm1, %xmm7
maxsd %xmm4, %xmm7
ucomisd %xmm10, %xmm10
movapd %xmm0, %xmm8
jp 0x271fc
movapd %xmm0, %xmm8
maxsd %xmm10, %xmm8
movapd %xmm4, %xmm9
cmpunordsd %xmm4, %xmm9
movapd %xmm9, %xmm2
andpd %xmm1, %xmm2
minsd %xmm4, %xmm1
andnpd %xmm1, %xmm9
orpd %xmm2, %xmm9
movsd 0x17eaa(%rip), %xmm2    # 0x3f0d0
addsd %xmm2, %xmm9
addsd %xmm3, %xmm7
movapd %xmm10, %xmm4
cmpunordsd %xmm10, %xmm4
movapd %xmm4, %xmm1
andpd %xmm0, %xmm1
minsd %xmm10, %xmm0
andnpd %xmm0, %xmm4
orpd %xmm1, %xmm4
addsd %xmm2, %xmm4
movapd %xmm4, 0x10(%rsp)
addsd %xmm3, %xmm8
testb $0x1, %bpl
movapd %xmm7, (%rsp)
movapd %xmm8, 0x20(%rsp)
movapd %xmm9, 0x70(%rsp)
je 0x272d6
movapd 0xd0(%rsp), %xmm0
mulsd %xmm5, %xmm0
movapd %xmm6, %xmm4
movapd 0xa0(%rsp), %xmm2
mulsd %xmm2, %xmm4
addsd %xmm0, %xmm4
movapd %xmm4, %xmm1
andpd 0x17d8b(%rip), %xmm1    # 0x3f030
ucomisd %xmm1, %xmm3
movq %r15, %rbx
jbe 0x2731f
leaq 0x18f7c(%rip), %rdi     # 0x40231
callq 0x70b0
movapd 0x70(%rsp), %xmm9
movapd 0x20(%rsp), %xmm8
movapd (%rsp), %xmm7
movapd %xmm0, %xmm5
jmp 0x2735a
movq %r15, %rbx
movq %r15, %rdi
leaq 0x40(%rsp), %rsi
callq 0x266b0
movaps 0x90(%rsp), %xmm0
movsd %xmm0, 0xc0(%rsp)
movaps 0xa0(%rsp), %xmm0
movsd %xmm0, 0xe8(%rsp)
movsd 0x80(%rsp), %xmm0
movsd %xmm0, 0xb0(%rsp)
jmp 0x273a7
movapd %xmm2, %xmm1
movsd 0x110(%rsp), %xmm0
mulsd %xmm0, %xmm1
movsd 0x80(%rsp), %xmm2
mulsd %xmm2, %xmm5
subsd %xmm1, %xmm5
divsd %xmm4, %xmm5
mulsd %xmm2, %xmm6
mulsd 0x90(%rsp), %xmm0
subsd %xmm6, %xmm0
divsd %xmm4, %xmm0
ucomisd %xmm5, %xmm9
ja 0x2739a
ucomisd %xmm7, %xmm5
ja 0x2739a
movapd 0x10(%rsp), %xmm1
ucomisd %xmm0, %xmm1
ja 0x2739a
ucomisd %xmm8, %xmm0
ja 0x2739a
movq 0xe0(%rsp), %rax
movq (%rax), %rax
movslq %r12d, %rcx
shlq $0x4, %rcx
movsd %xmm5, -0x10(%rax,%rcx)
movsd %xmm0, -0x8(%rax,%rcx)
jmp 0x273a7
movq %rbx, %rdi
leaq 0x40(%rsp), %rsi
callq 0x266b0
incq %r13
movq %rbx, %rdi
leaq 0x128(%rsp), %rsi
callq 0x266b0
movq 0x18(%rbx), %r12
subq 0x10(%rbx), %r12
shrq $0x4, %r12
movq 0x60(%rsp), %rbx
movslq 0x8(%rbx), %rax
decq %rax
addq $0x10, %r14
movb $0x1, %bpl
cmpq %rax, %r13
movsd 0x17ce4(%rip), %xmm3    # 0x3f0c8
movapd 0xa0(%rsp), %xmm1
movsd 0xc0(%rsp), %xmm6
movapd 0x90(%rsp), %xmm7
movsd 0x80(%rsp), %xmm8
jl 0x26e22
movq %r15, %r13
movq %r12, %rbp
movsd 0xe8(%rsp), %xmm5
movapd (%rsp), %xmm9
movapd 0x20(%rsp), %xmm10
movapd 0x70(%rsp), %xmm11
jmp 0x27470
movsd 0x17c93(%rip), %xmm11   # 0x3f0d0
movsd 0x15bc3(%rip), %xmm6    # 0x3d008
movapd %xmm6, %xmm5
movsd %xmm0, 0xb0(%rsp)
movapd %xmm6, %xmm7
movapd %xmm6, %xmm1
xorpd %xmm8, %xmm8
movapd %xmm3, %xmm9
movapd %xmm11, 0x10(%rsp)
movapd %xmm3, %xmm10
movapd %xmm5, %xmm0
mulsd %xmm7, %xmm0
movapd %xmm6, %xmm2
mulsd %xmm1, %xmm2
subsd %xmm0, %xmm2
movapd %xmm1, %xmm4
movapd 0x17ba0(%rip), %xmm1    # 0x3f030
andpd %xmm2, %xmm1
ucomisd %xmm1, %xmm3
xorpd %xmm0, %xmm0
ja 0x274d3
movsd 0xb0(%rsp), %xmm0
mulsd %xmm0, %xmm4
mulsd %xmm8, %xmm5
subsd %xmm4, %xmm5
divsd %xmm2, %xmm5
mulsd %xmm8, %xmm6
mulsd %xmm0, %xmm7
subsd %xmm6, %xmm7
divsd %xmm2, %xmm7
movsd %xmm7, 0x58(%rsp)
movapd %xmm5, %xmm0
movsd 0x17bed(%rip), %xmm2    # 0x3f0c8
ucomisd %xmm1, %xmm2
ja 0x27539
ucomisd %xmm0, %xmm11
movq 0xe0(%rsp), %rax
movq (%rax), %rsi
ja 0x2753d
ucomisd %xmm9, %xmm0
ja 0x2753d
movapd 0x10(%rsp), %xmm1
ucomisd 0x58(%rsp), %xmm1
ja 0x2753d
movsd 0x58(%rsp), %xmm1
ucomisd %xmm10, %xmm1
ja 0x2753d
movslq %ebp, %rax
shlq $0x4, %rax
movsd %xmm0, -0x10(%rsi,%rax)
movsd 0x58(%rsp), %xmm1
movsd %xmm1, -0x8(%rsi,%rax)
movsd %xmm0, (%rsi)
movsd %xmm1, 0x8(%rsi)
jmp 0x27551
movq 0x10(%r13), %rsi
movq %r13, %rdi
callq 0x266b0
movq 0x18(%r13), %rbp
subq 0x10(%r13), %rbp
shrq $0x4, %rbp
movq 0x10(%r13), %rax
movslq 0x8(%r13), %rcx
shlq $0x4, %rcx
movsd 0x8(%rax), %xmm0
movsd -0x8(%rax,%rcx), %xmm1
movsd -0x10(%rax,%rcx), %xmm2
movsd (%rax), %xmm3
cmpeqpd %xmm2, %xmm3
cmpeqpd %xmm0, %xmm1
andpd %xmm3, %xmm1
movd %xmm1, %eax
andl $0x1, %eax
movl %eax, 0x98(%r13)
movq %r13, %rdi
callq 0x27c90
xorpd %xmm0, %xmm0
leaq 0x40(%rsp), %rax
movapd %xmm0, (%rax)
movl $0x2, %r15d
movapd 0x17a7e(%rip), %xmm13   # 0x3f030
xorl %edi, %edi
xorl %eax, %eax
movsd 0x17b09(%rip), %xmm12   # 0x3f0c8
leal -0x2(%rbp), %ecx
movslq %ecx, %rcx
cmpq %rcx, %rdi
jge 0x27bad
movq 0x10(%r13), %rcx
movq %rdi, %rdx
shlq $0x4, %rdx
leaq 0x1(%rdi), %rsi
movq %rsi, 0x90(%rsp)
shlq $0x4, %rsi
movsd (%rcx,%rdx), %xmm0
movsd (%rcx,%rsi), %xmm15
movapd %xmm0, %xmm5
ucomisd %xmm0, %xmm0
movapd %xmm15, 0x10(%rsp)
jp 0x27614
movapd %xmm15, %xmm0
maxsd %xmm5, %xmm0
movapd %xmm0, 0x10(%rsp)
movsd 0x8(%rcx,%rdx), %xmm0
movsd 0x8(%rcx,%rsi), %xmm1
ucomisd %xmm0, %xmm0
movapd %xmm1, (%rsp)
jp 0x27638
movapd %xmm1, %xmm2
maxsd %xmm0, %xmm2
movapd %xmm2, (%rsp)
leaq 0x2(%rdi), %rcx
leal -0x1(%rbp), %edx
movslq %edx, %rdx
cmpq %rdx, %rcx
movq %r15, 0xf0(%rsp)
jge 0x27b92
movapd %xmm5, %xmm6
cmpunordsd %xmm5, %xmm6
movapd %xmm6, %xmm2
andpd %xmm15, %xmm2
movapd %xmm15, %xmm3
minsd %xmm5, %xmm3
andnpd %xmm3, %xmm6
orpd %xmm2, %xmm6
movsd 0x17a52(%rip), %xmm4    # 0x3f0d0
addsd %xmm4, %xmm6
movapd %xmm6, 0x70(%rsp)
movapd 0x10(%rsp), %xmm2
addsd %xmm12, %xmm2
movapd %xmm2, 0x10(%rsp)
movapd %xmm0, %xmm6
cmpunordsd %xmm0, %xmm6
movapd %xmm6, %xmm2
andpd %xmm1, %xmm2
movapd %xmm1, %xmm3
minsd %xmm0, %xmm3
andnpd %xmm3, %xmm6
orpd %xmm2, %xmm6
addsd %xmm4, %xmm6
movapd %xmm6, 0x100(%rsp)
movapd (%rsp), %xmm2
addsd %xmm12, %xmm2
movapd %xmm2, (%rsp)
movapd %xmm0, %xmm2
subsd %xmm1, %xmm2
mulsd %xmm15, %xmm0
subsd %xmm5, %xmm15
mulsd %xmm1, %xmm5
subsd %xmm0, %xmm5
movsd %xmm5, 0x20(%rsp)
movapd %xmm2, 0x110(%rsp)
xorpd 0x17979(%rip), %xmm2    # 0x3f080
movapd %xmm2, 0x80(%rsp)
movq %rdi, 0xa0(%rsp)
movapd %xmm15, 0xd0(%rsp)
testq %rdi, %rdi
jne 0x27733
leal -0x2(%rbp), %ecx
cmpq %rcx, %r15
je 0x27b92
movq 0x10(%r13), %rcx
movq %r15, %rdx
shlq $0x4, %rdx
leaq 0x1(%r15), %rbx
movq %rbx, %rsi
shlq $0x4, %rsi
movsd (%rcx,%rdx), %xmm5
movsd (%rcx,%rsi), %xmm4
ucomisd %xmm5, %xmm5
movapd %xmm4, %xmm0
jp 0x27765
movapd %xmm4, %xmm0
maxsd %xmm5, %xmm0
movsd 0x8(%rcx,%rdx), %xmm3
movsd 0x8(%rcx,%rsi), %xmm2
ucomisd %xmm3, %xmm3
movapd %xmm2, %xmm1
jp 0x27783
movapd %xmm2, %xmm1
maxsd %xmm3, %xmm1
movapd %xmm3, %xmm10
subsd %xmm2, %xmm10
movapd %xmm4, %xmm8
subsd %xmm5, %xmm8
movapd %xmm8, %xmm6
mulsd 0x80(%rsp), %xmm6
movapd %xmm10, %xmm11
mulsd %xmm15, %xmm11
addsd %xmm6, %xmm11
movapd %xmm11, %xmm9
andpd %xmm13, %xmm9
xorpd %xmm6, %xmm6
ucomisd %xmm9, %xmm12
xorpd %xmm7, %xmm7
ja 0x2781d
movapd %xmm3, %xmm7
mulsd %xmm4, %xmm7
movapd %xmm5, %xmm6
mulsd %xmm2, %xmm6
subsd %xmm7, %xmm6
movapd %xmm15, %xmm7
mulsd %xmm6, %xmm7
movsd 0x20(%rsp), %xmm14
mulsd %xmm14, %xmm8
subsd %xmm7, %xmm8
divsd %xmm11, %xmm8
mulsd %xmm14, %xmm10
mulsd 0x110(%rsp), %xmm6
subsd %xmm10, %xmm6
divsd %xmm11, %xmm6
movapd %xmm8, %xmm7
movb $0x1, %sil
ucomisd %xmm9, %xmm12
ja 0x278fa
movsd %xmm7, 0x40(%rsp)
movsd %xmm6, 0x48(%rsp)
movapd 0x70(%rsp), %xmm8
ucomisd %xmm7, %xmm8
ja 0x278fa
ucomisd 0x10(%rsp), %xmm7
ja 0x278fa
movapd 0x100(%rsp), %xmm8
ucomisd %xmm6, %xmm8
ja 0x278fa
ucomisd (%rsp), %xmm6
ja 0x278fa
movapd %xmm5, %xmm8
cmpunordsd %xmm5, %xmm8
movapd %xmm8, %xmm9
andpd %xmm4, %xmm9
minsd %xmm5, %xmm4
andnpd %xmm4, %xmm8
orpd %xmm9, %xmm8
movsd 0x1782f(%rip), %xmm9    # 0x3f0d0
addsd %xmm9, %xmm8
addsd %xmm12, %xmm0
movapd %xmm3, %xmm4
cmpunordsd %xmm3, %xmm4
movapd %xmm4, %xmm5
andpd %xmm2, %xmm5
minsd %xmm3, %xmm2
andnpd %xmm2, %xmm4
orpd %xmm5, %xmm4
addsd %xmm9, %xmm4
addsd %xmm12, %xmm1
cmpltpd %xmm7, %xmm0
cmpltpd %xmm8, %xmm7
orpd %xmm0, %xmm7
movd %xmm7, %ecx
ucomisd %xmm6, %xmm4
seta %dl
ucomisd %xmm1, %xmm6
seta %sil
orb %dl, %sil
orb %cl, %sil
testb $0x1, %sil
jne 0x27b7e
movb %sil, 0x68(%rsp)
movq %rbx, 0x38(%rsp)
movq %r13, %r14
movl $0xc0, %edi
callq 0x7430
movq %rax, %r12
leaq 0x2a37b(%rip), %rax     # 0x51ca0
movq %rax, (%r12)
leaq 0x10(%r12), %rdi
xorl %eax, %eax
movl %eax, 0x8(%r12)
movl $0x8c, %edx
xorl %esi, %esi
callq 0x7270
xorpd %xmm0, %xmm0
movupd %xmm0, 0xb0(%r12)
movl $0x1, %eax
movl %eax, 0x9c(%r12)
xorl %ecx, %ecx
movq %rcx, 0xa8(%r12)
movabsq $0x3f1a36e2eb1c432d, %rax # imm = 0x3F1A36E2EB1C432D
movq %rax, 0xa0(%r12)
movl %ecx, 0xc(%r12)
movq 0x2b07c(%rip), %rbx     # 0x52a00
leaq 0x1(%rbx), %rax
movq %rax, 0x2b071(%rip)     # 0x52a00
movq %rbp, 0xc0(%rsp)
movq 0x2b092(%rip), %rbp     # 0x52a30
leaq 0x1(%rbp), %rax
movq %rax, 0x2b087(%rip)     # 0x52a30
movl $0xc0, %edi
callq 0x7430
movq %rax, %r13
leaq 0x2a2e3(%rip), %rax     # 0x51ca0
movq %rax, (%r13)
leaq 0x10(%r13), %rdi
xorl %eax, %eax
movl %eax, 0x8(%r13)
movl $0x8c, %edx
xorl %esi, %esi
callq 0x7270
xorpd %xmm0, %xmm0
movupd %xmm0, 0xb0(%r13)
movl $0x1, %eax
movl %eax, 0x9c(%r13)
xorl %eax, %eax
movq %rax, 0xa8(%r13)
movabsq $0x3f1a36e2eb1c432d, %rcx # imm = 0x3F1A36E2EB1C432D
movq %rcx, 0xa0(%r13)
movl %eax, 0xc(%r13)
addq $0x2, %rbx
movq %rbx, 0x2afe7(%rip)     # 0x52a00
addq $0x2, %rbp
movq %rbp, 0x2b00c(%rip)     # 0x52a30
movq 0xc0(%rsp), %rax
testl %eax, %eax
jle 0x27ad3
movl %eax, %ebx
xorl %ebp, %ebp
movq 0xa0(%rsp), %rdx
cmpq %rdx, %rbp
setae %al
cmpq %r15, %rbp
setbe %cl
testb %cl, %al
jne 0x27a60
movq %rbp, %rsi
shlq $0x4, %rsi
addq 0x10(%r14), %rsi
movq %r12, %rdi
jmp 0x27aa7
cmpq %rdx, %rbp
jne 0x27a82
movq %rbp, %rsi
shlq $0x4, %rsi
addq 0x10(%r14), %rsi
movq %r12, %rdi
callq 0x266b0
movq %r12, %rdi
leaq 0x40(%rsp), %rsi
jmp 0x27aa7
cmpq 0x90(%rsp), %rbp
jne 0x27ab6
movq %r13, %rdi
leaq 0x40(%rsp), %rsi
callq 0x266b0
movq %rbp, %rsi
shlq $0x4, %rsi
addq 0x10(%r14), %rsi
movq %r13, %rdi
callq 0x266b0
incq %rbp
cmpq %rbx, %rbp
jne 0x27a38
jmp 0x27ad3
movq %rbp, %rsi
shlq $0x4, %rsi
addq 0x10(%r14), %rsi
movq %r13, %rdi
callq 0x266b0
cmpq %r15, %rbp
jb 0x27aac
movq %r13, %rdi
jmp 0x27a7b
movq %r12, %rdi
callq 0x26926
movapd %xmm0, %xmm1
movapd 0x17549(%rip), %xmm0    # 0x3f030
andpd %xmm0, %xmm1
movapd %xmm1, 0xc0(%rsp)
movq %r13, %rdi
callq 0x26926
andpd 0x1752c(%rip), %xmm0    # 0x3f030
movapd 0xc0(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x27b1f
movq (%r13), %rax
movq %r13, %rdi
callq *0x8(%rax)
jmp 0x27b2c
movq (%r12), %rax
movq %r12, %rdi
callq *0x8(%rax)
movq %r13, %r12
testq %r14, %r14
movq 0x38(%rsp), %rbx
je 0x27b3f
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
movq 0x18(%r12), %rbp
subq 0x10(%r12), %rbp
shrq $0x4, %rbp
movl $0x1, %eax
movq %r12, %r13
movsd 0x1756a(%rip), %xmm12   # 0x3f0c8
movapd 0x174c9(%rip), %xmm13   # 0x3f030
movq 0xa0(%rsp), %rdi
movapd 0xd0(%rsp), %xmm15
movb 0x68(%rsp), %sil
leal -0x1(%rbp), %ecx
cmpl %ebx, %ecx
setg %cl
movq %rbx, %r15
testb %cl, %sil
jne 0x27722
movq 0xf0(%rsp), %r15
incq %r15
movq 0x90(%rsp), %rdi
testl %eax, %eax
je 0x275bf
xorl %edi, %edi
movl $0x2, %r15d
testl %eax, %eax
movl $0x0, %eax
jne 0x275bf
testl %ebp, %ebp
jle 0x27c2b
xorl %ebx, %ebx
xorl %r15d, %r15d
movq 0x60(%rsp), %r14
movq 0x10(%r13), %r12
addq %rbx, %r12
movq 0x60(%rsp), %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x27d3a
testl %eax, %eax
jg 0x27c0d
movq %r14, %rdi
movq %r12, %rsi
callq 0x269c4
movsd 0xb8(%rsp), %xmm1
subsd 0xa0(%r14), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x27c1c
movq %r13, %rdi
movl %r15d, %esi
callq 0x281be
movl 0x8(%r13), %ebp
incq %r15
movslq %ebp, %rax
addq $0x10, %rbx
cmpq %rax, %r15
jl 0x27bd0
movq 0x10(%r13), %rax
movslq 0x8(%r13), %rcx
shlq $0x4, %rcx
movsd 0x8(%rax), %xmm0
movsd -0x8(%rax,%rcx), %xmm1
movsd -0x10(%rax,%rcx), %xmm2
movsd (%rax), %xmm3
cmpeqpd %xmm2, %xmm3
cmpeqpd %xmm0, %xmm1
andpd %xmm3, %xmm1
movd %xmm1, %eax
andl $0x1, %eax
movl %eax, 0x98(%r13)
movl $0x1, 0x9c(%r13)
movq %r13, %rdi
callq 0x26926
movq %r13, %rax
addq $0x138, %rsp            # imm = 0x138
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq