#include "vectorsqrt.h" #include #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()<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]x[1] && y[1]>y[0]) || (x[2]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 结构数组。 调用方必须分配足够的空间以供输出, */ 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