// File: /workspace/github_cpp_makefile_star2_O3/rurban[P]dgnlib/dgnstroke.cpp
// Function: DGNStrokeCurve
int DGNStrokeCurve( DGNHandle hFile, DGNElemMultiPoint *psCurve, 
                    int nPoints, DGNPoint * pasPoints )

{
    int         k, nDGNPoints, iOutPoint;
    double      *padfMx, *padfMy, *padfD, dfTotalD = 0, dfStepSize, dfD;
    double      *padfTx, *padfTy;
    DGNPoint    *pasDGNPoints = psCurve->vertices;

    nDGNPoints = psCurve->num_vertices;

    if( nDGNPoints < 6 )
        return FALSE;

    if( nPoints < nDGNPoints - 4 )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Compute the Compute the slopes/distances of the segments.       */
/* -------------------------------------------------------------------- */
    padfMx = (double *) CPLMalloc(sizeof(double) * nDGNPoints);
    padfMy = (double *) CPLMalloc(sizeof(double) * nDGNPoints);
    padfD  = (double *) CPLMalloc(sizeof(double) * nDGNPoints);
    padfTx = (double *) CPLMalloc(sizeof(double) * nDGNPoints);
    padfTy = (double *) CPLMalloc(sizeof(double) * nDGNPoints);

    for( k = 0; k < nDGNPoints-1; k++ )
    {
        padfD[k] = sqrt( (pasDGNPoints[k+1].x-pasDGNPoints[k].x)
                           * (pasDGNPoints[k+1].x-pasDGNPoints[k].x)
                         + (pasDGNPoints[k+1].y-pasDGNPoints[k].y)
                           * (pasDGNPoints[k+1].y-pasDGNPoints[k].y) );
        if( padfD[k] == 0.0 )
        {
            padfD[k] = 0.0001;
            padfMx[k] = 0.0;
            padfMy[k] = 0.0;
        }
        else
        {
            padfMx[k] = (pasDGNPoints[k+1].x - pasDGNPoints[k].x) / padfD[k];
            padfMy[k] = (pasDGNPoints[k+1].y - pasDGNPoints[k].y) / padfD[k];
        }

        if( k > 1 && k < nDGNPoints - 3 )
            dfTotalD += padfD[k];
    }

/* -------------------------------------------------------------------- */
/*      Compute the Tx, and Ty coefficients for each segment.           */
/* -------------------------------------------------------------------- */
    for( k = 2; k < nDGNPoints - 2; k++ )
    {
        if( fabs(padfMx[k+1] - padfMx[k]) == 0.0
            && fabs(padfMx[k-1] - padfMx[k-2]) == 0.0 )
        {
            padfTx[k] = (padfMx[k] + padfMx[k-1]) / 2;
        }
        else
        {
            padfTx[k] = (padfMx[k-1] * fabs( padfMx[k+1] - padfMx[k])
                    + padfMx[k] * fabs( padfMx[k-1] - padfMx[k-2] ))
           / (ABS(padfMx[k+1] - padfMx[k]) + ABS(padfMx[k-1] - padfMx[k-2]));
        }

        if( fabs(padfMy[k+1] - padfMy[k]) == 0.0
            && fabs(padfMy[k-1] - padfMy[k-2]) == 0.0 )
        {
            padfTy[k] = (padfMy[k] + padfMy[k-1]) / 2;
        }
        else
        {
            padfTy[k] = (padfMy[k-1] * fabs( padfMy[k+1] - padfMy[k])
                    + padfMy[k] * fabs( padfMy[k-1] - padfMy[k-2] ))
            / (ABS(padfMy[k+1] - padfMy[k]) + ABS(padfMy[k-1] - padfMy[k-2]));
        }
    }

/* -------------------------------------------------------------------- */
/*      Determine a step size in D.  We scale things so that we have    */
/*      roughly equidistant steps in D, but assume we also want to      */
/*      include every node along the way.                               */
/* -------------------------------------------------------------------- */
    dfStepSize = dfTotalD / (nPoints - (nDGNPoints - 4) - 1);

/* ==================================================================== */
/*      Process each of the segments.                                   */
/* ==================================================================== */
    dfD = dfStepSize;
    iOutPoint = 0;

    for( k = 2; k < nDGNPoints - 3; k++ )
    {
        double  dfAx, dfAy, dfBx, dfBy, dfCx, dfCy;

/* -------------------------------------------------------------------- */
/*      Compute the "x" coefficients for this segment.                  */
/* -------------------------------------------------------------------- */
        dfCx = padfTx[k];
        dfBx = (3.0 * (pasDGNPoints[k+1].x - pasDGNPoints[k].x) / padfD[k]
                - 2.0 * padfTx[k] - padfTx[k+1]) / padfD[k];
        dfAx = (padfTx[k] + padfTx[k+1] 
                - 2 * (pasDGNPoints[k+1].x - pasDGNPoints[k].x) / padfD[k])
            / (padfD[k] * padfD[k]);

/* -------------------------------------------------------------------- */
/*      Compute the Y coefficients for this segment.                    */
/* -------------------------------------------------------------------- */
        dfCy = padfTy[k];
        dfBy = (3.0 * (pasDGNPoints[k+1].y - pasDGNPoints[k].y) / padfD[k]
                - 2.0 * padfTy[k] - padfTy[k+1]) / padfD[k];
        dfAy = (padfTy[k] + padfTy[k+1] 
                - 2 * (pasDGNPoints[k+1].y - pasDGNPoints[k].y) / padfD[k])
            / (padfD[k] * padfD[k]);

/* -------------------------------------------------------------------- */
/*      Add the start point for this segment.                           */
/* -------------------------------------------------------------------- */
        pasPoints[iOutPoint].x = pasDGNPoints[k].x;
        pasPoints[iOutPoint].y = pasDGNPoints[k].y;
        pasPoints[iOutPoint].z = 0.0;
        iOutPoint++;

/* -------------------------------------------------------------------- */
/*      Step along, adding intermediate points.                         */
/* -------------------------------------------------------------------- */
        while( dfD < padfD[k] && iOutPoint < nPoints - (nDGNPoints-k-1) )
        {
            pasPoints[iOutPoint].x = dfAx * dfD * dfD * dfD
                                   + dfBx * dfD * dfD
                                   + dfCx * dfD 
                                   + pasDGNPoints[k].x;
            pasPoints[iOutPoint].y = dfAy * dfD * dfD * dfD
                                   + dfBy * dfD * dfD
                                   + dfCy * dfD 
                                   + pasDGNPoints[k].y;
            pasPoints[iOutPoint].z = 0.0;
            iOutPoint++;

            dfD += dfStepSize;
        }

        dfD -= padfD[k];
    }

/* -------------------------------------------------------------------- */
/*      Add the start point for this segment.                           */
/* -------------------------------------------------------------------- */
    while( iOutPoint < nPoints )
    {
        pasPoints[iOutPoint].x = pasDGNPoints[nDGNPoints-3].x;
        pasPoints[iOutPoint].y = pasDGNPoints[nDGNPoints-3].y;
        pasPoints[iOutPoint].z = 0.0;
        iOutPoint++;
    }

/* -------------------------------------------------------------------- */
/*      Cleanup.                                                        */
/* -------------------------------------------------------------------- */
    CPLFree( padfMx );
    CPLFree( padfMy );
    CPLFree( padfD );
    CPLFree( padfTx );
    CPLFree( padfTy );

    return TRUE;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, 0x18(%rsp)
movq %rsi, %rbx
movl 0x50(%rsi), %ecx
cmpl $0x6, %ecx
setl %dil
leal -0x4(%rcx), %eax
cmpl %edx, %eax
setg %sil
xorl %eax, %eax
orb %dil, %sil
jne 0xea6b
movl %edx, 0xc(%rsp)
leaq 0x58(%rbx), %rax
movq %rax, 0x20(%rsp)
movl %ecx, %eax
movq %rax, 0x10(%rsp)
leaq (,%rax,8), %rbp
movq %rbp, %rdi
callq 0x2d6b
movq %rax, %r14
movq %rbp, %rdi
callq 0x2d6b
movq %rax, %r15
movq %rbp, %rdi
callq 0x2d6b
movq %rax, %r12
movq %rbp, %rdi
callq 0x2d6b
movq %rax, %r13
movq %rbp, %rdi
callq 0x2d6b
movq %rax, %rbp
movq 0x10(%rsp), %rcx
leal -0x1(%rcx), %eax
movq %rcx, %rdi
addl $-0x3, %ecx
addq $0x78, %rbx
xorpd %xmm1, %xmm1
xorl %edx, %edx
movabsq $0x3f1a36e2eb1c432d, %rsi # imm = 0x3F1A36E2EB1C432D
xorpd %xmm0, %xmm0
movsd -0x8(%rbx), %xmm2
movsd (%rbx), %xmm3
subsd -0x20(%rbx), %xmm2
subsd -0x18(%rbx), %xmm3
mulsd %xmm3, %xmm3
mulsd %xmm2, %xmm2
addsd %xmm3, %xmm2
sqrtsd %xmm2, %xmm2
movsd %xmm2, (%r12,%rdx,8)
ucomisd %xmm1, %xmm2
jne 0xe6b9
jp 0xe6b9
movq %rsi, (%r12,%rdx,8)
movq $0x0, (%r14,%rdx,8)
xorpd %xmm2, %xmm2
jmp 0xe6dc
movsd -0x8(%rbx), %xmm3
subsd -0x20(%rbx), %xmm3
divsd %xmm2, %xmm3
movsd %xmm3, (%r14,%rdx,8)
movsd (%rbx), %xmm2
subsd -0x18(%rbx), %xmm2
divsd (%r12,%rdx,8), %xmm2
movsd %xmm2, (%r15,%rdx,8)
cmpq $0x2, %rdx
jb 0xe6f3
cmpq %rcx, %rdx
jae 0xe6f3
addsd (%r12,%rdx,8), %xmm0
incq %rdx
addq $0x18, %rbx
cmpq %rdx, %rax
jne 0xe676
leal -0x2(%rdi), %eax
leaq -0x10(,%rax,8), %rax
xorl %ecx, %ecx
xorpd %xmm1, %xmm1
movsd 0xf2c(%rip), %xmm2      # 0xf648
movapd 0x26bc(%rip), %xmm3     # 0x10de0
movapd 0xb24(%rip), %xmm4      # 0xf250
movl 0xc(%rsp), %edx
movsd 0x8(%r14,%rcx), %xmm5
movsd 0x10(%r14,%rcx), %xmm6
movsd 0x18(%r14,%rcx), %xmm7
unpcklpd %xmm5, %xmm7            # xmm7 = xmm7[0],xmm5[0]
movapd %xmm6, %xmm8
movhpd (%r14,%rcx), %xmm8      # xmm8 = xmm8[0],mem[0]
subpd %xmm8, %xmm7
ucomisd %xmm1, %xmm7
movapd %xmm7, %xmm8
unpckhpd %xmm7, %xmm8            # xmm8 = xmm8[1],xmm7[1]
jne 0xe782
jp 0xe782
ucomisd %xmm1, %xmm8
jne 0xe782
jp 0xe782
addsd %xmm5, %xmm6
mulsd %xmm2, %xmm6
movapd %xmm6, %xmm5
jmp 0xe7bb
movapd %xmm7, %xmm9
andpd %xmm3, %xmm9
andpd %xmm3, %xmm8
mulsd %xmm8, %xmm6
mulsd %xmm9, %xmm5
addsd %xmm6, %xmm5
movapd %xmm7, %xmm6
xorpd %xmm4, %xmm6
maxpd %xmm7, %xmm6
movapd %xmm6, %xmm7
unpckhpd %xmm6, %xmm7            # xmm7 = xmm7[1],xmm6[1]
addsd %xmm6, %xmm7
divsd %xmm7, %xmm5
movsd %xmm5, 0x10(%r13,%rcx)
movsd 0x8(%r15,%rcx), %xmm5
movsd 0x10(%r15,%rcx), %xmm6
movsd 0x18(%r15,%rcx), %xmm7
unpcklpd %xmm5, %xmm7            # xmm7 = xmm7[0],xmm5[0]
movapd %xmm6, %xmm8
movhpd (%r15,%rcx), %xmm8      # xmm8 = xmm8[0],mem[0]
subpd %xmm8, %xmm7
ucomisd %xmm1, %xmm7
movapd %xmm7, %xmm8
unpckhpd %xmm7, %xmm8            # xmm8 = xmm8[1],xmm7[1]
jne 0xe814
jp 0xe814
ucomisd %xmm1, %xmm8
jne 0xe814
jp 0xe814
addsd %xmm5, %xmm6
mulsd %xmm2, %xmm6
movapd %xmm6, %xmm5
jmp 0xe84d
movapd %xmm7, %xmm9
andpd %xmm3, %xmm9
andpd %xmm3, %xmm8
mulsd %xmm8, %xmm6
mulsd %xmm9, %xmm5
addsd %xmm6, %xmm5
movapd %xmm7, %xmm6
xorpd %xmm4, %xmm6
maxpd %xmm7, %xmm6
movapd %xmm6, %xmm7
unpckhpd %xmm6, %xmm7            # xmm7 = xmm7[1],xmm6[1]
addsd %xmm6, %xmm7
divsd %xmm7, %xmm5
movsd %xmm5, 0x10(%rbp,%rcx)
addq $0x8, %rcx
cmpq %rcx, %rax
jne 0xe730
movl %edx, %eax
movq %rdi, %rdx
subl %edx, %eax
leal 0x3(%rax), %ecx
xorps %xmm1, %xmm1
cvtsi2sd %ecx, %xmm1
divsd %xmm1, %xmm0
addl $-0x3, %edx
movq 0x18(%rsp), %rcx
addq $0x10, %rcx
movq %rcx, 0x10(%rsp)
xorl %ecx, %ecx
movl $0x2, %esi
movapd 0x255b(%rip), %xmm1     # 0x10df0
movapd %xmm0, %xmm2
movq %rsi, %rdi
incq %rsi
leaq (%rdi,%rdi,2), %r8
movsd (%r12,%rdi,8), %xmm6
movq 0x20(%rsp), %r9
movupd (%r9,%r8,8), %xmm8
movupd 0x18(%r9,%r8,8), %xmm7
subpd %xmm8, %xmm7
movapd %xmm7, %xmm3
mulpd %xmm1, %xmm3
movsd (%r13,%rdi,8), %xmm4
movsd 0x8(%r13,%rdi,8), %xmm5
movhpd (%rbp,%rdi,8), %xmm4    # xmm4 = xmm4[0],mem[0]
movhpd 0x8(%rbp,%rdi,8), %xmm5 # xmm5 = xmm5[0],mem[0]
movslq %ecx, %rcx
leaq (%rcx,%rcx,2), %r9
movq 0x18(%rsp), %r10
movupd %xmm8, (%r10,%r9,8)
movq $0x0, 0x10(%r10,%r9,8)
incl %ecx
movsd (%r12,%rdi,8), %xmm8
ucomisd %xmm2, %xmm8
jbe 0xe9ec
leal (%rax,%rsi), %r9d
cmpl %r9d, %ecx
jge 0xe9ec
movq 0x20(%rsp), %r10
leaq (%r10,%r8,8), %r8
movapd %xmm6, %xmm8
mulsd %xmm6, %xmm8
unpcklpd %xmm6, %xmm6            # xmm6 = xmm6[0,0]
divpd %xmm6, %xmm3
movapd %xmm4, %xmm9
addpd %xmm4, %xmm9
subpd %xmm9, %xmm3
subpd %xmm5, %xmm3
addpd %xmm4, %xmm5
addpd %xmm7, %xmm7
divpd %xmm6, %xmm7
subpd %xmm7, %xmm5
divpd %xmm6, %xmm3
unpcklpd %xmm8, %xmm8            # xmm8 = xmm8[0,0]
divpd %xmm8, %xmm5
movslq %ecx, %r10
movslq %r9d, %r9
leaq (%r10,%r10,2), %r11
movq 0x10(%rsp), %rbx
leaq (%rbx,%r11,8), %r11
incq %r10
movapd %xmm2, %xmm6
unpcklpd %xmm2, %xmm6            # xmm6 = xmm6[0],xmm2[0]
movapd %xmm5, %xmm7
mulpd %xmm6, %xmm7
movapd %xmm3, %xmm8
mulpd %xmm6, %xmm8
mulpd %xmm6, %xmm7
mulpd %xmm6, %xmm8
mulpd %xmm6, %xmm7
addpd %xmm8, %xmm7
mulpd %xmm4, %xmm6
addpd %xmm7, %xmm6
movupd (%r8), %xmm7
addpd %xmm6, %xmm7
movupd %xmm7, -0x10(%r11)
movq $0x0, (%r11)
addsd %xmm0, %xmm2
movsd (%r12,%rdi,8), %xmm8
incl %ecx
ucomisd %xmm2, %xmm8
jbe 0xe9ec
addq $0x18, %r11
leaq 0x1(%r10), %rbx
cmpq %r9, %r10
movq %rbx, %r10
jl 0xe97f
subsd %xmm8, %xmm2
cmpq %rdx, %rsi
jne 0xe899
movl 0xc(%rsp), %eax
cmpl %eax, %ecx
jge 0xea3e
leaq (%rdx,%rdx,2), %rdx
movslq %ecx, %rsi
cltq
movq 0x20(%rsp), %rcx
movupd (%rcx,%rdx,8), %xmm0
leaq (%rsi,%rsi,2), %rcx
movq 0x18(%rsp), %rdx
leaq (%rdx,%rcx,8), %rcx
addq $0x10, %rcx
subq %rsi, %rax
movupd %xmm0, -0x10(%rcx)
movq $0x0, (%rcx)
addq $0x18, %rcx
decq %rax
jne 0xea29
movq %r14, %rdi
callq 0x6edd
movq %r15, %rdi
callq 0x6edd
movq %r12, %rdi
callq 0x6edd
movq %r13, %rdi
callq 0x6edd
movq %rbp, %rdi
callq 0x6edd
movl $0x1, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq