PlotterHMI/datafile/hpgl/vectorsqrt.cpp
2024-02-06 14:19:53 +08:00

4502 lines
137 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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