// File: /workspace/github_cpp_makefile_star2_O2/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, 0x10(%rsp)
movl 0x50(%rsi), %ecx
cmpl $0x6, %ecx
setl %dil
leal -0x4(%rcx), %eax
movl %edx, 0xc(%rsp)
cmpl %edx, %eax
setg %dl
xorl %eax, %eax
orb %dil, %dl
jne 0xdd5e
leaq 0x58(%rsi), %rbx
movl %ecx, %eax
movq %rax, 0x18(%rsp)
leaq (,%rax,8), %rbp
movq %rbp, %rdi
movq %rsi, 0x20(%rsp)
callq 0x2cb3
movq %rax, %r14
movq %rbp, %rdi
callq 0x2cb3
movq %rax, %r15
movq %rbp, %rdi
callq 0x2cb3
movq %rax, %r12
movq %rbp, %rdi
callq 0x2cb3
movq %rax, %r13
movq %rbp, %rdi
callq 0x2cb3
movq 0x20(%rsp), %r10
movq 0x18(%rsp), %r9
movq %rax, %rbp
leal -0x1(%r9), %ecx
leal -0x3(%r9), %eax
addq $0x78, %r10
xorpd %xmm1, %xmm1
xorl %r8d, %r8d
movabsq $0x3f1a36e2eb1c432d, %rdx # imm = 0x3F1A36E2EB1C432D
xorpd %xmm0, %xmm0
imulq $0x18, %r8, %rsi
addq %r10, %rsi
cmpq %r8, %rcx
je 0xda42
movq %r8, %rdi
movsd -0x8(%rsi), %xmm2
movsd (%rsi), %xmm3
subsd -0x20(%rsi), %xmm2
subsd -0x18(%rsi), %xmm3
mulsd %xmm3, %xmm3
mulsd %xmm2, %xmm2
addsd %xmm3, %xmm2
sqrtsd %xmm2, %xmm2
movsd %xmm2, (%r12,%r8,8)
ucomisd %xmm1, %xmm2
jne 0xd9f2
jp 0xd9f2
movq %rdx, (%r12,%rdi,8)
andq $0x0, (%r14,%rdi,8)
xorpd %xmm2, %xmm2
jmp 0xda15
movsd -0x8(%rsi), %xmm3
subsd -0x20(%rsi), %xmm3
divsd %xmm2, %xmm3
movsd %xmm3, (%r14,%rdi,8)
movsd (%rsi), %xmm2
subsd -0x18(%rsi), %xmm2
divsd (%r12,%rdi,8), %xmm2
movsd %xmm2, (%r15,%rdi,8)
addq $0x18, %rsi
leaq 0x1(%rdi), %r8
cmpq $0x2, %rdi
jb 0xd9a6
cmpq %rax, %rdi
jae 0xd9a6
addsd -0x8(%r12,%r8,8), %xmm0
jmp 0xd99f
leal -0x2(%r9), %ecx
leaq -0x10(,%rcx,8), %rcx
xorl %edx, %edx
xorpd %xmm1, %xmm1
movsd 0xbec(%rip), %xmm2      # 0xe648
movapd 0x238c(%rip), %xmm3     # 0xfdf0
movapd 0x7e4(%rip), %xmm4      # 0xe250
cmpq %rdx, %rcx
je 0xdba1
movsd 0x8(%r14,%rdx), %xmm5
movsd 0x10(%r14,%rdx), %xmm6
movsd 0x18(%r14,%rdx), %xmm7
unpcklpd %xmm5, %xmm7            # xmm7 = xmm7[0],xmm5[0]
movapd %xmm6, %xmm8
movhpd (%r14,%rdx), %xmm8      # xmm8 = xmm8[0],mem[0]
subpd %xmm8, %xmm7
ucomisd %xmm1, %xmm7
movapd %xmm7, %xmm8
unpckhpd %xmm7, %xmm8            # xmm8 = xmm8[1],xmm7[1]
jne 0xdac7
jp 0xdac7
ucomisd %xmm1, %xmm8
jne 0xdac7
jp 0xdac7
addsd %xmm5, %xmm6
mulsd %xmm2, %xmm6
movapd %xmm6, %xmm5
jmp 0xdb00
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,%rdx)
movsd 0x8(%r15,%rdx), %xmm5
movsd 0x10(%r15,%rdx), %xmm6
movsd 0x18(%r15,%rdx), %xmm7
unpcklpd %xmm5, %xmm7            # xmm7 = xmm7[0],xmm5[0]
movapd %xmm6, %xmm8
movhpd (%r15,%rdx), %xmm8      # xmm8 = xmm8[0],mem[0]
subpd %xmm8, %xmm7
ucomisd %xmm1, %xmm7
movapd %xmm7, %xmm8
unpckhpd %xmm7, %xmm8            # xmm8 = xmm8[1],xmm7[1]
jne 0xdb59
jp 0xdb59
ucomisd %xmm1, %xmm8
jne 0xdb59
jp 0xdb59
addsd %xmm5, %xmm6
mulsd %xmm2, %xmm6
movapd %xmm6, %xmm5
jmp 0xdb92
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,%rdx)
addq $0x8, %rdx
jmp 0xda6c
movl 0xc(%rsp), %ecx
movl %ecx, %edx
subl %r9d, %edx
leal 0x3(%rdx), %ecx
cvtsi2sd %ecx, %xmm1
divsd %xmm1, %xmm0
movq 0x10(%rsp), %rcx
leaq 0x28(%rcx), %rsi
xorl %ecx, %ecx
pushq $0x2
popq %rdi
movapd 0x2235(%rip), %xmm1     # 0xfe00
movapd %xmm0, %xmm2
movslq %ecx, %rcx
cmpq %rax, %rdi
je 0xdcfc
leaq 0x1(%rdi), %r8
imulq $0x18, %rdi, %r10
leaq (%rbx,%r10), %r9
movsd (%r12,%rdi,8), %xmm8
movapd %xmm8, %xmm7
mulsd %xmm8, %xmm7
movupd (%rbx,%r10), %xmm6
movupd 0x18(%rbx,%r10), %xmm9
subpd %xmm6, %xmm9
movapd %xmm9, %xmm3
mulpd %xmm1, %xmm3
unpcklpd %xmm8, %xmm8            # xmm8 = xmm8[0,0]
divpd %xmm8, %xmm3
movsd (%r13,%rdi,8), %xmm4
movsd 0x8(%r13,%rdi,8), %xmm5
movhpd (%rbp,%rdi,8), %xmm4    # xmm4 = xmm4[0],mem[0]
movapd %xmm4, %xmm10
addpd %xmm4, %xmm10
subpd %xmm10, %xmm3
movhpd 0x8(%rbp,%rdi,8), %xmm5 # xmm5 = xmm5[0],mem[0]
subpd %xmm5, %xmm3
addpd %xmm4, %xmm5
addpd %xmm9, %xmm9
divpd %xmm8, %xmm9
subpd %xmm9, %xmm5
divpd %xmm8, %xmm3
unpcklpd %xmm7, %xmm7            # xmm7 = xmm7[0,0]
divpd %xmm7, %xmm5
imulq $0x18, %rcx, %r10
movq 0x10(%rsp), %r11
movupd %xmm6, (%r11,%r10)
andq $0x0, 0x10(%r11,%r10)
leal (%rdx,%r8), %r11d
movslq %r11d, %r11
incq %rcx
addq %rsi, %r10
movsd (%r12,%rdi,8), %xmm6
ucomisd %xmm2, %xmm6
jbe 0xdcf0
cmpq %r11, %rcx
jge 0xdcf0
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 (%r9), %xmm7
addpd %xmm6, %xmm7
movupd %xmm7, -0x10(%r10)
andq $0x0, (%r10)
addsd %xmm0, %xmm2
incq %rcx
addq $0x18, %r10
jmp 0xdc8b
subsd %xmm6, %xmm2
movq %r8, %rdi
jmp 0xdbcf
imulq $0x18, %rax, %rax
addq %rax, %rbx
movslq 0xc(%rsp), %rax
imulq $0x18, %rcx, %rdx
movq 0x10(%rsp), %rsi
addq %rsi, %rdx
addq $0x10, %rdx
cmpq %rax, %rcx
jge 0xdd33
movupd (%rbx), %xmm0
movupd %xmm0, -0x10(%rdx)
andq $0x0, (%rdx)
incq %rcx
addq $0x18, %rdx
jmp 0xdd18
movq %r14, %rdi
callq 0x6a49
movq %r15, %rdi
callq 0x6a49
movq %r12, %rdi
callq 0x6a49
movq %r13, %rdi
callq 0x6a49
movq %rbp, %rdi
callq 0x6a49
pushq $0x1
popq %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq