// File: /workspace/github_cpp_makefile_star2_O1/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 $0x48, %rsp
movq %rsi, %r13
movl 0x50(%rsi), %r14d
cmpl $0x6, %r14d
setl %sil
leal -0x4(%r14), %eax
cmpl %edx, %eax
setg %dil
xorl %eax, %eax
orb %sil, %dil
jne 0xf391
movl %edx, 0x1c(%rsp)
movq %rcx, 0x38(%rsp)
leaq 0x58(%r13), %rax
movq %rax, 0x8(%rsp)
movslq %r14d, %rbp
movl %ebp, %eax
movq %rax, 0x28(%rsp)
leaq (,%rax,8), %rbx
movq %rbx, %rdi
callq 0x2d9b
movq %rax, (%rsp)
movq %rbx, %rdi
callq 0x2d9b
movq %rax, %r15
movq %rbx, %rdi
callq 0x2d9b
movq %rax, %r12
movq %rbx, %rdi
callq 0x2d9b
movq %rax, 0x20(%rsp)
movq %rbx, %rdi
callq 0x2d9b
movq (%rsp), %rdx
movq %rax, 0x10(%rsp)
movq %r14, 0x30(%rsp)
leal -0x1(%r14), %ebx
addq $-0x3, %rbp
addq $0x78, %r13
xorpd %xmm2, %xmm2
xorl %r14d, %r14d
xorpd %xmm12, %xmm12
movsd -0x8(%r13), %xmm0
subsd -0x20(%r13), %xmm0
movsd (%r13), %xmm1
subsd -0x18(%r13), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
addsd %xmm1, %xmm0
ucomisd %xmm2, %xmm0
jb 0xeec7
sqrtsd %xmm0, %xmm0
jmp 0xeee2
movsd %xmm12, 0x40(%rsp)
callq 0x2220
xorpd %xmm2, %xmm2
movsd 0x40(%rsp), %xmm12
movq (%rsp), %rdx
movsd %xmm0, (%r12,%r14,8)
ucomisd %xmm2, %xmm0
jne 0xef0c
jp 0xef0c
movabsq $0x3f1a36e2eb1c432d, %rax # imm = 0x3F1A36E2EB1C432D
movq %rax, (%r12,%r14,8)
movq $0x0, (%rdx,%r14,8)
xorpd %xmm0, %xmm0
jmp 0xef34
movsd -0x8(%r13), %xmm1
subsd -0x20(%r13), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rdx,%r14,8)
movsd (%r13), %xmm0
subsd -0x18(%r13), %xmm0
divsd (%r12,%r14,8), %xmm0
movsd %xmm0, (%r15,%r14,8)
cmpq $0x2, %r14
setae %al
cmpq %rbp, %r14
setl %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0xef54
addsd (%r12,%r14,8), %xmm12
incq %r14
addq $0x18, %r13
cmpq %r14, %rbx
jne 0xee97
movq 0x28(%rsp), %r8
cmpl $0x5, %r8d
movq 0x38(%rsp), %r13
movl 0x1c(%rsp), %ebp
movq 0x20(%rsp), %rbx
movq 0x30(%rsp), %rdi
jl 0xf0d9
leal -0x2(%r8), %eax
addq $-0x2, %rax
xorl %ecx, %ecx
xorpd %xmm0, %xmm0
movsd 0x168c(%rip), %xmm1     # 0x10628
movapd 0x2d8c(%rip), %xmm2     # 0x11d30
movapd 0x12b4(%rip), %xmm3     # 0x10260
movq 0x10(%rsp), %rsi
movsd 0x10(%rdx,%rcx,8), %xmm4
movsd 0x18(%rdx,%rcx,8), %xmm5
subsd %xmm4, %xmm5
ucomisd %xmm0, %xmm5
jne 0xefee
jp 0xefee
movsd 0x8(%rdx,%rcx,8), %xmm6
movapd %xmm6, %xmm7
subsd (%rdx,%rcx,8), %xmm7
ucomisd %xmm0, %xmm7
jne 0xefee
jp 0xefee
addsd %xmm6, %xmm4
mulsd %xmm1, %xmm4
movapd %xmm4, %xmm6
jmp 0xf036
movsd 0x8(%rdx,%rcx,8), %xmm7
movapd %xmm5, %xmm6
andpd %xmm2, %xmm6
mulsd %xmm7, %xmm6
subsd (%rdx,%rcx,8), %xmm7
movapd %xmm7, %xmm8
xorpd %xmm3, %xmm8
maxsd %xmm7, %xmm8
andpd %xmm2, %xmm7
mulsd %xmm7, %xmm4
addsd %xmm4, %xmm6
movapd %xmm5, %xmm4
xorpd %xmm3, %xmm4
maxsd %xmm5, %xmm4
addsd %xmm4, %xmm8
divsd %xmm8, %xmm6
movsd %xmm6, 0x10(%rbx,%rcx,8)
movsd 0x10(%r15,%rcx,8), %xmm4
movsd 0x18(%r15,%rcx,8), %xmm5
subsd %xmm4, %xmm5
ucomisd %xmm0, %xmm5
jne 0xf07d
jp 0xf07d
movsd 0x8(%r15,%rcx,8), %xmm6
movapd %xmm6, %xmm7
subsd (%r15,%rcx,8), %xmm7
ucomisd %xmm0, %xmm7
jne 0xf07d
jp 0xf07d
addsd %xmm6, %xmm4
mulsd %xmm1, %xmm4
movapd %xmm4, %xmm6
jmp 0xf0c7
movsd 0x8(%r15,%rcx,8), %xmm7
movapd %xmm5, %xmm6
andpd %xmm2, %xmm6
mulsd %xmm7, %xmm6
subsd (%r15,%rcx,8), %xmm7
movapd %xmm7, %xmm8
xorpd %xmm3, %xmm8
maxsd %xmm7, %xmm8
andpd %xmm2, %xmm7
mulsd %xmm7, %xmm4
addsd %xmm4, %xmm6
movapd %xmm5, %xmm4
xorpd %xmm3, %xmm4
maxsd %xmm5, %xmm4
addsd %xmm4, %xmm8
divsd %xmm8, %xmm6
movsd %xmm6, 0x10(%rsi,%rcx,8)
incq %rcx
cmpq %rcx, %rax
jne 0xefb1
leal -0x3(%rdi), %eax
xorl %ecx, %ecx
movl %eax, %eax
cmpl $0x6, %edi
jl 0xf315
movl %ebp, %ecx
subl %edi, %ecx
addl $0x3, %ecx
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
divsd %xmm0, %xmm12
movl %ebp, %edx
subl %r8d, %edx
leaq 0x10(%r13), %rsi
xorl %ecx, %ecx
movl $0x2, %edi
movsd 0x2c0c(%rip), %xmm0     # 0x11d20
movapd %xmm12, %xmm1
movq %rdi, %r8
movsd (%rbx,%rdi,8), %xmm2
movsd 0x8(%rbx,%rdi,8), %xmm3
incq %rdi
leaq (%r8,%r8,2), %r9
movq 0x8(%rsp), %r11
movsd 0x18(%r11,%r9,8), %xmm11
movsd (%r11,%r9,8), %xmm6
movsd 0x8(%r11,%r9,8), %xmm7
movsd (%r12,%r8,8), %xmm8
movq 0x10(%rsp), %r10
movsd (%r10,%r8,8), %xmm4
movsd 0x8(%r10,%r8,8), %xmm5
movsd 0x20(%r11,%r9,8), %xmm9
movslq %ecx, %rcx
leaq (%rcx,%rcx,2), %r10
movsd %xmm6, (%r13,%r10,8)
movsd %xmm7, 0x8(%r13,%r10,8)
movq $0x0, 0x10(%r13,%r10,8)
incl %ecx
movsd (%r12,%r8,8), %xmm10
ucomisd %xmm1, %xmm10
jbe 0xf302
leal (%rdx,%rdi), %r10d
cmpl %r10d, %ecx
jge 0xf302
movq 0x8(%rsp), %r11
leaq (%r11,%r9,8), %r9
subsd %xmm6, %xmm11
movapd %xmm11, %xmm6
mulsd %xmm0, %xmm6
divsd %xmm8, %xmm6
movapd %xmm2, %xmm10
addsd %xmm2, %xmm10
subsd %xmm10, %xmm6
subsd %xmm3, %xmm6
divsd %xmm8, %xmm6
addsd %xmm2, %xmm3
addsd %xmm11, %xmm11
divsd %xmm8, %xmm11
subsd %xmm11, %xmm3
movapd %xmm8, %xmm10
mulsd %xmm8, %xmm10
divsd %xmm10, %xmm3
subsd %xmm7, %xmm9
movapd %xmm9, %xmm7
mulsd %xmm0, %xmm7
divsd %xmm8, %xmm7
movapd %xmm4, %xmm11
addsd %xmm4, %xmm11
subsd %xmm11, %xmm7
subsd %xmm5, %xmm7
divsd %xmm8, %xmm7
addsd %xmm4, %xmm5
addsd %xmm9, %xmm9
divsd %xmm8, %xmm9
subsd %xmm9, %xmm5
divsd %xmm10, %xmm5
movslq %ecx, %r11
movslq %r10d, %r10
leaq (%r11,%r11,2), %rbx
leaq (%rsi,%rbx,8), %rbx
incq %r11
movapd %xmm3, %xmm8
mulsd %xmm1, %xmm8
mulsd %xmm1, %xmm8
movapd %xmm6, %xmm9
mulsd %xmm1, %xmm9
mulsd %xmm1, %xmm9
mulsd %xmm1, %xmm8
addsd %xmm9, %xmm8
movapd %xmm2, %xmm9
mulsd %xmm1, %xmm9
addsd %xmm8, %xmm9
addsd (%r9), %xmm9
movsd %xmm9, -0x10(%rbx)
movapd %xmm5, %xmm8
mulsd %xmm1, %xmm8
mulsd %xmm1, %xmm8
movapd %xmm7, %xmm9
mulsd %xmm1, %xmm9
mulsd %xmm1, %xmm9
mulsd %xmm1, %xmm8
addsd %xmm9, %xmm8
movapd %xmm4, %xmm9
mulsd %xmm1, %xmm9
addsd %xmm8, %xmm9
addsd 0x8(%r9), %xmm9
movsd %xmm9, -0x8(%rbx)
movq $0x0, (%rbx)
addsd %xmm12, %xmm1
movsd (%r12,%r8,8), %xmm10
incl %ecx
ucomisd %xmm1, %xmm10
jbe 0xf302
addq $0x18, %rbx
leaq 0x1(%r11), %r14
cmpq %r10, %r11
movq %r14, %r11
jl 0xf24e
subsd %xmm10, %xmm1
cmpq %rax, %rdi
movq 0x20(%rsp), %rbx
jne 0xf119
cmpl %ebp, %ecx
jge 0xf361
leaq (%rax,%rax,2), %rax
movq 0x8(%rsp), %rdx
leaq (%rdx,%rax,8), %rax
movslq %ecx, %rsi
movslq %ebp, %rcx
leaq (%rsi,%rsi,2), %rdx
leaq 0x10(,%rdx,8), %rdx
addq %r13, %rdx
subq %rsi, %rcx
movsd (%rax), %xmm0
movsd %xmm0, -0x10(%rdx)
movsd 0x8(%rax), %xmm0
movsd %xmm0, -0x8(%rdx)
movq $0x0, (%rdx)
addq $0x18, %rdx
decq %rcx
jne 0xf33e
movq (%rsp), %rdi
callq 0x701d
movq %r15, %rdi
callq 0x701d
movq %r12, %rdi
callq 0x701d
movq %rbx, %rdi
callq 0x701d
movq 0x10(%rsp), %rdi
callq 0x701d
movl $0x1, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq