#include "vectorsqrt.h"

#include <math.h>

#include "comm/crc16.h"

//---------------------------------------------------------------------------------------------------------

VSqrtItem::VSqrtItem(QObject *parent) :
    QObject(parent),
    m_sqrttype(0),
    m_begx(0),
    m_begy(0),
    m_midx(0),
    m_midy(0),
    m_midx2(0),
    m_midy2(0),
    m_endx(0),
    m_endy(0),
    m_code(0),
    m_ownsteplock(0),
    m_stepSize(0),
    m_blockNum(0),
    m_blockTimes(0),
    m_blockjumps(0),
    m_elockNum(0),
    m_elockTimes(0),
    m_elockjumps(0)
{

}

VSqrtItem::VSqrtItem(const VSqrtItem & item) :
    QObject()
{
    CopyData(item);
}

VSqrtItem& VSqrtItem::operator=(const VSqrtItem & item)
{
    CopyData(item);
    return * this;
}

void VSqrtItem::CopyData(const VSqrtItem & item)
{
    if (this != &item)
    {
        this->m_sqrttype    =   item.m_sqrttype;
        this->m_begx        =   item.m_begx;
        this->m_begy        =   item.m_begy;
        this->m_endx        =   item.m_endx;
        this->m_endy        =   item.m_endy;
        this->m_midx        =   item.m_midx;
        this->m_midy        =   item.m_midy;
        this->m_midx2       =   item.m_midx2;
        this->m_midy2       =   item.m_midy2;
        this->m_code        =   item.m_code;
        this->m_ownsteplock =   item.m_ownsteplock;
        this->m_stepSize    =   item.m_stepSize;
        this->m_blockNum    =   item.m_blockNum;
        this->m_blockTimes  =   item.m_blockTimes;
        this->m_blockjumps  =   item.m_blockjumps;
        this->m_elockNum    =   item.m_elockNum;
        this->m_elockTimes  =   item.m_elockTimes;
        this->m_elockjumps  =   item.m_elockjumps;
    }
}

void VSqrtItem::InitVSItem()
{
    m_sqrttype    =   0;
    m_begx        =   0;
    m_begy        =   0;
    m_endx        =   0;
    m_endy        =   0;
    m_midx        =   0;
    m_midy        =   0;
    m_midx2       =   0;
    m_midy2       =   0;
    m_code        =   0;
    m_ownsteplock =   0;
    m_stepSize    =   0;
    m_blockNum    =   0;
    m_blockTimes  =   0;
    m_blockjumps  =   0;
    m_elockNum    =   0;
    m_elockTimes  =   0;
    m_elockjumps  =   0;
}

//---------------------------------------------------------------------------------------------------------
#define MAX_ITEM_NUM    (100*10000)


VectorSqrt::VectorSqrt(QObject *parent) :
    QObject(parent),
    m_filename(),
    m_anchorSel(0),
    m_vSqitItemList(),
    m_para_stepSize(0),
    m_para_blockNum(0),
    m_para_blockTimes(0),
    m_para_blockjumps(0),
    m_para_elockNum(0),
    m_para_elockTimes(0),
    m_para_elockjumps(0)
{

}

VectorSqrt::~VectorSqrt()
{
    m_vSqitItemList.clear();
    m_filename.clear();
}

VectorSqrt::VectorSqrt(const VectorSqrt & item) :
    QObject()
{
    CopyData(item);
}

VectorSqrt& VectorSqrt::operator=(const VectorSqrt & item)
{
    CopyData(item);
    return * this;
}

void VectorSqrt::CopyData(const VectorSqrt & item)
{
    if (this != &item)
    {
        this->m_filename          = item.m_filename;
        this->m_anchorSel         = item.m_anchorSel;
        this->m_vSqitItemList     = item.m_vSqitItemList;
        this->m_para_stepSize     = item.m_para_stepSize;
        this->m_para_blockNum     = item.m_para_blockNum;
        this->m_para_blockTimes   = item.m_para_blockTimes;
        this->m_para_blockjumps   = item.m_para_blockjumps;
        this->m_para_elockNum     = item.m_para_elockNum;
        this->m_para_elockTimes   = item.m_para_elockTimes;
        this->m_para_elockjumps   = item.m_para_elockjumps;
    }
}

void VectorSqrt::InitVSqrt(QString name)
{
    m_filename = name;          // 名称
    m_vSqitItemList.clear(); 	// 图形列表
    m_para_stepSize    = 0;     // 步长
    m_para_blockNum    = 0;     // 起始锁针针数
    m_para_blockTimes  = 0;     // 起始锁针次数
    m_para_blockjumps  = 0;     // 起始跳过针数
    m_para_elockNum    = 0;     // 结束锁针针数
    m_para_elockTimes  = 0;     // 结束锁针次数
    m_para_elockjumps  = 0;     // 结束跳过针数
}
void VectorSqrt::SetAnchor(int nX,int nY)
{
    m_anchorX = nX;
    m_anchorY = nY;
}

void VectorSqrt::SetBegin(int nX,int nY)
{
    m_beginX = nX;
    m_beginY = nY;
}
#if 0
int VectorSqrt::CreateDs16FromSqrt(QByteArray & ds16Ary)//
{
    int rslt;
    ds16Ary.clear();
    rslt = 0;
    if (m_vSqitItemList.size() != 0)
    {
        double threex[3], threey[3];

        int begx, begy, begr, begflag;

        int paraBLockNum, paraBLockTimes, paraBLockJumps;
        int paraELockNum, paraELockTimes, paraELockJumps;
        int blockNum, blockTimes;
        int elockNum, elockTimes;
        int blockjumps, elockjumps;
        int stepSize, sqrtNum;
        int actx, acty, actr;
        int i, j, k, idx;
        int stepNumber, curtNumber, totalNumber;
        int n, cutflag;
        int offsetdr = 0; qDebug() << offsetdr ;

        u8 ctrl, oldctrl, attr;

        const int maxitemnum = MAX_ITEM_NUM;

        DataItem * dataItemArray = new DataItem[maxitemnum];
        if (dataItemArray == NULL)
        {
            return -1;
        }
        DataItem * pSteps, * pData, * pTemp;
        pSteps = dataItemArray;                 // 数据存放地址
        //------------------

        sqrtNum = m_vSqitItemList.size();   // 图形个数

        begx = m_vSqitItemList.at(0).m_begx;
        begy = m_vSqitItemList.at(0).m_begy;
        begr = 0;

        actx = begx;
        acty = begy;
        actr = 0;

        begflag = 0;
        totalNumber = 0;
        oldctrl = 0;
        ctrl = 0;
        cutflag = 0;

        //  printf("\t sqrtNum = %d\r\n", sqrtNum);

        //------------------
        // 生成文件内容
        for (idx = 0; idx < sqrtNum; idx++)
        {
            if (m_vSqitItemList.at(idx).m_ownsteplock != 0)     // 使用单独的针步和回针参数
            {
                stepSize        = m_vSqitItemList.at(idx).m_stepSize;			// 分割针步大小
                paraBLockNum    = m_vSqitItemList.at(idx).m_blockNum;
                paraBLockTimes  = m_vSqitItemList.at(idx).m_blockTimes;
                paraBLockJumps  = m_vSqitItemList.at(idx).m_blockjumps;
                paraELockNum    = m_vSqitItemList.at(idx).m_elockNum;
                paraELockTimes  = m_vSqitItemList.at(idx).m_elockTimes;
                paraELockJumps  = m_vSqitItemList.at(idx).m_elockjumps;
            }
            else
            {
                stepSize        = m_para_stepSize;			// 分割针步大小
                paraBLockNum    = m_para_blockNum;
                paraBLockTimes  = m_para_blockTimes;
                paraBLockJumps  = m_para_blockjumps;
                paraELockNum    = m_para_elockNum;
                paraELockTimes  = m_para_elockTimes;
                paraELockJumps  = m_para_elockjumps;
            }

#if (0)
            qDebug("m_vSqitItemList[%d] para:\r\n", idx);

            qDebug("\t stepSize = %d\r\n",      stepSize);
            qDebug("\t blockNum = %d\r\n",      blockNum);
            qDebug("\t blockTimes = %d\r\n",    blockTimes);
            qDebug("\t blockjumps = %d\r\n",    blockjumps);
            qDebug("\t elockNum = %d\r\n",      elockNum);
            qDebug("\t elockTimes = %d\r\n",    elockTimes);
            qDebug("\t elockjumps = %d\r\n",    elockjumps);
#endif

            //------------------
            // 起始回针参数处理
            if (paraBLockTimes > 0 && paraBLockNum > 0)
            {
                if (paraBLockJumps > paraBLockTimes*paraBLockNum)
                {
                    paraBLockNum = 0;
                    paraBLockTimes = 0;
                    paraBLockJumps = 0;
                }
            }
            else
            {
                paraBLockNum = 0;
                paraBLockTimes = 0;
                paraBLockJumps = 0;
            }
            while (paraBLockJumps >= paraBLockNum && paraBLockTimes > 1) // 保证jumps小于locknums
            {
                paraBLockJumps -= paraBLockNum;
                paraBLockTimes--;
            }
            // 结束回针参数处理
            if (paraELockTimes > 0 && paraELockNum > 0)
            {
                if (paraELockJumps > paraELockTimes*paraELockNum)
                {
                    paraELockNum = 0;
                    paraELockTimes = 0;
                    paraELockJumps = 0;
                }
            }
            else
            {
                paraELockNum = 0;
                paraELockTimes = 0;
                paraELockJumps = 0;
            }
            while (paraELockJumps >= paraELockNum && paraELockTimes > 1) // 保证jumps小于locknums
            {
                paraELockJumps -= paraELockNum;
                paraELockTimes--;
            }
            //------------------

#if (0)
            qDebug("calc para:\r\n");

            qDebug("\t sqrtNum = %d\r\n",    sqrtNum);
            qDebug("\t stepSize = %d\r\n",   stepSize);
            qDebug("\t blockNum = %d\r\n",   paraBLockNum);
            qDebug("\t blockTimes = %d\r\n", paraBLockTimes);
            qDebug("\t blockjumps = %d\r\n", paraBLockJumps);
            qDebug("\t elockNum = %d\r\n",   paraELockNum);
            qDebug("\t elockTimes = %d\r\n", paraELockTimes);
            qDebug("\t elockjumps = %d\r\n", paraELockJumps);
#endif

#if (0)
            qDebug("\t begx = %f\r\n", m_vSqitItemList.at(idx).m_begx);
            qDebug("\t begy = %f\r\n", m_vSqitItemList.at(idx).m_begy);
            qDebug("\t endx = %f\r\n", m_vSqitItemList.at(idx).m_endx);
            qDebug("\t endy = %f\r\n", m_vSqitItemList.at(idx).m_endy);
            qDebug("\t midx = %f\r\n", m_vSqitItemList.at(idx).m_midx);
            qDebug("\t midy = %f\r\n", m_vSqitItemList.at(idx).m_midy);
#endif

            //------------------
            if (begflag != 0)   // 非起始，插入偏移数据
            {
                if (fabs(m_vSqitItemList.at(idx).m_begx - m_vSqitItemList.at(idx-1).m_endx) > 1 ||
                        fabs(m_vSqitItemList.at(idx).m_begy - m_vSqitItemList.at(idx-1).m_endy) > 1 ||
                        0	)
                {
                    // 自动插入偏移数据
                    threex[0] = m_vSqitItemList.at(idx-1).m_endx;
                    threey[0] = m_vSqitItemList.at(idx-1).m_endy;
                    threex[1] = m_vSqitItemList.at(idx).m_begx;
                    threey[1] = m_vSqitItemList.at(idx).m_begy;
                    threex[2] = m_vSqitItemList.at(idx).m_begx;
                    threey[2] = m_vSqitItemList.at(idx).m_begy;		// 三点共线，作为直线

                    stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, S16_MAX/2, pSteps, DATA_OFFSET);

                    pSteps += stepNumber;
                    totalNumber += stepNumber;
                }

            }

            oldctrl = ctrl;
            ctrl = m_vSqitItemList.at(idx).m_code;

            blockNum = 0;   blockTimes = 0; blockjumps = 0;
            elockNum = 0;   elockTimes = 0; elockjumps = 0;
            cutflag = 0;

            if ((ctrl == DATA_SEWING ||
                 ctrl == DATA_SYNCSEW))
            {
                if (oldctrl != ctrl)
                {
                    blockNum    = paraBLockNum;         // 起始锁针针数
                    blockTimes  = paraBLockTimes;       // 起始锁针次数
                    blockjumps  = paraBLockJumps;       // 起针跳过针数
                    if (blockTimes > 0)
                    {
                        if (blockjumps > blockTimes*blockNum)
                        {
                            blockTimes = 0;
                            blockNum = 0;
                            blockjumps = 0;
                        }
                    }
                    else
                    {
                        blockTimes = 0;
                        blockNum = 0;
                        blockjumps = 0;
                    }
                }

                if ( idx+1 >= sqrtNum || m_vSqitItemList.at(idx+1).m_code != ctrl)
                {
                    elockNum    = paraELockNum;         // 结束锁针针数
                    elockTimes  = paraELockTimes;       // 结束锁针次数
                    elockjumps  = paraELockJumps;       // 结束跳过针数
                    cutflag = 1;
                    if (elockTimes > 0)
                    {
                        if (elockjumps > elockTimes*elockNum)
                        {
                            elockTimes = 0;
                            elockNum = 0;
                            elockjumps = 0;
                        }
                    }
                    else
                    {
                        elockTimes = 0;
                        elockNum = 0;
                        elockjumps = 0;
                    }
                }
            }

            threex[0] = m_vSqitItemList.at(idx).m_begx;
            threey[0] = m_vSqitItemList.at(idx).m_begy;
            threex[1] = m_vSqitItemList.at(idx).m_midx;
            threey[1] = m_vSqitItemList.at(idx).m_midy;
            threex[2] = m_vSqitItemList.at(idx).m_endx;
            threey[2] = m_vSqitItemList.at(idx).m_endy;

            stepNumber = CalcCurve(threex, threey, NULL, NULL, NULL, stepSize, NULL, ctrl);
            curtNumber = stepNumber + blockNum*blockTimes + elockNum*elockTimes - blockjumps - elockjumps;;

            //          qDebug("stepNumber = %d, cur totalNumber=%d:\r\n", stepNumber, curtNumber);

            pData = pSteps + (blockNum*blockTimes) - blockjumps;

            n = CalcCurve(threex, threey, &actx, &acty, &actr, stepSize, pData, ctrl);
            if (n != stepNumber)
            {
                //              qDebug("create number =%d, is not equal to stepNumber=%d:\r\n", n, stepNumber);
            }

            if (begflag == 0)
            {
                begr = pData->dr;
                pData->dr = 0;
            }

            //------------------
            // 倒序添加起针锁针
#if (0)
            // 起始锁针信息
            printf("before add lock:\r\n");
            for (i = 0; i < curtNumber; i++)
            {
                printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pSteps[i].ctrl, pSteps[i].attr, pSteps[i].dx, pSteps[i].dy);
            }
#endif
            pTemp = pData - 1;
            k = blockTimes*blockNum;
            for (i = 0; i < blockTimes; i++)
            {
                if (i%2 == 0)	// 奇数锁针
                {
                    //				printf("ji shu:\r\n");
                    for (j = 0; j < blockNum; j++)
                    {
                        // 拷贝针步
                        memcpy(pTemp, &(pData[j]), sizeof(DataItem));
                        pTemp->dx *= -1;
                        pTemp->dy *= -1;		// 方向取反
                        pTemp->dr *= -1;		// 方向取反
                        k--;
                        if (k < blockjumps)		// 跳过计数器
                        {
                            pTemp->ctrl = DATA_OFFSET;  // 转换为offset
                        }
                        else
                        {
                            attr = pTemp->attr;
                            attr |= ATTR_RESEW;		// 回针标志
                            pTemp->attr = attr;
                        }
                        pTemp--;
                    }
                }
                else	// 偶数锁针
                {
                    //				printf("ou shu:\r\n");
                    for (j = blockNum-1; j >= 0; j--)
                    {
                        // 拷贝针步
                        memcpy(pTemp, &(pData[j]), sizeof(DataItem));

                        k--;
                        if (k < blockjumps)		// 跳过计数器
                        {
                            pTemp->ctrl = DATA_OFFSET;  // 转换为offset
                        }
                        else
                        {
                            attr = pTemp->attr;
                            attr |= ATTR_RESEW;		// 回针标志
                            pTemp->attr = attr;
                        }
                        pTemp--;
                    }
                }
            }
            // 正向扫描，修正起针回针中的dr
            k = blockTimes*blockNum;
            pTemp = pData - k;
            if(blockTimes != 0  )
            {
                for (i = 0; i <= blockTimes; i++)   // 跳过第一次锁针(偶数)，且
                {
                    if (i%2 == 0)	// 偶数锁针
                    {
                        if (i == 0)   // 第一针, 这里不做处理，后面添加单独运动dr的offset
                        {
                        }
                        else
                        {
                            pTemp->dr = 0;
                        }
                        pTemp += blockNum;
                    }
                    else            // 奇数锁针
                    {
                        pTemp += blockNum - 1 ;
                        pTemp->dr = 0;
                        pTemp++;
                    }
                }
            }
#if (0)
            // 结束锁针信息
            printf("after add begin lock:\r\n");
            for (i = 0; i < curtNumber; i++)
            {
                printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
            }
#endif
            //------------------
            // 顺序添加末针锁针
            pTemp = pData + stepNumber;
            k = 0;
            for (i = 0; i < elockTimes; i++)
            {
                if (i%2 == 0)	// 奇数锁针
                {
                    for (j = 0; j < elockNum; j++)
                    {
                        // 拷贝针步
                        memcpy(pTemp, &(pData[stepNumber-1-j]), sizeof(DataItem));
                        pTemp->dx *= -1;
                        pTemp->dy *= -1;		// 方向取反
                        pTemp->dr *= -1;		// 方向取反

                        k++;
                        if (k > elockTimes*elockNum - elockjumps)		// 结束跳过计数器
                        {
                            pTemp->ctrl = DATA_OFFSET;  // 转换为offset
                        }
                        else
                        {
                            attr = pTemp->attr;
                            attr |= ATTR_RESEW;		// 回针标志
                            pTemp->attr = attr;
                        }
                        pTemp++;
                    }
                }
                else
                {
                    for (j = elockNum-1; j >= 0; j--)
                    {
                        // 拷贝针步
                        memcpy(pTemp, &(pData[stepNumber-1-j]), sizeof(DataItem));
                        k++;
                        if (k > elockTimes*elockNum - elockjumps)		// 结束跳过计数器
                        {
                            pTemp->ctrl = DATA_OFFSET;  // 转换为offset
                        }
                        else
                        {
                            attr = pTemp->attr;
                            attr |= ATTR_RESEW;		// 回针标志
                            pTemp->attr = attr;
                        }
                        pTemp++;
                    }
                }
            }

#if (0)
            printf("after add end lock:\r\n");
            for (i = 0; i < curtNumber; i++)
            {
                printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
            }
#endif
            //------------------

            stepNumber = curtNumber;

            if (cutflag != 0)	// 缝纫针步添加剪线码
            {
                // 添加剪线码
                pSteps[stepNumber].ctrl = DATA_CUTTRD;
                pSteps[stepNumber].attr = 0;
                pSteps[stepNumber].dx = 0;
                pSteps[stepNumber].dy = 0;
                pSteps[stepNumber].dr = 0;
                stepNumber++;
            }

#if (0)
            printf("after jump lock:\r\n");
            for (i = 0; i < curtNumber; i++)
            {
                printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pSteps[i].ctrl, pSteps[i].attr, pSteps[i].dx, pSteps[i].dy);
            }
#endif

            pSteps += stepNumber;
            totalNumber += stepNumber;
            begflag = 1;
        }	// end of for(idx......

        //------------------
        // 最后一针添加结束码
        dataItemArray[totalNumber].ctrl = DATA_END;
        dataItemArray[totalNumber].attr = 0;
        dataItemArray[totalNumber].dx = 0;
        dataItemArray[totalNumber].dy = 0;
        dataItemArray[totalNumber].dr = 0;

        totalNumber++;
        if (rslt != 0)
        {
            qDebug("no enough item mem");
        }

#if (0)
        printf("after calc, begx=%d, begy=%d, stepNumber=%d\r\n", begx, begy, totalNumber);
#endif

#if (1)
        // 剪线码移到缝纫数据之后
        pData = dataItemArray;    // 源
        begflag = 0;

        for (i = 0; i < totalNumber; i++)
        {
            if ((pData->ctrl == DATA_SEWING || pData->ctrl == DATA_SYNCSEW))
            {
                begflag = 1;
            }
            else if (pData->ctrl == DATA_OFFSET)
            {
                if (begflag == 1)
                {
                    pSteps = pData;
                    begflag = 2;
                }
                else if (begflag != 2)
                {
                    begflag = 0;
                }
            }
            else if (pData->ctrl == DATA_CUTTRD)
            {
                if (begflag == 2)
                {
                    // 交换 pSteps 和 pData
                    DataItem tmpItem;
                    memcpy(&tmpItem, pData, sizeof(DataItem));
                    memcpy(pData, pSteps, sizeof(DataItem));
                    memcpy(pSteps, &tmpItem, sizeof(DataItem));
                }
                begflag = 0;
            }
            else
            {
                begflag = 0;
            }
            pData++;
        }

#endif
        pData = dataItemArray;      // 源
        pSteps = pData;             // 目标
        // 扫描生成数据，确定起点坐标，合并offset数据
        // 起点坐标
        begr = pData[0].dr;        // 第一个针步，dr是从0开始的变化量
        pData[0].dr = 0;           // 设置第一个针步的变化量为0

        i = 0;
#if (0)
        for (i = 0; i < totalNumber; i++)
        {
            if (pData->ctrl != DATA_OFFSET)   // 起始的offset合并到起点坐标
            {
                break;
            }

            begx += pData->dx;
            begy += pData->dy;
            begr += pData->dr;        // 改变起针位置
            pData++;                  // 源后移
        }
#endif

        begflag = 0;
        actr = begr;
#if (0)
        int offset_dr;

        // 继续扫描生成数据，合并offset数据
        for (i = i, j = 0; i < totalNumber; i++)
        {
            if (pData->ctrl == DATA_OFFSET)
            {
                if (begflag == 0)
                {
                    // 初始化offset计数
                    threex[0] = 0;
                    threey[0] = 0;
                    threex[1] = 0;
                    threey[1] = 0;
                    threex[2] = 0;
                    threey[2] = 0;
                    offset_dr = 0;
                    begflag = 1;
                }

                threex[2] += pData->dx;
                threey[2] += pData->dy;
                offset_dr += pData->dr;
            }
            else
            {
                if (begflag != 0 && pData->ctrl != DATA_END)
                {
                    // 重新插入偏移数据
                    actx = 0;
                    acty = 0;
                    stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, S16_MAX*3/5, pSteps, DATA_OFFSET);
                    pSteps->dr = offset_dr ;

                    pSteps += stepNumber;
                    j += stepNumber;
                    begflag = 0;
                }
                if (pSteps != pData)
                {
                    memcpy(pSteps, pData, sizeof(DataItem));
                }
                j++;
                actr += pSteps->dr;
                pSteps++;
            }

            pData++;
        }

        totalNumber = j;
#endif

#if (0)
        printf("before write begx=%d, begy=%d, stepNumber=%d\r\n", begx, begy, totalNumber);
#endif

#ifdef used_mac_DHQ  // 1  插入小的数据 0 不插入小的数据

        DataItem * cp_dataItemArray = new DataItem[totalNumber];

        memcpy( cp_dataItemArray , dataItemArray  , sizeof( DataItem )*totalNumber);

        j = 0 ;
        for (int var = 0; var < totalNumber; ++var)
        {
            if((var + 1) > totalNumber)
            {
                break;
            }
            else if(
                    (cp_dataItemArray[var].ctrl == cp_dataItemArray[var + 1].ctrl)
                    &&
                    ((cp_dataItemArray[var].ctrl == DATA_SEWING)||
                     (cp_dataItemArray[var].ctrl == DATA_SECF_SEW)||
                     (cp_dataItemArray[var].ctrl == DATA_SYNCSEW)
                     )
                    &&
                    (fabs( cp_dataItemArray[var].len - cp_dataItemArray[var + 1 ].len) >
                     1.8 * m_rvsf_info.i_dense_step)
                    )
            {
                DataItem temp ;
#if 1
                memset( &temp , 0 ,  sizeof (DataItem ));

                int len = cp_dataItemArray[var].len ;

                if( cp_dataItemArray[ var ].len > cp_dataItemArray[ var + 1 ].len )
                {
                    len =  cp_dataItemArray[ var + 1 ].len ;
                }
                else  if( cp_dataItemArray[var].len < cp_dataItemArray[var + 1].len)
                {
                    len =  cp_dataItemArray[ var ].len ;
                }

                if( abs( cp_dataItemArray[var].len - cp_dataItemArray[var + 1 ].len ) > len*0.3 )
                {
                    memcpy( &(temp) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                    temp.attr |=  ATTR_RESEW;
                    memcpy( &(dataItemArray[j]) , &(temp) , sizeof( DataItem ));
                    j++;
                }
                else if( abs( cp_dataItemArray[var].len - cp_dataItemArray[var + 1 ].len ) > len*0.3 )
                {
                    memcpy( &(dataItemArray[j]) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                    j++;
                    var++;
                    memcpy( &(temp) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                    temp.attr |=  ATTR_RESEW;
                    memcpy( &(dataItemArray[j]) , &(temp) , sizeof( DataItem ));
                    j++;
                }
#endif

#if 0

                if( cp_dataItemArray[var].len > cp_dataItemArray[var + 1 ].len)
                {

                    //两个索引都退两个
                    var -= 2;
                    j   -= 2;

                    //复制第一个针步
                    memcpy( &temp , &(cp_dataItemArray[var]) , sizeof( DataItem ));

                    temp.dx = temp.dx / 2 ;
                    temp.dy = temp.dy / 2 ;
                    temp.attr |=  ATTR_RESEW;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[var]) , &temp, sizeof( DataItem ));
                    j++ ;

                    temp.dx = cp_dataItemArray[var].dx - temp.dx ;
                    temp.dy = cp_dataItemArray[var].dy - temp.dy ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[var]) , &temp, sizeof( DataItem ));
                    j++ ;
                    var++;

                    //复制第二个针步
                    memcpy( &temp , &(cp_dataItemArray[var]) , sizeof( DataItem ));

                    temp.dx = temp.dx / 2 ;
                    temp.dy = temp.dy / 2 ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[j]) , &temp, sizeof( DataItem ));
                    j++ ;

                    temp.dx = cp_dataItemArray[var].dx - temp.dx ;
                    temp.dy = cp_dataItemArray[var].dy - temp.dy ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[j]) , &temp, sizeof( DataItem ));
                    j++ ;
                    var++;
                }
                else if( cp_dataItemArray[var + 1].len > cp_dataItemArray[var].len)
                {

                    memcpy( &(dataItemArray[j]) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                    var++;
                    j++ ;

                    //复制第一个针步
                    memcpy( &temp , &(cp_dataItemArray[var]) , sizeof( DataItem ));

                    temp.dx = temp.dx / 2 ;
                    temp.dy = temp.dy / 2 ;
                    temp.attr |=  ATTR_RESEW;

                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[var]) , &temp, sizeof( DataItem ));
                    j++ ;

                    temp.dx = cp_dataItemArray[var].dx - temp.dx ;
                    temp.dy = cp_dataItemArray[var].dy - temp.dy ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[var]) , &temp, sizeof( DataItem ));
                    j++ ;
                    var++;

                    //复制第二个针步
                    memcpy( &temp , &(cp_dataItemArray[var]) , sizeof( DataItem ));

                    temp.dx = temp.dx / 2 ;
                    temp.dy = temp.dy / 2 ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[j]) , &temp, sizeof( DataItem ));
                    j++ ;

                    temp.dx = cp_dataItemArray[var].dx - temp.dx ;
                    temp.dy = cp_dataItemArray[var].dy - temp.dy ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[j]) , &temp, sizeof( DataItem ));
                    j++ ;
                    var++;
                }
#endif
            }
            else
            {
                memcpy( &(dataItemArray[j]) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                j++ ;
            }
        }
        delete [] cp_dataItemArray;
        totalNumber = j;
#endif


        // dataItemArray

        for( int i = 0 ; i  <  (totalNumber -1); i++)
        {
            if(
                    ( dataItemArray[i].ctrl == DATA_OFFSET  )
                    &&
                    (
                        ( dataItemArray[i + 1 ].ctrl == DATA_RKNIFE  )
                        ||( dataItemArray[i + 1 ].ctrl == DATA_SKNIFE  )
                        )
                    )
            {
                dataItemArray[i  ].dr += dataItemArray[i + 1 ].dr;
                dataItemArray[i + 1 ].dr = 0 ;
            }
        }

        // 写文件头
        DataFileHead fileHead;	// 数据文件头描述
        memset(&fileHead, 0, sizeof(DataFileHead));

        m_filename = "test.plt";
        QByteArray ba = m_filename.toLatin1();  // ISO-8859-1 文件名称
        int cpsize = ba.size();
        if (cpsize > 32)
        {
            cpsize = 32;
        }


        memcpy(fileHead.fileName, (char*)ba.data(), cpsize);

        fileHead.dataSize = totalNumber*sizeof(DataItem);	// 文件长度
        fileHead.itemNums = totalNumber;					// 有效针数
        fileHead.bytesPerItem = sizeof(DataItem);			// 每针占的字节数
        fileHead.bytesPerBlk = 1024;						// 文件内容划分块大小

        fileHead.dataChecksum = CalcCheckSum32((u8*)(dataItemArray), totalNumber*sizeof(DataItem));  // 花样数据累加校验和
        fileHead.checkCrc = CalcCrc16((u8*)(&fileHead), 6*sizeof(u32));   // 前6个字段CRC校验


        s32 minx, miny, maxx, maxy;
        GetDataMinMax(dataItemArray, totalNumber, minx, miny, maxx, maxy);

        fileHead.minX = minx - minx  + m_beginX;
        fileHead.maxX = maxx - minx  + m_beginX;
        fileHead.minY = miny - miny  + m_beginY;
        fileHead.maxY = maxy - miny  + m_beginY;

        fileHead.beginX = m_beginX ;
        fileHead.beginY = m_beginY ;

        fileHead.anchorX = m_anchorX;
        fileHead.anchorY = m_anchorY;		// 定位点

        /*
    +  begx
    +  begy
    +  begx
    +  begy
*/
#if (0)
        if( 1 )
        {
            m_anchorSel = 1 ; // 当文件是 qui 的时候

            fileHead.beginX = begx;
            fileHead.beginY = begy;
        }
        else if( 0 )
        {
            m_anchorSel = 0 ; //当文件是 rvsf 的时候

            fileHead.beginX = m_rvsf_info.i_Gantry;
            fileHead.beginY = m_rvsf_info.i_Head_B;
            fileHead.beginR = begr;			// 起始点坐标

            fileHead.beginX2 = m_rvsf_info.i_Gantry;
            fileHead.beginY2 = m_rvsf_info.i_Head_A;
            fileHead.beginR2 = 0;

            if( fileHead.beginX2  < fileHead.minX)
            {
                fileHead.minX = fileHead.beginX2;
            }
            if( fileHead.beginX2  > fileHead.maxX)
            {
                fileHead.maxX = fileHead.beginX2;
            }
            if( fileHead.beginY2  < fileHead.minY)
            {
                fileHead.minY = fileHead.beginY2;
            }
            if( fileHead.beginY2  > fileHead.maxY)
            {
                fileHead.maxY = fileHead.beginY2;
            }
        }
        // 定位点选择; 0, 和起点重合; 1，图形的左下角; 2, 图形的右下角; 3, 图形的右上角; 4, 图形的左上角; 5, 图形的中心
        switch (m_anchorSel)
        {
        case 1:                 // 1，图形的左下角
            fileHead.anchorX = fileHead.minX;
            fileHead.anchorY = fileHead.minY;		// 定位点
            break;
        case 2:                 // 2，图形的右下角
            fileHead.anchorX = fileHead.maxX;
            fileHead.anchorY = fileHead.minY;		// 定位点
            break;
        case 3:                 // 3，图形的右上角
            fileHead.anchorX = fileHead.maxX;
            fileHead.anchorY = fileHead.maxY;		// 定位点
            break;
        case 4:                 // 4，图形的左上角
            fileHead.anchorX = fileHead.minX;
            fileHead.anchorY = fileHead.maxY;		// 定位点
            break;
        default:

            fileHead.anchorX = fileHead.beginX;
            fileHead.anchorY = fileHead.beginY;		// 定位点

            fileHead.anchorX2 = fileHead.beginX2 ;
            fileHead.anchorY2 = fileHead.beginY2 ;	// 定位点

            break;
        }
#endif



#if (0)
        printf("finial write:\r\n");
        for (i = 0; i < stepNumber; i++)
        {
            printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
        }
#endif
        // 拷贝数据
        ds16Ary.resize(sizeof(DataFileHead)+totalNumber*sizeof(DataItem));
        memcpy (ds16Ary.data(), &fileHead, sizeof(DataFileHead));
        memcpy (&m_fileHead, &fileHead, sizeof(DataFileHead));
        memcpy (ds16Ary.data() + sizeof(DataFileHead), dataItemArray, totalNumber*sizeof(DataItem));

        delete []dataItemArray;
    }

    return rslt;
}

#endif
#if 1
int VectorSqrt::CreateDs16FromSqrt(QByteArray & ds16Ary)//
{
    int rslt;
    ds16Ary.clear();
    rslt = 0;
    if (m_vSqitItemList.size() != 0)
    {
        double threex[3], threey[3];

        int begx, begy, begr, begflag;

        int paraBLockNum, paraBLockTimes, paraBLockJumps;
        int paraELockNum, paraELockTimes, paraELockJumps;
        int blockNum, blockTimes;
        int elockNum, elockTimes;
        int blockjumps, elockjumps;
        int stepSize, sqrtNum;
        int actx, acty, actr;
        int i, j, k, idx;
        int stepNumber, curtNumber, totalNumber;
        int n, cutflag;
        int offsetdr = 0;

        u8 ctrl, oldctrl, attr;

        const int maxitemnum = MAX_ITEM_NUM;

        DataItem * dataItemArray = new DataItem[maxitemnum];
        if (dataItemArray == NULL)
        {
            return -1;
        }
        DataItem * pSteps, * pData, * pTemp;
        pSteps = dataItemArray;                 // 数据存放地址
        //------------------

        sqrtNum = m_vSqitItemList.size();   // 图形个数

        begx = m_vSqitItemList.at(0).m_begx;
        begy = m_vSqitItemList.at(0).m_begy;
        begr = 0;

        actx = begx;
        acty = begy;
        actr = 0;

        begflag = 0;
        totalNumber = 0;
        oldctrl = 0;
        ctrl = 0;
        cutflag = 0;

        //  printf("\t sqrtNum = %d\r\n", sqrtNum);

        //------------------
        // 生成文件内容
        for (idx = 0; idx < sqrtNum; idx++)
        {
            if (m_vSqitItemList.at(idx).m_ownsteplock != 0)     // 使用单独的针步和回针参数
            {
                stepSize        = m_vSqitItemList.at(idx).m_stepSize;			// 分割针步大小
                paraBLockNum    = m_vSqitItemList.at(idx).m_blockNum;
                paraBLockTimes  = m_vSqitItemList.at(idx).m_blockTimes;
                paraBLockJumps  = m_vSqitItemList.at(idx).m_blockjumps;
                paraELockNum    = m_vSqitItemList.at(idx).m_elockNum;
                paraELockTimes  = m_vSqitItemList.at(idx).m_elockTimes;
                paraELockJumps  = m_vSqitItemList.at(idx).m_elockjumps;
            }
            else
            {
                stepSize        = m_para_stepSize;			// 分割针步大小
                paraBLockNum    = m_para_blockNum;
                paraBLockTimes  = m_para_blockTimes;
                paraBLockJumps  = m_para_blockjumps;
                paraELockNum    = m_para_elockNum;
                paraELockTimes  = m_para_elockTimes;
                paraELockJumps  = m_para_elockjumps;
            }

#if (0)
            qDebug("m_vSqitItemList[%d] para:\r\n", idx);

            qDebug("\t stepSize = %d\r\n",      stepSize);
            qDebug("\t blockNum = %d\r\n",      blockNum);
            qDebug("\t blockTimes = %d\r\n",    blockTimes);
            qDebug("\t blockjumps = %d\r\n",    blockjumps);
            qDebug("\t elockNum = %d\r\n",      elockNum);
            qDebug("\t elockTimes = %d\r\n",    elockTimes);
            qDebug("\t elockjumps = %d\r\n",    elockjumps);
#endif

            //------------------
            // 起始回针参数处理
            /*if (paraBLockTimes > 0 && paraBLockNum > 0)
            {
                if (paraBLockJumps > paraBLockTimes*paraBLockNum)
                {
                    paraBLockNum = 0;
                    paraBLockTimes = 0;
                    paraBLockJumps = 0;
                }
            }
            else
            {
                paraBLockNum = 0;
                paraBLockTimes = 0;
                paraBLockJumps = 0;
            }
            while (paraBLockJumps >= paraBLockNum && paraBLockTimes > 1) // 保证jumps小于locknums
            {
                paraBLockJumps -= paraBLockNum;
                paraBLockTimes--;
            }
            // 结束回针参数处理
            if (paraELockTimes > 0 && paraELockNum > 0)
            {
                if (paraELockJumps > paraELockTimes*paraELockNum)
                {
                    paraELockNum = 0;
                    paraELockTimes = 0;
                    paraELockJumps = 0;
                }
            }
            else
            {
                paraELockNum = 0;
                paraELockTimes = 0;
                paraELockJumps = 0;
            }
            while (paraELockJumps >= paraELockNum && paraELockTimes > 1) // 保证jumps小于locknums
            {
                paraELockJumps -= paraELockNum;
                paraELockTimes--;
            }*/
            //------------------

#if (0)
            qDebug("calc para:\r\n");

            qDebug("\t sqrtNum = %d\r\n",    sqrtNum);
            qDebug("\t stepSize = %d\r\n",   stepSize);
            qDebug("\t blockNum = %d\r\n",   paraBLockNum);
            qDebug("\t blockTimes = %d\r\n", paraBLockTimes);
            qDebug("\t blockjumps = %d\r\n", paraBLockJumps);
            qDebug("\t elockNum = %d\r\n",   paraELockNum);
            qDebug("\t elockTimes = %d\r\n", paraELockTimes);
            qDebug("\t elockjumps = %d\r\n", paraELockJumps);
#endif

#if (0)
            qDebug("\t begx = %f\r\n", m_vSqitItemList.at(idx).m_begx);
            qDebug("\t begy = %f\r\n", m_vSqitItemList.at(idx).m_begy);
            qDebug("\t endx = %f\r\n", m_vSqitItemList.at(idx).m_endx);
            qDebug("\t endy = %f\r\n", m_vSqitItemList.at(idx).m_endy);
            qDebug("\t midx = %f\r\n", m_vSqitItemList.at(idx).m_midx);
            qDebug("\t midy = %f\r\n", m_vSqitItemList.at(idx).m_midy);
#endif

            //------------------
            if (begflag != 0)   // 非起始，插入偏移数据
            {
                if (fabs(m_vSqitItemList.at(idx).m_begx - m_vSqitItemList.at(idx-1).m_endx) > 1 ||
                        fabs(m_vSqitItemList.at(idx).m_begy - m_vSqitItemList.at(idx-1).m_endy) > 1 ||
                        0	)
                {
                    // 自动插入偏移数据
                    threex[0] = m_vSqitItemList.at(idx-1).m_endx;
                    threey[0] = m_vSqitItemList.at(idx-1).m_endy;
                    threex[1] = m_vSqitItemList.at(idx).m_begx;
                    threey[1] = m_vSqitItemList.at(idx).m_begy;
                    threex[2] = m_vSqitItemList.at(idx).m_begx;
                    threey[2] = m_vSqitItemList.at(idx).m_begy;		// 三点共线，作为直线

                    stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, S16_MAX/2, pSteps, DATA_OFFSET);
                    if (totalNumber + stepNumber >= maxitemnum)
                    {
                        rslt = -1;
                        break;
                    }

#if 1   // 暂不插入偏移数据
                    pSteps += stepNumber;
                    totalNumber += stepNumber;
#endif

                    if (stepNumber != 0)
                    {
                        ctrl = DATA_OFFSET;
                    }
                }
                else
                {
                    // 偏差小于1个单位, 不支持插入
                }
            }

            oldctrl = ctrl;
            ctrl = m_vSqitItemList.at(idx).m_code;

            blockNum = 0;   blockTimes = 0; blockjumps = 0;
            elockNum = 0;   elockTimes = 0; elockjumps = 0;
            cutflag = 0;

            if ((ctrl == DATA_SEWING ||
                 ctrl == DATA_SECF_SEW ||
                 ctrl == DATA_SYNCSEW))
            {
                if (oldctrl != ctrl)
                {
                    blockNum    = paraBLockNum;         // 起始锁针针数
                    blockTimes  = paraBLockTimes;       // 起始锁针次数
                    blockjumps  = paraBLockJumps;       // 起针跳过针数
                    if ((blockTimes%2) != 0)            // 使回针成为偶数
                    {
                        blockTimes++;
                        blockjumps += blockNum;
                    }
                }

                if (    idx+1 >= sqrtNum ||  // 边界条件 数据最后

                        (ctrl == DATA_SYNCSEW &&
                         (m_vSqitItemList[idx+1].m_code == DATA_SEWING
                          || m_vSqitItemList[idx+1].m_code == DATA_SECF_SEW)) || // 两个机头变成一个机头时候需要添加剪线 这个剪线的具体执行要下位机自己判断

                        ((ctrl == DATA_SEWING || ctrl == DATA_SYNCSEW || ctrl == DATA_SECF_SEW) &&    // 一组线段的后面添加剪线
                         (m_vSqitItemList[idx+1].m_code == DATA_OFFSET ||
                          m_vSqitItemList[idx+1].m_code == DATA_SECF_OFST ||
                          m_vSqitItemList[idx+1].m_code == DATA_SYNCOFST)) ||

                        fabs(m_vSqitItemList.at(idx+1).m_begx - m_vSqitItemList.at(idx).m_endx) > 1 ||  // 上一条线的尾部和和下一条的头部不相连 边界条件 基本不会触发
                        fabs(m_vSqitItemList.at(idx+1).m_begy - m_vSqitItemList.at(idx).m_endy) > 1 ||  // 上一条线的尾部和和下一条的头部不相连 边界条件 基本不会触发
                        0   )
                {
                    elockNum    = paraELockNum;         // 结束锁针针数
                    elockTimes  = paraELockTimes;       // 结束锁针次数
                    elockjumps  = paraELockJumps;       // 结束跳过针数
                    if ((elockTimes%2) != 0)            // 使回针成为偶数
                    {
                        elockTimes++;
                        elockjumps += elockNum;
                    }

                    cutflag = 1;
                }
            }

            threex[0] = m_vSqitItemList.at(idx).m_begx;
            threey[0] = m_vSqitItemList.at(idx).m_begy;
            threex[1] = m_vSqitItemList.at(idx).m_midx;
            threey[1] = m_vSqitItemList.at(idx).m_midy;
            threex[2] = m_vSqitItemList.at(idx).m_endx;
            threey[2] = m_vSqitItemList.at(idx).m_endy;

            stepNumber = CalcCurve(threex, threey, NULL, NULL, NULL, stepSize, NULL, ctrl);
            curtNumber = stepNumber + blockNum*blockTimes + elockNum*elockTimes;

            //          qDebug("stepNumber = %d, cur totalNumber=%d:\r\n", stepNumber, curtNumber);

            if (totalNumber + curtNumber >= maxitemnum)
            {
                rslt = -1;
                break;
            }
            pData = pSteps + (blockNum*blockTimes);

            n = CalcCurve(threex, threey, &actx, &acty, &actr, stepSize, pData, ctrl);
            if (n != stepNumber)
            {
                //              qDebug("create number =%d, is not equal to stepNumber=%d:\r\n", n, stepNumber);
            }

            //------------------
            // 倒序添加起针锁针
#if (0)
            // 起始锁针信息
            printf("before add lock:\r\n");
            for (i = 0; i < curtNumber; i++)
            {
                printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pSteps[i].ctrl, pSteps[i].attr, pSteps[i].dx, pSteps[i].dy);
            }
#endif
            pTemp = pData - 1;
            k = blockTimes*blockNum;
            for (i = 0; i < blockTimes; i++)
            {
                if (i%2 == 0)	// 奇数锁针
                {
                    //				printf("ji shu:\r\n");
                    for (j = 0; j < blockNum; j++)
                    {
                        // 拷贝针步
                        memcpy(pTemp, &(pData[j]), sizeof(DataItem));
                        pTemp->dx *= -1;
                        pTemp->dy *= -1;		// 方向取反
                        pTemp->dr *= -1;		// 方向取反
                        k--;
                        if (k < blockjumps)		// 跳过计数器
                        {
                            pTemp->ctrl = DATA_OFFSET;  // 转换为offset
                        }
                        else
                        {
                            attr = pTemp->attr;
                            attr |= ATTR_RESEW;		// 回针标志
                            pTemp->attr = attr;
                        }
                        pTemp--;
                    }
                }
                else	// 偶数锁针
                {
                    //				printf("ou shu:\r\n");
                    for (j = blockNum-1; j >= 0; j--)
                    {
                        // 拷贝针步
                        memcpy(pTemp, &(pData[j]), sizeof(DataItem));

                        k--;
                        if (k < blockjumps)		// 跳过计数器
                        {
                            pTemp->ctrl = DATA_OFFSET;  // 转换为offset
                        }
                        else
                        {
                            attr = pTemp->attr;
                            attr |= ATTR_RESEW;		// 回针标志
                            pTemp->attr = attr;
                        }
                        pTemp--;
                    }
                }
            }
            // 正向扫描，修正起针回针中的dr
            k = blockTimes*blockNum;
            pTemp = pData - k;
            if(blockTimes != 0  )
            {
                for (i = 0; i <= blockTimes; i++)   // 跳过第一次锁针(偶数)，且
                {
                    if (i%2 == 0)	// 偶数锁针
                    {
                        if (i == 0)   // 第一针, 这里不做处理，后面添加单独运动dr的offset
                        {
                        }
                        else
                        {
                            pTemp->dr = 0;
                        }
                        pTemp += blockNum;
                    }
                    else            // 奇数锁针
                    {
                        pTemp += blockNum - 1 ;
                        pTemp->dr = 0;
                        pTemp++;
                    }
                }
            }
#if (0)
            // 结束锁针信息
            printf("after add begin lock:\r\n");
            for (i = 0; i < curtNumber; i++)
            {
                printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
            }
#endif
            //------------------
            // 顺序添加末针锁针
            pTemp = pData + stepNumber;
            k = 0;
            for (i = 0; i < elockTimes; i++)
            {
                if (i%2 == 0)	// 奇数锁针
                {
                    for (j = 0; j < elockNum; j++)
                    {
                        // 拷贝针步
                        memcpy(pTemp, &(pData[stepNumber-1-j]), sizeof(DataItem));
                        pTemp->dx *= -1;
                        pTemp->dy *= -1;		// 方向取反
                        pTemp->dr *= -1;		// 方向取反

                        k++;
                        if (k > elockTimes*elockNum - elockjumps)		// 结束跳过计数器
                        {
                            pTemp->ctrl = DATA_OFFSET;  // 转换为offset
                        }
                        else
                        {
                            attr = pTemp->attr;
                            attr |= ATTR_RESEW;		// 回针标志
                            pTemp->attr = attr;
                        }
                        pTemp++;
                    }
                }
                else
                {
                    for (j = elockNum-1; j >= 0; j--)
                    {
                        // 拷贝针步
                        memcpy(pTemp, &(pData[stepNumber-1-j]), sizeof(DataItem));
                        k++;
                        if (k > elockTimes*elockNum - elockjumps)		// 结束跳过计数器
                        {
                            pTemp->ctrl = DATA_OFFSET;  // 转换为offset
                        }
                        else
                        {
                            attr = pTemp->attr;
                            attr |= ATTR_RESEW;		// 回针标志
                            pTemp->attr = attr;
                        }
                        pTemp++;
                    }
                }
            }

#if (0)
            printf("after add end lock:\r\n");
            for (i = 0; i < curtNumber; i++)
            {
                printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
            }
#endif
            //------------------

            stepNumber = curtNumber;

            if (cutflag != 0)	// 缝纫针步添加剪线码
            {
                // 添加剪线码
                pSteps[stepNumber].ctrl = DATA_CUTTRD;
                pSteps[stepNumber].attr = 0;
                pSteps[stepNumber].dx = 0;
                pSteps[stepNumber].dy = 0;
                pSteps[stepNumber].dr = 0;
                stepNumber++;
            }

#if (0)
            printf("after jump lock:\r\n");
            for (i = 0; i < curtNumber; i++)
            {
                printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pSteps[i].ctrl, pSteps[i].attr, pSteps[i].dx, pSteps[i].dy);
            }
#endif

            pSteps += stepNumber;
            totalNumber += stepNumber;
            begflag = 1;
        }	// end of for(idx......

        //------------------
        // 最后一针添加结束码
        dataItemArray[totalNumber].ctrl = DATA_END;
        dataItemArray[totalNumber].attr = 0;
        dataItemArray[totalNumber].dx = 0;
        dataItemArray[totalNumber].dy = 0;
        dataItemArray[totalNumber].dr = 0;

        totalNumber++;
        if (rslt != 0)
        {
            qDebug("no enough item mem");
        }

#if (0)
        printf("after calc, begx=%d, begy=%d, stepNumber=%d\r\n", begx, begy, totalNumber);
#endif

#if (1)
        // 剪线码移到缝纫数据之后
        pData = dataItemArray;    // 源
        begflag = 0;

        for (i = 0; i < totalNumber; i++)
        {
            if ((pData->ctrl == DATA_SEWING || pData->ctrl == DATA_SYNCSEW))
            {
                begflag = 1;
            }
            else if (pData->ctrl == DATA_OFFSET)
            {
                if (begflag == 1)
                {
                    pSteps = pData;
                    begflag = 2;
                }
                else if (begflag != 2)
                {
                    begflag = 0;
                }
            }
            else if (pData->ctrl == DATA_CUTTRD)
            {
                if (begflag == 2)
                {
                    // 交换 pSteps 和 pData
                    DataItem tmpItem;
                    memcpy(&tmpItem, pData, sizeof(DataItem));
                    memcpy(pData, pSteps, sizeof(DataItem));
                    memcpy(pSteps, &tmpItem, sizeof(DataItem));
                }
                begflag = 0;
            }
            else
            {
                begflag = 0;
            }
            pData++;
        }

#endif
        pData = dataItemArray;      // 源
        pSteps = pData;             // 目标
        // 扫描生成数据，确定起点坐标，合并offset数据
        // 起点坐标
        begr = pData[0].dr;        // 第一个针步，dr是从0开始的变化量
        pData[0].dr = 0;           // 设置第一个针步的变化量为0

        i = 0;
#if (0)
        for (i = 0; i < totalNumber; i++)
        {
            if (pData->ctrl != DATA_OFFSET)   // 起始的offset合并到起点坐标
            {
                break;
            }

            begx += pData->dx;
            begy += pData->dy;
            begr += pData->dr;        // 改变起针位置
            pData++;                  // 源后移
        }
#endif

        begflag = 0;
        actr = begr;
#if (0)
        int offset_dr;

        // 继续扫描生成数据，合并offset数据
        for (i = i, j = 0; i < totalNumber; i++)
        {
            if (pData->ctrl == DATA_OFFSET)
            {
                if (begflag == 0)
                {
                    // 初始化offset计数
                    threex[0] = 0;
                    threey[0] = 0;
                    threex[1] = 0;
                    threey[1] = 0;
                    threex[2] = 0;
                    threey[2] = 0;
                    offset_dr = 0;
                    begflag = 1;
                }

                threex[2] += pData->dx;
                threey[2] += pData->dy;
                offset_dr += pData->dr;
            }
            else
            {
                if (begflag != 0 && pData->ctrl != DATA_END)
                {
                    // 重新插入偏移数据
                    actx = 0;
                    acty = 0;
                    stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, S16_MAX*3/5, pSteps, DATA_OFFSET);
                    pSteps->dr = offset_dr ;

                    pSteps += stepNumber;
                    j += stepNumber;
                    begflag = 0;
                }
                if (pSteps != pData)
                {
                    memcpy(pSteps, pData, sizeof(DataItem));
                }
                j++;
                actr += pSteps->dr;
                pSteps++;
            }

            pData++;
        }

        totalNumber = j;
#endif

#if (0)
        printf("before write begx=%d, begy=%d, stepNumber=%d\r\n", begx, begy, totalNumber);
#endif

#ifdef used_mac_DHQ  // 1  插入小的数据 0 不插入小的数据

        DataItem * cp_dataItemArray = new DataItem[totalNumber];

        memcpy( cp_dataItemArray , dataItemArray  , sizeof( DataItem )*totalNumber);

        j = 0 ;
        for (int var = 0; var < totalNumber; ++var)
        {
            if((var + 1) > totalNumber)
            {
                break;
            }
            else if(
                    (cp_dataItemArray[var].ctrl == cp_dataItemArray[var + 1].ctrl)
                    &&
                    ((cp_dataItemArray[var].ctrl == DATA_SEWING)||
                     (cp_dataItemArray[var].ctrl == DATA_SECF_SEW)||
                     (cp_dataItemArray[var].ctrl == DATA_SYNCSEW)
                     )
                    &&
                    (fabs( cp_dataItemArray[var].len - cp_dataItemArray[var + 1 ].len) >
                     1.8 * m_rvsf_info.i_dense_step)
                    )
            {
                DataItem temp ;
#if 1
                memset( &temp , 0 ,  sizeof (DataItem ));

                int len = cp_dataItemArray[var].len ;

                if( cp_dataItemArray[ var ].len > cp_dataItemArray[ var + 1 ].len )
                {
                    len =  cp_dataItemArray[ var + 1 ].len ;
                }
                else  if( cp_dataItemArray[var].len < cp_dataItemArray[var + 1].len)
                {
                    len =  cp_dataItemArray[ var ].len ;
                }

                if( abs( cp_dataItemArray[var].len - cp_dataItemArray[var + 1 ].len ) > len*0.3 )
                {
                    memcpy( &(temp) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                    temp.attr |=  ATTR_RESEW;
                    memcpy( &(dataItemArray[j]) , &(temp) , sizeof( DataItem ));
                    j++;
                }
                else if( abs( cp_dataItemArray[var].len - cp_dataItemArray[var + 1 ].len ) > len*0.3 )
                {
                    memcpy( &(dataItemArray[j]) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                    j++;
                    var++;
                    memcpy( &(temp) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                    temp.attr |=  ATTR_RESEW;
                    memcpy( &(dataItemArray[j]) , &(temp) , sizeof( DataItem ));
                    j++;
                }
#endif

#if 0

                if( cp_dataItemArray[var].len > cp_dataItemArray[var + 1 ].len)
                {

                    //两个索引都退两个
                    var -= 2;
                    j   -= 2;

                    //复制第一个针步
                    memcpy( &temp , &(cp_dataItemArray[var]) , sizeof( DataItem ));

                    temp.dx = temp.dx / 2 ;
                    temp.dy = temp.dy / 2 ;
                    temp.attr |=  ATTR_RESEW;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[var]) , &temp, sizeof( DataItem ));
                    j++ ;

                    temp.dx = cp_dataItemArray[var].dx - temp.dx ;
                    temp.dy = cp_dataItemArray[var].dy - temp.dy ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[var]) , &temp, sizeof( DataItem ));
                    j++ ;
                    var++;

                    //复制第二个针步
                    memcpy( &temp , &(cp_dataItemArray[var]) , sizeof( DataItem ));

                    temp.dx = temp.dx / 2 ;
                    temp.dy = temp.dy / 2 ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[j]) , &temp, sizeof( DataItem ));
                    j++ ;

                    temp.dx = cp_dataItemArray[var].dx - temp.dx ;
                    temp.dy = cp_dataItemArray[var].dy - temp.dy ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[j]) , &temp, sizeof( DataItem ));
                    j++ ;
                    var++;
                }
                else if( cp_dataItemArray[var + 1].len > cp_dataItemArray[var].len)
                {

                    memcpy( &(dataItemArray[j]) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                    var++;
                    j++ ;

                    //复制第一个针步
                    memcpy( &temp , &(cp_dataItemArray[var]) , sizeof( DataItem ));

                    temp.dx = temp.dx / 2 ;
                    temp.dy = temp.dy / 2 ;
                    temp.attr |=  ATTR_RESEW;

                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[var]) , &temp, sizeof( DataItem ));
                    j++ ;

                    temp.dx = cp_dataItemArray[var].dx - temp.dx ;
                    temp.dy = cp_dataItemArray[var].dy - temp.dy ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[var]) , &temp, sizeof( DataItem ));
                    j++ ;
                    var++;

                    //复制第二个针步
                    memcpy( &temp , &(cp_dataItemArray[var]) , sizeof( DataItem ));

                    temp.dx = temp.dx / 2 ;
                    temp.dy = temp.dy / 2 ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[j]) , &temp, sizeof( DataItem ));
                    j++ ;

                    temp.dx = cp_dataItemArray[var].dx - temp.dx ;
                    temp.dy = cp_dataItemArray[var].dy - temp.dy ;
                    temp.len = sqrt( temp.dx * temp.dx* 1.0 + temp.dy *temp.dy * 1.0);
                    memcpy( &(dataItemArray[j]) , &temp, sizeof( DataItem ));
                    j++ ;
                    var++;
                }
#endif
            }
            else
            {
                memcpy( &(dataItemArray[j]) , &(cp_dataItemArray[var]) , sizeof( DataItem ));
                j++ ;
            }
        }
        delete [] cp_dataItemArray;
        totalNumber = j;
#endif

#if 0
        QList < DataItem > i_list ;
        DataItem i_item ;

        for( int count = 0 ; count  <  (totalNumber); count++)
        {
            memset( & i_item , 0  , sizeof ( DataItem ));
            memcpy( & i_item , & (dataItemArray[ count ]) , sizeof ( DataItem ));

            i_list.append(i_item);

            if( (count + 1) == totalNumber )
            {
                break;
            }

            if(
                    ( dataItemArray[count].ctrl == DATA_OFFSET  )
                    &&
                    (
                        ( dataItemArray[count + 1 ].ctrl == DATA_RKNIFE  )
                        ||( dataItemArray[count + 1 ].ctrl == DATA_SKNIFE  )
                        )
                    )
            {
                i_item.ctrl = DATA_OFFSET ;
//                i_item.ctrl = dataItemArray[count + 1 ].ctrl ;
                i_item.attr = 0 ;
                i_item.dx   = 0 ;
                i_item.dy   = 0 ;
                i_item.dr   = dataItemArray[i + 1 ].dr ;
                i_item.len  = 0 ;

                i_list.append(i_item);
                dataItemArray[count + 1 ].dr = 0 ;
            }
        }

        totalNumber =  i_list.size() ;
        for( int count = 0 ; count  < totalNumber ; count++)
        {
            memcpy(  & (dataItemArray[ count ]) , & (i_list[count]) ,  sizeof ( DataItem ));
        }

        i_list.clear();

#endif

            // dataItemArray

            for( int i = 0 ; i  <  (totalNumber -1); i++)
            {
                if(
                        ( dataItemArray[i].ctrl == DATA_OFFSET  )
                        &&
                        (
                            ( dataItemArray[i + 1 ].ctrl == DATA_RKNIFE  )
                            ||( dataItemArray[i + 1 ].ctrl == DATA_SKNIFE  )
                            ||( dataItemArray[i + 1 ].ctrl == DATA_DRAWING  )
                            )
                        )
                {
                    int nSum = dataItemArray[i  ].dr + dataItemArray[i + 1 ].dr;

                    if(abs(nSum)> PI*RADIAN_ACCURACY)
                    {
                        if(nSum >0)
                        {
                            nSum -=  2*PI*RADIAN_ACCURACY;
                        }
                        else
                        {
                            nSum +=  2*PI*RADIAN_ACCURACY;
                        }
                    }

                    dataItemArray[i  ].dr = nSum;

                    dataItemArray[i + 1 ].dr = 0 ;
                }
            }

        // 写文件头
        DataFileHead fileHead;	// 数据文件头描述
        memset(&fileHead, 0, sizeof(DataFileHead));

        m_filename = "test.plt";
        QByteArray ba = m_filename.toLatin1();  // ISO-8859-1 文件名称
        int cpsize = ba.size();
        if (cpsize > 32)
        {
            cpsize = 32;
        }


        memcpy(fileHead.fileName, (char*)ba.data(), cpsize);

        fileHead.dataSize = totalNumber*sizeof(DataItem);	// 文件长度
        fileHead.itemNums = totalNumber;					// 有效针数
        fileHead.bytesPerItem = sizeof(DataItem);			// 每针占的字节数
        fileHead.bytesPerBlk = 1024;						// 文件内容划分块大小

        fileHead.dataChecksum = CalcCheckSum32((u8*)(dataItemArray), totalNumber*sizeof(DataItem));  // 花样数据累加校验和
        fileHead.checkCrc = CalcCrc16((u8*)(&fileHead), 6*sizeof(u32));   // 前6个字段CRC校验


        s32 minx, miny, maxx, maxy;
        GetDataMinMax(dataItemArray, totalNumber, minx, miny, maxx, maxy);


        qDebug()<<minx<<miny<<maxx<<maxy;
//        fileHead.minX = minx - minx  + m_beginX;
//        fileHead.maxX = maxx - minx  + m_beginX;
//        fileHead.minY = miny - miny  + m_beginY;
//        fileHead.maxY = maxy - miny  + m_beginY;

        fileHead.minX = minx + m_beginX;
        fileHead.maxX = maxx + m_beginX;
        fileHead.minY = miny + m_beginY;
        fileHead.maxY = maxy + m_beginY;

        fileHead.beginX = m_beginX ;
        fileHead.beginY = m_beginY ;
        fileHead.beginR = begr;                 // 起始角度

        fileHead.anchorX = m_anchorX;
        fileHead.anchorY = m_anchorY;		// 定位点


        qDebug()<<"fileHead.minX ="<<fileHead.minX /100.0<<"fileHead.maxX ="<<fileHead.maxX/100.0;
        qDebug()<<"fileHead.minY ="<<fileHead.minY /100.0<<"fileHead.maxY ="<<fileHead.maxY/100.0;
        qDebug()<<"fileHead.beginX = "<<fileHead.beginX /100.0<<"fileHead.beginY ="<<fileHead.beginY/100.0;
        qDebug()<<"fileHead.anchorX ="<<fileHead.anchorX/100.0<<"fileHead.anchorY = "<<fileHead.anchorY/100.0;


        /*
    +  begx
    +  begy
    +  begx
    +  begy
*/
#if (0)
        if( 1 )
            m_anchorSel = 1 ; // 当文件是 qui 的时候

            fileHead.beginX = begx;
            {
            fileHead.beginY = begy;
        }
        else if( 0 )
        {
            m_anchorSel = 0 ; //当文件是 rvsf 的时候

            fileHead.beginX = m_rvsf_info.i_Gantry;
            fileHead.beginY = m_rvsf_info.i_Head_B;
            fileHead.beginR = begr;			// 起始点坐标

            fileHead.beginX2 = m_rvsf_info.i_Gantry;
            fileHead.beginY2 = m_rvsf_info.i_Head_A;
            fileHead.beginR2 = 0;

            if( fileHead.beginX2  < fileHead.minX)
            {
                fileHead.minX = fileHead.beginX2;
            }
            if( fileHead.beginX2  > fileHead.maxX)
            {
                fileHead.maxX = fileHead.beginX2;
            }
            if( fileHead.beginY2  < fileHead.minY)
            {
                fileHead.minY = fileHead.beginY2;
            }
            if( fileHead.beginY2  > fileHead.maxY)
            {
                fileHead.maxY = fileHead.beginY2;
            }
        }
        // 定位点选择; 0, 和起点重合; 1，图形的左下角; 2, 图形的右下角; 3, 图形的右上角; 4, 图形的左上角; 5, 图形的中心
        switch (m_anchorSel)
        {
        case 1:                 // 1，图形的左下角
            fileHead.anchorX = fileHead.minX;
            fileHead.anchorY = fileHead.minY;		// 定位点
            break;
        case 2:                 // 2，图形的右下角
            fileHead.anchorX = fileHead.maxX;
            fileHead.anchorY = fileHead.minY;		// 定位点
            break;
        case 3:                 // 3，图形的右上角
            fileHead.anchorX = fileHead.maxX;
            fileHead.anchorY = fileHead.maxY;		// 定位点
            break;
        case 4:                 // 4，图形的左上角
            fileHead.anchorX = fileHead.minX;
            fileHead.anchorY = fileHead.maxY;		// 定位点
            break;
        default:

            fileHead.anchorX = fileHead.beginX;
            fileHead.anchorY = fileHead.beginY;		// 定位点

            fileHead.anchorX2 = fileHead.beginX2 ;
            fileHead.anchorY2 = fileHead.beginY2 ;	// 定位点

            break;
        }
#endif



#if (0)
        printf("finial write:\r\n");
        for (i = 0; i < stepNumber; i++)
        {
            printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
        }
#endif
        // 拷贝数据
        ds16Ary.resize(sizeof(DataFileHead)+totalNumber*sizeof(DataItem));
        memcpy (ds16Ary.data(), &fileHead, sizeof(DataFileHead));
        memcpy (&m_fileHead, &fileHead, sizeof(DataFileHead));
        memcpy (ds16Ary.data() + sizeof(DataFileHead), dataItemArray, totalNumber*sizeof(DataItem));

        delete []dataItemArray;
    }

    return rslt;
}
#else
int VectorSqrt::CreateDs16FromSqrt(QByteArray & ds16Ary)
{
    double threex[3], threey[3];

    int begx, begy, begr, begflag;
    int blockNum, blockTimes;
    int elockNum, elockTimes;
    int blockjumps, elockjumps;
    int stepSize, sqrtNum;
    int actx, acty, actr;
    int i, j, k, idx;
    int stepNumber, curtNumber, totalNumber;
    int n, cutflag;

    unsigned char  ctrl, oldctrl, attr;

    const int maxitemnum = MAX_ITEM_NUM;
    DataItem * pSteps, * pData, * pTemp;
    DataItem * dataItemArray = new DataItem[maxitemnum];
    if (dataItemArray == NULL)
    {
        return -1;
    }
    pSteps = dataItemArray;				// 数据存放地址



    //------------------
#if (0)
    printf("SqrtInfo para:\r\n");

    printf("\t midy = %d\r\n", pSqrt->sqrtNum);
    printf("\t stepSize = %d\r\n", pSqrt->stepSize);
    printf("\t blockNum = %d\r\n", pSqrt->blockNum);
    printf("\t blockTimes = %d\r\n", pSqrt->blockTimes);
    printf("\t elockNum = %d\r\n", pSqrt->elockNum);
    printf("\t elockTimes = %d\r\n", pSqrt->elockTimes);
    printf("\t blockjumps = %d\r\n", pSqrt->blockjumps);
    printf("\t elockjumps = %d\r\n", pSqrt->elockjumps);
#endif

    sqrtNum = m_vSqitItemList.size();   // 图形个数

    stepSize = m_para_stepSize;			// 分割针步大小

    begx = m_beginX;
    begy = m_beginY;
    begr = 0;

    actx = begx;
    acty = begy;
    actr = 0;

    begflag = 0;
    totalNumber = 0;
    oldctrl = 0;
    cutflag = 0;

    //------------------
    // 生成文件内容
    //int tttt = 0;
    for (idx = 0; idx < sqrtNum; idx++)
    {


#if (0)
        printf("\t begx = %f\r\n", pSqrt->sqrtItem[idx].begx);
        printf("\t begy = %f\r\n", pSqrt->sqrtItem[idx].begy);
        printf("\t endx = %f\r\n", pSqrt->sqrtItem[idx].endx);
        printf("\t endy = %f\r\n", pSqrt->sqrtItem[idx].endy);
        printf("\t midx = %f\r\n", pSqrt->sqrtItem[idx].midx);
        printf("\t midy = %f\r\n", pSqrt->sqrtItem[idx].midy);
#endif
        if (begflag != 0)
        {
            if (m_vSqitItemList.at(idx).m_begx != m_vSqitItemList.at(idx-1).m_endx ||
                    m_vSqitItemList.at(idx).m_begy != m_vSqitItemList.at(idx-1).m_endy ||
                    0	)
            {
                // 自动插入偏移数据
                threex[0] = m_vSqitItemList.at(idx-1).m_endx;
                threey[0] = m_vSqitItemList.at(idx-1).m_endy;
                threex[1] = m_vSqitItemList.at(idx).m_begx;
                threey[1] = m_vSqitItemList.at(idx).m_begy;
                threex[2] = m_vSqitItemList.at(idx).m_begx;
                threey[2] = m_vSqitItemList.at(idx).m_begy;		// 三点共线，作为直线

                stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, S16_MAX/2, pSteps, DATA_OFFSET);
                pSteps += stepNumber;
                totalNumber += stepNumber;

            }
        }

        oldctrl = ctrl;
        //ctrl = m_vSqitItemList.at(idx).m_sqrttype;//20200211
        ctrl = m_vSqitItemList.at(idx).m_code;

        blockNum = 0;
        blockTimes = 0;
        blockjumps = 0;

        elockNum = 0;
        elockTimes = 0;
        elockjumps = 0;
        cutflag = 0;

        if ((ctrl == DATA_SEWING || ctrl == DATA_SYNCSEW))
        {
            if (oldctrl != ctrl)
            {
                blockNum = m_para_blockNum;			// 起始锁针针数
                blockTimes = m_para_blockTimes;		// 起始锁针次数
                blockjumps = m_para_blockjumps;		// 起针跳过针数

                if (blockTimes > 0)
                {
                    if (blockjumps > blockTimes*blockNum)
                    {
                        blockTimes = 0;
                        blockNum = 0;
                        blockjumps = 0;
                    }
                }
                else
                {
                    blockTimes = 0;
                    blockNum = 0;
                    blockjumps = 0;
                }
            }

            if (idx+1 >= sqrtNum || m_vSqitItemList.at(idx+1).m_code != ctrl)
            {
                elockNum = m_para_blockNum;			// 结束锁针针数
                elockTimes = m_para_blockTimes;		// 结束锁针次数
                elockjumps =  m_para_blockjumps;		// 结束跳过针数
                cutflag = 1;
                if (elockTimes > 0)
                {
                    if (elockjumps > elockTimes*elockNum)
                    {
                        elockTimes = 0;
                        elockNum = 0;
                        elockjumps = 0;
                    }
                }
                else
                {
                    elockTimes = 0;
                    elockNum = 0;
                    elockjumps = 0;
                }
            }
        }

        threex[0] = m_vSqitItemList.at(idx).m_begx;
        threey[0] = m_vSqitItemList.at(idx).m_begy;
        threex[1] = m_vSqitItemList.at(idx).m_midx;
        threey[1] = m_vSqitItemList.at(idx).m_midy;
        threex[2] = m_vSqitItemList.at(idx).m_endx;
        threey[2] = m_vSqitItemList.at(idx).m_endy;

        stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, stepSize, NULL, ctrl);
        curtNumber = stepNumber + blockNum*blockTimes + elockNum*elockTimes - blockjumps - elockjumps;

        //      printf("stepNumber = %d, cur totalNumber=%d:\r\n", stepNumber, curtNumber);

        pData = pSteps + (blockNum*blockTimes) - blockjumps;
        n = CalcCurve(threex, threey, &actx, &acty, &actr, stepSize, pData, ctrl);
        if (n != stepNumber)
        {
            //       printf("create number =%d, is not equal to stepNumber=%d:\r\n", n, stepNumber);
        }


        if (begflag == 0)
        {
            begr = pData->dr;
            pData->dr = 0;
        }

#if (0)
        // 起始锁针信息
        printf("before add lock:\r\n");
        for (i = 0; i < curtNumber; i++)
        {
            printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pSteps[i].ctrl, pSteps[i].attr, pSteps[i].dx, pSteps[i].dy);
        }
#endif

        // 倒序添加起针锁针
        pTemp = pData - 1;
        k = blockTimes*blockNum;
        for (i = 0; i < blockTimes; i++)
        {
            if (k < blockjumps)		// 跳过计数器
            {
                break;
            }
            k--;
            if (i%2 == 0)	// 奇数锁针
            {
                //				printf("ji shu:\r\n");
                for (j = 0; j < blockNum; j++)
                {
                    // 拷贝针步
                    memcpy(pTemp, &(pData[j]), sizeof(DataItem));
                    attr = pTemp->attr;
                    pTemp->dx *= -1;
                    pTemp->dy *= -1;		// 方向取反
                    pTemp->dr *= -1;		// 方向取反
                    attr |= ATTR_RESEW;		// 回针标志
                    pTemp->attr = attr;

                    if (begflag == 0)
                    {
                        begx += pTemp->dx;
                        begy += pTemp->dy;
                    }
                    pTemp--;
                }
            }
            else	// 偶数锁针
            {
                //				printf("ou shu:\r\n");
                for (j = blockNum-1; j >= 0; j--)
                {
                    // 拷贝针步
                    memcpy(pTemp, &(pData[j]), sizeof(DataItem));
                    pTemp->attr |= ATTR_RESEW;		// 回针标志

                    if (begflag == 0)
                    {
                        begx += pTemp->dx;
                        begy += pTemp->dy;
                    }
                    pTemp--;
                }
            }
        }

#if (0)
        // 结束锁针信息
        printf("after add begin lock:\r\n");
        for (i = 0; i < curtNumber; i++)
        {
            printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
        }
#endif

        // 顺序添加末针锁针
        pTemp = pData + stepNumber;
        k = 0;
        for (i = 0; i < elockTimes; i++)
        {
            k++;
            if (k > elockTimes*elockNum - elockjumps)		// 结束跳过计数器
            {
                break;
            }
            if (i%2 == 0)	// 奇数锁针
            {
                for (j = 0; j < elockNum; j++)
                {
                    // 拷贝针步
                    memcpy(pTemp, &(pData[stepNumber-1-j]), sizeof(DataItem));
                    attr = pTemp->attr;
                    pTemp->dx *= -1;
                    pTemp->dy *= -1;		// 方向取反
                    pTemp->dr *= -1;		// 方向取反
                    attr |= ATTR_RESEW;		// 回针标志
                    pTemp->attr = attr;
                    pTemp++;
                }
            }
            else
            {
                for (j = elockNum-1; j >= 0; j--)
                {
                    // 拷贝针步
                    memcpy(pTemp, &(pData[stepNumber-1-j]), sizeof(DataItem));
                    pTemp->attr |= ATTR_RESEW;	// 回针标志
                    pTemp++;
                }
            }
        }

#if (0)
        printf("after add end lock:\r\n");
        for (i = 0; i < curtNumber; i++)
        {
            printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
        }
#endif

        stepNumber = curtNumber;

        if (cutflag != 0)	// 缝纫针步添加剪线码
        {
            // 添加剪线码
            pSteps[stepNumber].ctrl = DATA_CUTTRD;
            pSteps[stepNumber].attr = 0;
            pSteps[stepNumber].dx = 0;
            pSteps[stepNumber].dy = 0;
            stepNumber++;
        }

#if (0)
        printf("after jump lock:\r\n");
        for (i = 0; i < curtNumber; i++)
        {
            printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pSteps[i].ctrl, pSteps[i].attr, pSteps[i].dx, pSteps[i].dy);
        }
#endif

        pSteps += stepNumber;
        totalNumber += stepNumber;
        begflag = 1;

    }	// end of for(idx......

    // 最后一针添加结束码
    dataItemArray[totalNumber].ctrl = DATA_END;
    dataItemArray[totalNumber].attr = 0;
    dataItemArray[totalNumber].dx = 0;
    dataItemArray[totalNumber].dy = 0;
    totalNumber++;

    // 合并角度到前面的offset
    DataItem * pTDItem;
    pTDItem = new DataItem[totalNumber];

    memcpy(pTDItem, dataItemArray, sizeof(DataItem)*totalNumber);

    for (i = 0, j = 0; i < totalNumber; i++)
    {
        if (i != 0 && pTDItem[i-1].ctrl == DATA_OFFSET && pTDItem[i].ctrl != DATA_OFFSET && pTDItem[i].dr != 0)
        {
            memset(&(dataItemArray[j]), 0, sizeof(DataItem));
            dataItemArray[j].ctrl = DATA_OFFSET;
            dataItemArray[j].dr = pTDItem[i].dr;
            j++;
            pTDItem[i].dr = 0;
        }

        memcpy(&(dataItemArray[j]), &(pTDItem[i]), sizeof(DataItem));
        j++;
    }
    totalNumber = j;
    delete []pTDItem;
    pTDItem = NULL;

    // 写文件头
    // 写文件头
    DataFileHead fileHead;	// 数据文件头描述
    memset(&fileHead, 0, sizeof(DataFileHead));

    m_filename = "test.plt";
    QByteArray ba = m_filename.toLatin1();  // ISO-8859-1 文件名称
    int cpsize = ba.size();
    if (cpsize > 32)
    {
        cpsize = 32;
    }


    memcpy(fileHead.fileName, (char*)ba.data(), cpsize);

    fileHead.dataSize = totalNumber*sizeof(DataItem);	// 文件长度
    fileHead.itemNums = totalNumber;					// 有效针数
    fileHead.bytesPerItem = sizeof(DataItem);			// 每针占的字节数
    fileHead.bytesPerBlk = 1024;						// 文件内容划分块大小

    fileHead.dataChecksum = CalcCheckSum32((u8*)(dataItemArray), totalNumber*sizeof(DataItem));  // 花样数据累加校验和
    fileHead.checkCrc = CalcCrc16((u8*)(&fileHead), 6*sizeof(u32));   // 前6个字段CRC校验


    s32 minx, miny, maxx, maxy;
    GetDataMinMax(dataItemArray, totalNumber, minx, miny, maxx, maxy);

//    fileHead.minX = minx - minx  + m_beginX;
//    fileHead.maxX = maxx - minx  + m_beginX;
//    fileHead.minY = miny - miny  + m_beginY;
//    fileHead.maxY = maxy - miny  + m_beginY;

    fileHead.minX = minx + m_beginX;
    fileHead.maxX = maxx + m_beginX;
    fileHead.minY = miny + m_beginY;
    fileHead.maxY = maxy + m_beginY;

    fileHead.beginX = m_beginX ;
    fileHead.beginY = m_beginY ;
    fileHead.beginR = begr;                 // 起始角度

    fileHead.anchorX = m_anchorX;
    fileHead.anchorY = m_anchorY;		// 定位点



    /*
+  begx
+  begy
+  begx
+  begy
*/
#if (0)
    if( 1 )
    {
        m_anchorSel = 1 ; // 当文件是 qui 的时候

        fileHead.beginX = begx;
        fileHead.beginY = begy;
    }
    else if( 0 )
    {
        m_anchorSel = 0 ; //当文件是 rvsf 的时候

        fileHead.beginX = m_rvsf_info.i_Gantry;
        fileHead.beginY = m_rvsf_info.i_Head_B;
        fileHead.beginR = begr;			// 起始点坐标

        fileHead.beginX2 = m_rvsf_info.i_Gantry;
        fileHead.beginY2 = m_rvsf_info.i_Head_A;
        fileHead.beginR2 = 0;

        if( fileHead.beginX2  < fileHead.minX)
        {
            fileHead.minX = fileHead.beginX2;
        }
        if( fileHead.beginX2  > fileHead.maxX)
        {
            fileHead.maxX = fileHead.beginX2;
        }
        if( fileHead.beginY2  < fileHead.minY)
        {
            fileHead.minY = fileHead.beginY2;
        }
        if( fileHead.beginY2  > fileHead.maxY)
        {
            fileHead.maxY = fileHead.beginY2;
        }
    }
    // 定位点选择; 0, 和起点重合; 1，图形的左下角; 2, 图形的右下角; 3, 图形的右上角; 4, 图形的左上角; 5, 图形的中心
    switch (m_anchorSel)
    {
    case 1:                 // 1，图形的左下角
        fileHead.anchorX = fileHead.minX;
        fileHead.anchorY = fileHead.minY;		// 定位点
        break;
    case 2:                 // 2，图形的右下角
        fileHead.anchorX = fileHead.maxX;
        fileHead.anchorY = fileHead.minY;		// 定位点
        break;
    case 3:                 // 3，图形的右上角
        fileHead.anchorX = fileHead.maxX;
        fileHead.anchorY = fileHead.maxY;		// 定位点
        break;
    case 4:                 // 4，图形的左上角
        fileHead.anchorX = fileHead.minX;
        fileHead.anchorY = fileHead.maxY;		// 定位点
        break;
    default:

        fileHead.anchorX = fileHead.beginX;
        fileHead.anchorY = fileHead.beginY;		// 定位点

        fileHead.anchorX2 = fileHead.beginX2 ;
        fileHead.anchorY2 = fileHead.beginY2 ;	// 定位点

        break;
    }
#endif



#if (0)
    printf("finial write:\r\n");
    for (i = 0; i < stepNumber; i++)
    {
        printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
    }
#endif
    // 拷贝数据
    ds16Ary.resize(sizeof(DataFileHead)+totalNumber*sizeof(DataItem));
    memcpy (ds16Ary.data(), &fileHead, sizeof(DataFileHead));
    memcpy (&m_fileHead, &fileHead, sizeof(DataFileHead));
    memcpy (ds16Ary.data() + sizeof(DataFileHead), dataItemArray, totalNumber*sizeof(DataItem));

    delete []dataItemArray;


    return 0;




}

#endif


int GetDataMinMax(DataItem * pData, int nums, s32 & minx, s32 & miny, s32 & maxx, s32 & maxy)
{
    s32 actx, acty;

    minx = miny = INT_MAX;
    maxx = maxy = INT_MIN;
    actx = acty = 0;

    if (pData == NULL)
    {
        return -1;
    }

    int i;
    for (i = 0; i < nums; i++)
    {
        if (    pData->ctrl == DATA_END	||	// 结束码
                pData->ctrl == DATA_NULL || 	// 文件结束
                0	)
        {
            break;
        }

        if (    pData->ctrl == DATA_PAUSE 	||	// 暂停功能码
                pData->ctrl == DATA_CHGND 	||	// 换针功能码（换色）
                pData->ctrl == DATA_CUTTRD	||	// 剪线功能码
                pData->ctrl == DATA_ANGLE	||	// 拐点功能码
                0   )
        {
            pData++;
            continue;
        }

        actx += pData->dx;
        acty += pData->dy;

        if (actx < minx)
        {
            minx = actx;
        }
        if (actx > maxx)
        {
            maxx = actx;
        }

        if (acty < miny)
        {
            miny = acty;
        }
        if (acty > maxy)
        {
            maxy = acty;
        }
        pData++;
    }
    return 0;
}

int VectorSqrt::CreateDs8FromDs16(const QByteArray & ds16Ary, QByteArray & ds8Ary)
{
    int rslt = 0;
    int ds16size = ds16Ary.size();
    ds8Ary.clear();

    if (ds16size <= (int)sizeof(DataFileHead) ||
            ((ds16size - sizeof(DataFileHead))%sizeof(DataItem) != 0) )
    {
        rslt = -1;
        return rslt;
    }

    const char * ds16buff = ds16Ary.data();
    DataFileHead * pDs16FileHead = (DataFileHead *)ds16buff;
    DataItem * ds16Array = (DataItem *)(ds16buff+sizeof(DataFileHead));
    int itemnum = (ds16size - sizeof(DataFileHead)) / sizeof(DataItem);

    int ds8size = sizeof(DataFileHead) + itemnum * sizeof(Ds8Item);

    char * ds8buff = new char[ds8size];
    DataFileHead * pDs8FileHead = (DataFileHead *)ds8buff;
    Ds8Item * ds8Array = (Ds8Item *)(ds8buff+sizeof(DataFileHead));

    DataItem * pDs16Ptr = ds16Array;
    Ds8Item * pDs8Ptr = ds8Array;
    int i;
    for (i = 0; i < itemnum; i++)
    {
        pDs8Ptr->ctrl   =   pDs16Ptr->ctrl;
        pDs8Ptr->attr   =   pDs16Ptr->attr;
        pDs8Ptr->dx     =   pDs16Ptr->dx;
        pDs8Ptr->dy     =   pDs16Ptr->dy;
        pDs8Ptr->dr     =   pDs16Ptr->dr;
        pDs8Ptr++;
        pDs16Ptr++;
    }

    memcpy(pDs8FileHead, pDs16FileHead, sizeof(DataFileHead));

    pDs8FileHead->dataSize = itemnum*sizeof(Ds8Item);       // 文件长度
    pDs8FileHead->itemNums = itemnum;                       // 有效针数
    pDs8FileHead->bytesPerItem = sizeof(Ds8Item);			// 每针占的字节数
    pDs8FileHead->bytesPerBlk = 1024;						// 文件内容划分块大小

    pDs8FileHead->dataChecksum = CalcCheckSum32((u8*)(ds8Array), itemnum*sizeof(Ds8Item));   // 花样数据累加校验和
    pDs8FileHead->checkCrc = CalcCrc16((u8*)(pDs8FileHead), 6*sizeof(u32));                  // 前6个字段CRC校验

    // 其余字段不变......

    // 拷贝数据
    ds8Ary.resize(ds8size);
    memcpy(ds8Ary.data(), ds8buff, ds8size);
    delete []ds8buff;

    return rslt;
}

int VectorSqrt::CreateDs4FromSqrt(QByteArray & ds4Ary)
{
    int rslt = 0;
    ds4Ary.clear();

    return rslt;
}

int VectorSqrt::CreateDs2FromDs4(const QByteArray & ds4Ary, QByteArray & ds2Ary)
{
    int rslt = 0;

    int ds4size = ds4Ary.size();
    ds2Ary.clear();

    if (ds4size <= (int)sizeof(DataFileHead) ||
            ((ds4size - sizeof(DataFileHead))%sizeof(Ds4Item) != 0) )
    {
        rslt = -1;
        return rslt;
    }

    const char * ds4buff = ds4Ary.data();
    DataFileHead * pDs4FileHead = (DataFileHead *)ds4buff;
    Ds4Item * ds4Array = (Ds4Item *)(ds4buff+sizeof(DataFileHead));
    int itemnum = (ds4size - sizeof(DataFileHead)) / sizeof(Ds4Item);

    int ds2size = sizeof(DataFileHead) + itemnum * sizeof(Ds2Item);

    char * ds2buff = new char[ds2size];
    DataFileHead * pDs2FileHead = (DataFileHead *)ds2buff;
    Ds2Item * ds2Array = (Ds2Item *)(ds2buff+sizeof(DataFileHead));

    Ds4Item * pDs4Ptr = ds4Array;
    Ds2Item * pDs2Ptr = ds2Array;
    int i;
    u8 cdx, cdy;
    u8 yux, yuy;
    yux = yuy = 0;
    for (i = 0; i < itemnum; i++)
    {
        if (    pDs4Ptr->ctrl == DATA_SEWING ||
                pDs4Ptr->ctrl == DATA_OFFSET ||
                0   )
        {
            cdx = pDs4Ptr->dx;
            cdx += yux;
            yux = cdx & 0x01;
            cdy = pDs4Ptr->dy;
            cdy += yuy;
            yuy = cdy & 0x01;
            if (pDs4Ptr->ctrl == DATA_SEWING)
            {
                cdx &= 0xFE;
                cdy &= 0xFE;            // 0      0      缝纫数据，数据范围从-128 -- +126, 只有偶数可用（精度0.2mm），单位0.1mm
            }
            else if (pDs4Ptr->ctrl == DATA_OFFSET)
            {
                cdx &= 0xFE;
                cdy |= 0x01;            // 0      1      空走数据，数据范围从-128 -- +126, 只有偶数可用（精度0.2mm），单位0.1mm
            }
        }
        else
        {
            cdx = pDs4Ptr->ctrl;
            cdx <<= 1;
            cdx |= 0x01;
            cdy = 0x01;                 // 1      1      控制数据，数据位定义为控制码和参数 cdx.7--cdx.1 控制码 cdy.7--cyd.1 为参数
        }

        pDs2Ptr->cdx = cdx;
        pDs2Ptr->cdy = cdy;

        pDs2Ptr++;
        pDs4Ptr++;
    }

    memcpy(pDs2FileHead, pDs4FileHead, sizeof(DataFileHead));

    pDs2FileHead->dataSize = itemnum*sizeof(Ds2Item);       // 文件长度
    pDs2FileHead->itemNums = itemnum;                       // 有效针数
    pDs2FileHead->bytesPerItem = sizeof(Ds2Item);			// 每针占的字节数
    pDs2FileHead->bytesPerBlk = 1024;						// 文件内容划分块大小

    pDs2FileHead->dataChecksum = CalcCheckSum32((u8*)(ds2Array), itemnum*sizeof(Ds2Item));   // 花样数据累加校验和
    pDs2FileHead->checkCrc = CalcCrc16((u8*)(pDs2FileHead), 6*sizeof(u32));                  // 前6个字段CRC校验

    // 其余字段不变......

    // 拷贝数据
    ds2Ary.resize(ds2size);
    memcpy(ds2Ary.data(), ds2buff, ds2size);

    delete []ds2buff;

    return rslt;
}


//---------------------------------------------------------------------------------------------------------
// 生成数据文件的算法

#if (1)

// 分割直线
int CalcLine(double x0, double y0, double x1, double y1, int * pactx, int * pacty, int stepSize, DataItem * pData, u8 type, s16 dr)
{
    double length, tmp, len;
    double stepx, stepy;
    double sx, sy;
    double xlk;
    int i, count;
    int actx, acty;
    s32 sdx, sdy;
    u8 attr;

    attr = 0;

    if(x0 == x1 && y0 == y1)
    {
        return 0;
    }

    if(x0 > x1)
    {
        sx = -1.0;				// x反向
    }
    else
    {
        sx = 1.0;
    }

    if(y0 > y1)
    {
        sy = -1.0;				// y反向
    }
    else
    {
        sy = 1.0;
    }

    // 开始分割针步
    length = sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
    tmp = length/stepSize;		// 实际针步数
    count = (int)(tmp);			// 最少整针步数

    if (tmp - count >= 0.5)
    {
        count += 1;
        //		printf("count++=%d\r\n", count);
    }

    if (count == 0 && length > 0)	// 短直线
    {
        count = 1;
    }

    if (pData == NULL)
    {
        return count;
    }

    actx = *pactx;
    acty = *pacty;

    if (x1 != x0 && y1 == y0)				// 横直线
    {
        //		printf("H Line: \r\n");
        sdy = 0;
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count)*sx + x0;	// 实际坐标

            stepx = (tmp - actx);
            sdx = (s32)(stepx+0.5*sx);

            pData[i].ctrl = type;
            pData[i].attr = attr;
            pData[i].dx = sdx;
            pData[i].dy = sdy;
            pData[i].dr = 0;

            len = sqrt(1.0*sdx*sdx + 1.0*sdy*sdy);
            pData[i].len = (u16)(len+0.9);

            actx += sdx;
            //			acty += sdy;
        }
    }
    else if (x1 == x0 && y1 != y0)			// 竖直线
    {
        //		printf("v Line: \r\n");

        sdx = 0;
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count)*sy + y0;	// 实际针步

            stepy = (tmp - acty);
            sdy = (s32)(stepy+0.5*sy);

            pData[i].ctrl = type;
            pData[i].attr = attr;
            pData[i].dx = sdx;
            pData[i].dy = sdy;
            pData[i].dr = 0;

            len = sqrt(1.0*sdx*sdx + 1.0*sdy*sdy);
            pData[i].len = (u16)(len+0.9);
            //			actx += sdx;
            acty += sdy;
        }
    }
    else if(x1 != x0 && y1 != y0)			 // 任意斜线
    {
        //		printf("any Line: k=%f\r\n", xlk);

        // 斜率
        xlk = (y1-y0)/(x1-x0);
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count);	// 实际针步

            stepx = fabs(tmp*cos(atan(xlk)))*sx + x0 - actx;
            stepy = fabs(tmp*sin(atan(xlk)))*sy + y0 - acty;

            sdx = (s32)(stepx+0.5*sx);
            sdy = (s32)(stepy+0.5*sy);

            pData[i].ctrl = type;
            pData[i].attr = attr;
            pData[i].dx = sdx;
            pData[i].dy = sdy;
            pData[i].dr = 0;

            len = sqrt(1.0*sdx*sdx + 1.0*sdy*sdy);
            pData[i].len = (u16)(len+0.9);

            actx += sdx;
            acty += sdy;
        }
    }
    pData[0].dr = dr;		// 第一段数据添加r变化量

    *pactx = actx;
    *pacty = acty;

    return count;
}

//---------------------------------------------------------------------------------------------------------
// 圆弧

// 旋转坐标值
void Rotatec(double xin, double yin, double * px, double * py, double angle)
{
    *px=xin*cos(angle)-yin*sin(angle);
    *py=xin*sin(angle)+yin*cos(angle);
}

// 根据坐标确定增加方向
int ArcDir(const double x[], const double y[])
{
    double k;
    if(x[1] > x[0])
    {
        k = (y[1] - y[0]) / (x[1]-x[0]);
        if (y[2] < (k*(x[2]-x[1]) + y[1]))
        {
            return -1;
        }
        else
        {
            return 1;
        }
    }
    else if (x[1] < x[0])
    {
        k = (y[1] - y[0]) / (x[1] - x[0]);
        if (y[2] < (k * (x[2]-x[1]) + y[1]))
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }
    else if ( (x[2]>x[1] && y[1]<y[0]) || (x[2]<x[1] && y[0]<y[1]) )
    {
        return 1;
    }
    else if ( (x[2]>x[1] && y[1]>y[0]) || (x[2]<x[1] && y[0]>y[1]) )
    {
        return -1;
    }
    else
    {
        printf("1. what's this case?\r\n");
        return 0;
    }
}

// 三点共线
int	IsThreePointOnALine(const double threex[], const double threey[])
{
    double	k0,k1,k2;

    if ((fabs(threex[0]-threex[1]) < 1e-6) &&
            (fabs(threex[0]-threex[2]) < 1e-6) &&
            (fabs(threex[2]-threex[1]) < 1e-6) &&
            (fabs(threey[0]-threey[1]) < 1e-6) &&
            (fabs(threey[0]-threey[2]) < 1e-6) &&
            (fabs(threey[2]-threey[1]) < 1e-6) &&
            1	)
    {
        //		printf("1.IsThreePointOnALine\r\n");
        return 1;
    }
    else if (	((fabs(threex[0]-threex[1]) < 1e-6) && (fabs(threey[0]-threey[1]) < 1e-6)) ||
                ((fabs(threex[0]-threex[2]) < 1e-6) && (fabs(threey[0]-threey[2]) < 1e-6)) ||
                ((fabs(threex[2]-threex[1]) < 1e-6) && (fabs(threey[2]-threey[1]) < 1e-6)) ||
                0	)
    {
        //		printf("2.IsThreePointOnALine\r\n");
        return 1;
    }
    else if (	(fabs(threex[0]-threex[1]) < 1e-6) &&
                (fabs(threex[0]-threex[2]) < 1e-6) &&
                (fabs(threex[2]-threex[1]) < 1e-6) &&
                1	)
    {
        //		printf("3.IsThreePointOnALine\r\n");
        return 1;
    }
    else if (	(fabs(threey[0]-threey[1]) < 1e-6) &&
                (fabs(threey[0]-threey[2]) < 1e-6) &&
                (fabs(threey[2]-threey[1]) < 1e-6) &&
                1	)
    {
        //		printf("4.IsThreePointOnALine\r\n");
        return 1;
    }
    else if (	(fabs(threex[2]-threex[1]) >= 1e-6) &&
                (fabs(threex[2]-threex[0]) >= 1e-6) &&
                (fabs(threex[1]-threex[0]) >= 1e-6) &&
                (fabs(threey[2]-threey[1]) >= 1e-6) &&
                (fabs(threey[2]-threey[0]) >= 1e-6) &&
                (fabs(threey[1]-threey[0]) >= 1e-6) &&
                1	)
    {
        k0 = (threey[2]-threey[1])/(threex[2]-threex[1]);
        k1 = (threey[2]-threey[0])/(threex[2]-threex[0]);
        k2 = (threey[1]-threey[0])/(threex[1]-threex[0]);

        if(fabs(k0-k1) < 1e-6 && fabs(k1-k2) < 1e-6)
        {
            //			printf("5.IsThreePointOnALine\r\n");
            return 1;
        }
        else
        {
            //			printf("6.IsThreePointOnALine\r\n");
            return 0;
        }
    }
    else
    {
        //		printf("7.IsThreePointOnALine\r\n");
        return 0;
    }
}

// 得到圆心和半径
int GetArcCenter(const double x[], const double y[], double * pxc, double * pyc, double * pr)
{
    long double a, b, c, d, e, f;
    double xc, yc, r;

    if (IsThreePointOnALine(x, y) == 1)
    {
        return -1;
    }

    a = 2 * (x[1]-x[0]);
    b = 2 * (y[1]-y[0]);
    c = x[1]*x[1] + y[1]*y[1] - x[0]*x[0] - y[0]*y[0];
    d = 2 * (x[2]-x[1]);
    e = 2 * (y[2]-y[1]);
    f = x[2]*x[2] + y[2]*y[2] - x[1]*x[1] - y[1]*y[1];

    xc = (b*f-e*c)/(b*d-e*a);
    yc = (d*c-a*f)/(b*d-e*a);
    r = sqrt((xc-x[0])*(xc-x[0])+(yc-y[0])*(yc-y[0]));

    *pxc = xc;
    *pyc = yc;
    *pr = r;

    return 0;
}

int GetArcRectAndAngle(const double x[], const double y[], double * minx, double * maxx, double * miny, double * maxy, double * startangle, double * aangle)
{
    int rslt;
    double cx, cy, r;
    double cosf, angle;
    rslt = GetArcCenter(x, y, &cx, &cy, &r);
    if (rslt == 0)
    {
        *minx = cx - r;
        *maxx = cx + r;
        *miny = cy - r;
        *maxy = cy + r;

        // 起始点向量和x正向的夹角
        cosf = (x[0]-cx)/r;
        if (cosf < -1)
        {
            cosf = -1;
        }
        else if (cosf > 1)
        {
            cosf = 1;
        }
        angle = acos(cosf);
        if (y[0] < cy)
        {
            angle = 2*PI - angle;
        }
        *startangle = angle;

        // 计算弦长和圆心角
        double distance2 = ((x[0]-x[2])*(x[0]-x[2])+(y[0]-y[2])*(y[0]-y[2]));	// 两点间距离就是弦长
        cosf = ((r*r+r*r)-distance2)/(2*r*r);	// cosc = (a*a + b*b - c*c)/2*a*b
        if (cosf < -1)
        {
            cosf = -1;
        }
        else if (cosf > 1)
        {
            cosf = 1;
        }

        // 圆心角
        angle = acos(cosf);

        // 区分象限和旋转方向
        double k = (x[0]-x[1])*(x[2]-x[1]) + (y[0]-y[1])*(y[2]-y[1]);	// 向量 01 和 向量 21 的夹角的余弦的符号-- > 0 小于90度. < 0 大于90度 = 0, 90 度
        if (k > 0)	// 夹角小于90度, 说明弧是大于半圆
        {
            angle = 2*PI-angle;
        }
        else	// 夹角大于等于90度, 说明弧是小于等于半圆, 不需要处理
        {
        }
        angle *= ArcDir(x, y);

        *aangle = angle;
    }
    return rslt;
}

int GetArcMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy)
{
    double k, xc, yc, r;
    int beg = 0;
    int mid = 0;
    int end = 0;
    double minx, miny, maxx, maxy;

    GetArcCenter(x, y, &xc, &yc, &r);
    //	printf("cx=%f, cy=%f, r=%f\n", xc, yc, r);
    // 区分象限和方向
    k = (x[0]-x[1])*(x[2]-x[1]) + (y[0]-y[1])*(y[2]-y[1]);		// 向量 01 和 向量 21 的夹角的余弦的符号--
    //	> 0 小于90度
    //	< 0 大于90度
    //	= 0 90 度

#ifdef PRTS
    printf("k = %f\n", k);

    if (k > 0)			// 向量夹角小于90度, 说明弧是大于半圆
    {
        printf("angle less then 90d, this arc is more then half cicle\n");
    }
    else if (k < 0)		// 向量夹角大于90度, 说明弧是小于半圆
    {
        printf("angle more then 90d, this arc is less then half cicle\n");
    }
    else				// 向量夹角等于90度, 说明弧是半圆
    {
        printf("angle equal 90d, this arc is equal to half cicle\n");
    }

#endif

#ifdef PRTS
    printf("x[0]=%f,x[1]=%f,x[2]=%f,xc=%f\n", x[0], x[1], x[2], xc);
    printf("y[0]=%f,y[1]=%f,y[2]=%f,yc=%f\n", y[0], y[1], y[2], yc);
#endif

    if (x[0] > xc && y[0] > yc)		// 起点在第一象限
    {
#ifdef PRTS
        printf("first point in quadrant 1\n");
#endif
        beg = 1;
    }
    else if (x[0] < xc && y[0] > yc)	// 起点在第二象限
    {
#ifdef PRTS
        printf("first point in quadrant 2\n");
#endif
        beg = 2;
    }
    else if (x[0] < xc && y[0] < yc)	// 起点在第三象限
    {
#ifdef PRTS
        printf("first point in quadrant 3\n");
#endif
        beg = 3;
    }
    else if (x[0] > xc && y[0] < yc)	// 起点在第四象限
    {
#ifdef PRTS
        printf("first point in quadrant 4\n");
#endif
        beg = 4;
    }
    else if (fabs(y[0]-yc) < 1e-6)		// 起点在x轴上
    {
#ifdef PRTS
        printf("first point on x axes\n");
#endif
        if (x[0] > xc)
        {
            beg = 5;		// x正半轴
        }
        else
        {
            beg = 6;		// x负半轴
        }
    }
    else if (fabs(x[0]-xc) < 1e-6)		// 起点在y轴上
    {
#ifdef PRTS
        printf("first point on y axes\n");
#endif
        if (y[0] > yc)
        {
            beg = 7;	// y正半轴
        }
        else
        {
            beg = 8;	// y正半轴
        }
    }
    else
    {
        printf("this is an new selection for first point\n");
    }

    if (x[1] > xc && y[1] > yc)		// 中点在第一象限
    {
#ifdef PRTS
        printf("second point in quadrant 1\n");
#endif
        mid = 1;
    }
    else if (x[1] < xc && y[1] > yc)	// 中点在第二象限
    {
#ifdef PRTS
        printf("second point in quadrant 2\n");
#endif
        mid = 2;
    }
    else if (x[1] < xc && y[1] < yc)	// 中点在第三象限
    {
#ifdef PRTS
        printf("second point in quadrant 3\n");
#endif
        mid = 3;
    }
    else if (x[1] > xc && y[1] < yc)	// 中点在第四象限
    {
#ifdef PRTS
        printf("second point in quadrant 4\n");
#endif
        mid = 4;
    }
    else if (fabs(y[1]-yc)<1e-6)		// 中点在x轴上
    {
#ifdef PRTS
        printf("second point on x axes\n");
#endif
        if (x[1] > xc)	{mid = 5;}		// x正半轴
        else{	mid = 6;	}			// x负半轴
    }
    else if (fabs(x[1]-xc)<1e-6)		// 中点在y轴上
    {
#ifdef PRTS
        printf("second point on x axes\n");
#endif
        if (y[1] > yc)		// y正半轴
        {
            mid = 7;
        }
        else	{	mid = 8;	}		// y负半轴
    }
    else
    {
#ifdef PRTS
        printf("this is an new selection for second point\n");
#endif
    }

    if (x[2] > xc && y[2] > yc)		// 终点在第一象限
    {
#ifdef PRTS
        printf("third point in quadrant 1\n");
#endif
        end = 1;
    }
    else if (x[2] < xc && y[2] > yc)	// 终点在第二象限
    {
#ifdef PRTS
        printf("third point in quadrant 2\n");
#endif
        end = 2;
    }
    else if (x[2] < xc && y[2] < yc)	// 终点在第三象限
    {
#ifdef PRTS
        printf("third point in quadrant 3\n");
#endif
        end = 3;
    }
    else if (x[2] > xc && y[2] < yc)	// 终点在第四象限
    {
#ifdef PRTS
        printf("third point in quadrant 4\n");
#endif
        end = 4;
    }
    else if (fabs(y[2]-yc)<1e-6)		// 终点在x轴上
    {
#ifdef PRTS
        printf("third point on x axes\n");
#endif
        if (x[2] > xc)	{end = 5;}		// x正半轴
        else{end = 6;}					// x负半轴
    }
    else if (fabs(x[2]-xc)<1e-6)		// 终点在y轴上
    {
#ifdef PRTS
        printf("third point on x axes\n");
#endif
        if (y[2] > yc){	end = 7;}		// y正半轴
        else{end = 8;}					// y负半轴
    }
    else
    {
#ifdef PRTS
        printf("this is an new selection for third point\n");
#endif
    }

#if 0
    printf("\tx0=%.2f,y0=%.2f\n", x[0], y[0]);
    printf("\tx1=%.2f,y1=%.2f\n", x[1], y[1]);
    printf("\tx2=%.2f,y2=%.2f\n", x[2], y[2]);
    printf("\n\txc=%.2f,yc=%.2f, r=%.2f\n", xc, yc, r);
#endif

    minx = S32_MAX;
    maxx = S32_MAX*-1;
    miny = S32_MAX;
    maxy = S32_MAX*-1;

    switch (beg)
    {
    case 1:	// 起点在第一象限内
    {
        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 5:	// 终点在x正半轴上
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("1 Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 6:	// 终点在x负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else 		// 半弧
            {
                printf("2 Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
            if (mid == 2 || mid == 6 || mid == 7 ||
                    (mid == 1 && x[1] < x[0]) || (mid == 3 && x[1] < x[2]))		// 逆时针方向
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (mid == 4 || mid == 5 || mid == 8 ||
                     (mid == 1 && x[1] > x[0]) || (mid == 3 && x[1] > x[2]))	// 顺时针方向
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else
            {
                printf("3. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("4. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }

        break;
    }
    case 2:	// 起点在第二象限内
    {
        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 5:	// 终点在x正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else 		// 半弧
            {
                printf("5. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 6:	// 终点在x负半轴上
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("6. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("7. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
            if (mid == 3 || mid == 6 || mid == 8 ||
                    (mid == 2 && x[1] < x[0]) || (mid == 4 && x[1] < x[2]))		// 逆时针方向
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (mid == 1 || mid == 5 || mid == 7 ||
                     (mid == 2 && x[1] > x[0]) || (mid == 4 && x[1] > x[2]))	// 顺时针方向
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else
            {
                printf("8. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }
        break;
    }
    case 3:	// 起点在第三象限内
    {
        switch (end)
        {
        case 1:	// 终点在第一象限内
            if (mid == 4 || mid == 5 || mid == 8 ||
                    (mid == 1 && x[1] > x[0]) || (mid == 3 && x[1] > x[2]))		// 逆时针方向
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (mid == 2 || mid == 6 || mid == 7 ||
                     (mid == 1 && x[1] < x[0]) || (mid == 3 && x[1] < x[2]))	// 顺时针方向
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else
            {
                printf("9. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)		// 小半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("10. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	 // 不可能出现的情况
            }
            break;
        case 3:	// 终点在第三象限内
        case 6:	// 终点在x负半轴上
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("11. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	 // 不可能出现的情况
            }
            break;
        case 4:	// 终点在第四象限内
        case 5:	// 终点在x正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("12. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }
        break;
    }
    case 4:	// 起点在第四象限内
    {
        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("13. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
            if (mid == 1 || mid == 5 || mid == 7 ||
                    (mid == 2 && x[1] > x[0]) || (mid == 4 && x[1] > x[2]))		// 逆时针方向
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (mid == 3 || mid == 6 || mid == 8 ||
                     (mid == 2 && x[1] < x[0]) || (mid == 4 && x[1] < x[2]))	// 顺时针方向
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else
            {
                printf("14. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
        case 6:	// 终点在x负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("15. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
        case 5:	// 终点在x正半轴上
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("16. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }
        break;
    }
    case 5:	// 起点在在x正半轴上
    {
        maxx = xc + r;

        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 4:	// 终点在第四象限内
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("17. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else 		// 半弧
            {
                printf("18. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("19. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 5:	// 终点在x正半轴上
            printf("20. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            break;

        case 6:	// 终点在x负半轴上
            minx = xc - r;
            if (y[1] > yc)	// 逆时针
            {
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (y[1] < yc)	// 顺时针
            {
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else
            {
                printf("21. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }
        break;
    }
    case 6:	// 起点在x负半轴上
    {
        minx = xc - r;

        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (k < 0)	// 小半弧
            {
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else 		// 半弧
            {
                printf("22. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 3:	// 终点在第三象限内
            if (k > 0)			// 大半弧
            {
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("23. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("24. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 5:	// 终点在x正半轴上
            maxx = xc + r;
            if (y[1] > yc)	// 顺时针
            {
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (y[1] < yc)	// 逆时针
            {
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else
            {
                printf("25. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 6:	// 终点在x负半轴上
            printf("26. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            break;

        default:
            break;
        }
        break;
    }

    case 7:	// 起点在y正半轴上
    {
        maxy = yc + r;

        switch (end)
        {

        case 1:	// 终点在第一象限内
        case 2:	// 终点在第二象限内
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("27. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
        case 6:	// 终点在x负半轴上
            if (k > 0)			// 大半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("28. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
        case 5:	// 终点在x正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
            }

            else 		// 半弧
            {
                printf("29. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 7:	// 终点在y正半轴上
            printf("30. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            break;

        case 8:	// 终点在y负半轴上
            miny = yc - r;
            if (x[1] > xc)	// 顺时针
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
            }
            else if (x[1] < xc)	// 逆时针
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
            }
            else
            {
                printf("31. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        default:
            break;
        }
        break;
    }
    case 8:	// 起点在y负半轴上
    {
        miny = yc - r;
        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 5:	// 终点在x正半轴上
        {
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("32. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        }
        case 2:	// 终点在第二象限内
        case 6:	// 终点在x负半轴上
        {
            if (k > 0)			// 大半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("33. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        }
        case 3:	// 终点在第三象限内
        case 4:	// 终点在第四象限内
        {
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("34. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        }
        case 7:	// 终点在y正半轴上
        {
            maxy = yc + r;

            if (x[1] > xc)		// 逆时针
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
            }
            else if (x[1] < xc)	// 顺时针
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
            }
            else
            {
                printf("35. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        }
        case 8:	// 终点在y负半轴上
        {
            printf("36. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            break;
        }
        default:
            break;
        }
        break;
    }

    default:
        break;
    }

    if (minx < *pminx)
    {
        *pminx = minx;
    }

    if (miny < *pminy)
    {
        *pminy = miny;
    }

    if (maxx > *pmaxx)
    {
        *pmaxx = maxx;
    }

    if (maxy > *pmaxy)
    {
        *pmaxy = maxy;
    }

    //	printf("minx=%.2f, maxx=%.2f, miny=%.2f, maxy=%.2f\n", minx, maxx, miny, maxy);

    return 0;
}

// 得到直线角度和角度差
s16 GetAngle(const double bx, const double by, const double ex, const double ey, int * pActAng)
{
    double cosf, angle, length;
    s32 dr;

    length = sqrt((ex-bx)*(ex-bx) + (ey-by)*(ey-by));
    if (length != 0)
    {
        // 计算直线角度（和x正方向的夹角。弧度表示，范围为 0--2PI）
        cosf = (ex-bx)/length;
        angle = acos(cosf);
        if (ey < by)
        {
            angle = 2*PI - angle;
        }

        // 角度差
        if ((angle*RADIAN_ACCURACY - *pActAng) > PI*RADIAN_ACCURACY)	// 角度差大于180度，
        {
            dr = (s32)(angle*RADIAN_ACCURACY - *pActAng - 2*PI* RADIAN_ACCURACY);		// 反向到达目标角度
            *pActAng += (int)(2*PI*RADIAN_ACCURACY)+dr;									// 实际位置
        }
        else if ((angle*RADIAN_ACCURACY - *pActAng) < (-1)*PI*RADIAN_ACCURACY)	// 角度差大于180度
        {
            dr = (s32)(angle*RADIAN_ACCURACY - *pActAng + 2*PI* RADIAN_ACCURACY);
            *pActAng += (int)(-2*PI*RADIAN_ACCURACY)+dr;								// 实际位置
        }
        else
        {
            dr = (s32)(angle*RADIAN_ACCURACY - *pActAng);		// 正向
            *pActAng += dr;
        }

        while (*pActAng > 2*PI*RADIAN_ACCURACY)
        {
            *pActAng -= 2*PI*RADIAN_ACCURACY;
        }
        while (*pActAng < 0)
        {
            *pActAng += 2*PI*RADIAN_ACCURACY;
        }

        return dr;
    }
    return 0;
}

// 分割圆弧线
int CalcCurve(double threex[], double threey[], int * pactx, int * pacty, int * pActAng, int stepSize, DataItem * pData, u8 type)
{
    u8 attr;
    s16 dx, dy, dr;

    double k, alph, increment;
    double xc, yc, r;
    double distance2;
    double curx, cury, lastx, lasty;
    double xrot, yrot;
    double len;
    int actx, acty;
    int ddx, ddy;
    int count = 0;
    int i;

    //	printf("Calc Curve x0=%.2f,y0=%.2f,x1=%.2f,\r\n\t y1=%.2f,x2=%.2f,y2=%.2f\r\n", threex[0],threey[0],threex[1],threey[1],threex[2],threey[2]);

    if(IsThreePointOnALine(threex, threey) == 1)	// 3点共线
    {
        // 直线和X坐标轴正方向的夹角, 公式: cosφ=∣A1A2+B1B2∣/[√(A1^2+B1^2)√(A2^2+B2^2)]
        if (pData != NULL)
        {
            dr = GetAngle(threex[0], threey[0], threex[2], threey[2], pActAng);
        }
        return CalcLine(threex[0], threey[0], threex[2], threey[2], pactx, pacty, stepSize, pData, type, dr);	// 作为直线分割
    }

    // 计算圆心和半径
    GetArcCenter(threex, threey, &xc, &yc, &r);

    //  printf("center=%f,%f,r=%f\r\n", xc, yc, r);

    // 计算弦长和圆心角
    distance2 = ((threex[0]-threex[2])*(threex[0]-threex[2])+(threey[0]-threey[2])*(threey[0]-threey[2]));	// 两点间距离就是弦长
    k = ((r*r+r*r)-distance2)/(2*r*r);	// cosc = (a*a + b*b - c*c)/2*a*b
    if (k < -1)
    {
        k = -1;
    }
    else if (k > 1)
    {
        k = 1;
    }

#if (0)
    distance2 = sqrt(distance2);
    printf("distance=%f, k=%f\r\n", distance2, k);
#endif

    // 圆心角
    alph = acos(k);
#if (0)
    printf("calc alph=%f\r\n", alph);
    printf("long double size=%d\r\n", sizeof(long double));
#endif
    // 区分象限和旋转方向
    k = (threex[0]-threex[1])*(threex[2]-threex[1]) + (threey[0]-threey[1])*(threey[2]-threey[1]);	// 向量 01 和 向量 21 的夹角的余弦的符号-- > 0 小于90度. < 0 大于90度 = 0, 90 度

    if (k > 0)	// 夹角小于90度, 说明弧是大于半圆
    {
        alph = 2*PI-alph;
    }
    else	// 夹角大于等于90度, 说明弧是小于等于半圆, 不需要处理
    {
    }
#if (0)
    printf("act alph=%f, arclen=%d\r\n", alph, alph*r);
#endif

    // 计算每个针步对应的弧心角大小
    if (fabsl(2*r*r-1.0*stepSize*stepSize)/(2*r*r) > 1)
    {
        increment = alph;
    }
    else
    {
        increment = (acos((2*r*r-1.0*stepSize*stepSize)/(r*r+r*r)));
    }

    // 计算分割针步数
    count = (int)(alph/increment+0.5);
    if (count == 0)
    {
        count++;
    }
    //	printf("1.count=%d, increment=%f\r\n", count, increment);

    if (pData == NULL)		// 返回个数
    {
        return count;
    }

    // 重新计算每个针步弧心角
    increment = alph/count;

    // 确定针步增加的角度和方向
    increment *= ArcDir(threex, threey);
    //   printf("2.count=%d, increment=%f\r\n", count, increment);

    // 起点
    lastx = threex[0];
    lasty = threey[0];

    actx = *pactx;
    acty = *pacty;

    i = 0;
    do
    {
        if (i == count-1)
        {
            // 最后一个针步
            //			printf("the last step\r\n");
            curx = threex[2];
            cury = threey[2];
        }
        else
        {
            // 点 (lastx, lasty) 在圆上旋转
            //			printf("before Rotatec point(%f, %f)\r\n", lastx, lasty);
            Rotatec(lastx-xc, lasty-yc, &xrot, &yrot, increment);
            curx = xrot + xc;
            cury = yrot + yc;
        }

        ddx = curx-actx;
        ddy = cury-acty;

        dx = (s16)(curx-actx+(0.5*(ddx>=0?1:-1)));
        dy = (s16)(cury-acty+(0.5*(ddy>=0?1:-1)));
        dr = GetAngle(lastx, lasty, curx, cury, pActAng);		// 计算直线 (lastx, lasty) 到（curx, cury）和上条直线的角度差

        attr = 0;

        pData[i].ctrl = type;
        pData[i].attr = attr;
        pData[i].dx = dx;
        pData[i].dy = dy;
        pData[i].dr = dr;

        len = sqrt(1.0*dx*dx + 1.0*dy*dy);
        pData[i].len = (u16)(len+0.9);

        //		printf("after Rotatec point(%f, %f)\r\n", lastx, lasty);

        lastx = curx;
        lasty = cury;
        actx += dx;
        acty += dy;
        i++;

    } while(i < count);

    *pactx = actx;
    *pacty = acty;

    return count;
}

//---------------------------------------------------------------------------------------------------------
// 三次贝塞尔曲线

/* cp 在此是四个元素的数组:
cp[0] 为起点，或上图中的 P0
cp[1] 为第一控制点，或上图中的 P1
cp[2] 为第二控制点，或上图中的 P2
cp[3] 为结束点，或上图中的 P3
t 为参数值，0 <= t <= 1 */

typedef struct
{
    double x;
    double y;
} Point2D;

Point2D PointOnCubicBezier(Point2D* cp, double t)
{
    double ax, bx, cx;
    double ay, by, cy;
    double tSquared, tCubed;
    Point2D result;

    /* 计算多项式系数 */
    cx = 3.0 * (cp[1].x - cp[0].x);
    bx = 3.0 * (cp[2].x - cp[1].x) - cx;
    ax = cp[3].x - cp[0].x - cx - bx;
    cy = 3.0 * (cp[1].y - cp[0].y);
    by = 3.0 * (cp[2].y - cp[1].y) - cy;
    ay = cp[3].y - cp[0].y - cy - by;

    /* 计算t位置的点值 */
    tSquared = t * t;
    tCubed = tSquared * t;
    result.x =((ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x);
    result.y =((ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y);

    return result;
}

/* 以控制点 cp 所产生的曲线点，填入 Point2D 结构数组。
调用方必须分配足够的空间以供输出，<sizeof(Point2D) * numberOfPoints> */
void ComputeBezier(Point2D* cp, long numberOfPoints, Point2D* curve)
{
    double dt;
    long i;
    dt = 1.0 / (numberOfPoints - 1);
    for(i = 0; i < numberOfPoints; i++)
    {
        curve[i] = PointOnCubicBezier(cp, i*dt);
    }
}

// 求贝塞尔曲线的最大值和最小值, 1个整数单位精度
int GetBezierMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy)
{
    long k = 0;
    long i = 0;
    double sx,sy;
    double minx, miny, maxx, maxy;
    Point2D cp[4];

    // 传递参数
    for (i = 0; i < 4; i++)
    {
        cp[i].x = x[i];
        cp[i].y = y[i];
    }

    // 求控制点总长
    for (i = 0; i < 3; i++)
    {
        sx = cp[i+1].x - cp[i].x;
        sy = cp[i+1].y - cp[i].y;
        k += sqrt(sx*sx+sy*sy);  // 分割点数 = 总长(精度为0.1mm)
    }

    if (k == 0)
    {
        return -1;
    }

    //  printf("calc Bezier point num=%ld\n", k);

    Point2D curve[k];

    ComputeBezier(cp, k, curve);	// 分割针步

    minx = S32_MAX;
    maxx = S32_MAX*-1;
    miny = S32_MAX;
    maxy = S32_MAX*-1;

    // 判断始末点
    if (minx > cp[0].x)   { minx = cp[0].x; }
    if (maxx < cp[0].x)   { maxx = cp[0].x; }
    if (miny > cp[0].y)   { miny = cp[0].y; }
    if (maxy < cp[0].y)   { maxy = cp[0].y; }
    if (minx > cp[3].x)   { minx = cp[3].x; }
    if (maxx < cp[3].x)   { maxx = cp[3].x; }
    if (miny > cp[3].y)   { miny = cp[3].y; }
    if (maxy < cp[3].y)   { maxy = cp[3].y; }

    for (i = 0; i < k; i++)
    {
        if (minx > cp[i].x)   { minx = cp[i].x; }
        if (maxx < cp[i].x)   { maxx = cp[i].x; }
        if (miny > cp[i].y)   { miny = cp[i].y; }
        if (maxy < cp[i].y)   { maxy = cp[i].y; }
    }

    //printf("\n BSR	minx = %f, maxx = %f, miny = %f, maxy = %f \n",minx,maxx,miny,maxy);

    if (minx < *pminx)
    {
        *pminx = minx;
    }

    if (miny < *pminy)
    {
        *pminy = miny;
    }

    if (maxx > *pmaxx)
    {
        *pmaxx = maxx;
    }

    if (maxy > *pmaxy)
    {
        *pmaxy = maxy;
    }

    return 0;
}



#endif
