2305 lines
58 KiB
C++
2305 lines
58 KiB
C++
#include "dataoperat.h"
|
|
|
|
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 ) //三点几乎重合
|
|
{
|
|
//printf("1.IsThreePointOnALine\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) )
|
|
{
|
|
//三点间,有2点几乎重合
|
|
if (fabs(threex[0]-threex[2]) < 1e-6 && fabs(threey[0]-threey[2]) < 1e-6)
|
|
{
|
|
//如果是两边2个点几乎重合,则将第2个点坐标->第3个点
|
|
return 2;
|
|
}
|
|
else
|
|
{
|
|
//printf("2.IsThreePointOnALine\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 )
|
|
{
|
|
//三个点,X的差距极小
|
|
//printf("3.IsThreePointOnALine\n");
|
|
if (threey[0] < threey[2])
|
|
{
|
|
if (threey[1] > threey[2])
|
|
{
|
|
return 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (threey[1] < threey[2])
|
|
{
|
|
return 2;
|
|
}
|
|
}
|
|
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 )
|
|
{ //三个点,Y的差距极小
|
|
// printf("4.IsThreePointOnALine\n");
|
|
if (threex[0] < threex[2])
|
|
{
|
|
if (threex[1] > threex[2])
|
|
{
|
|
return 2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (threex[1] < threex[2])
|
|
{
|
|
return 2;
|
|
}
|
|
}
|
|
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 )
|
|
{
|
|
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)
|
|
{
|
|
//三个点,2点之间的斜率差极小
|
|
//printf("5.IsThreePointOnALine\n");
|
|
if ( (threex[0] < threex[1] && threex[1] < threex[2] )
|
|
|| (threex[0] > threex[1] && threex[1] > threex[2]))
|
|
{
|
|
}
|
|
else
|
|
{
|
|
return 2;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
//printf("6.IsThreePointOnALine\n");
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//printf("7.IsThreePointOnALine\n");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int getArcCenter(const double x[], const double y[], double * pxc, double * pyc, double * pr)
|
|
{
|
|
#if 0
|
|
double x20, x21, xh0, xh1, y20, y21, yk0, yk1;
|
|
double x2y20, x2y21, xnyn, ykn;
|
|
|
|
double xx0,xx1,xx2;
|
|
double yy0,yy1,yy2;
|
|
xx0=x[0];
|
|
yy0=y[0];
|
|
xx1=x[1];
|
|
yy1=y[1];
|
|
xx2=x[2];
|
|
yy2=y[2];
|
|
|
|
if(fabs(xx0-xx1)<1e-6)
|
|
{
|
|
yc=(yy0+yy1)/2;
|
|
xc=(xx0*xx0-xx2*xx2+yy0*yy0-yy2*yy2+2*yy2*yc-2*yy0*yc)/(2*xx0-2*xx2);
|
|
r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
|
|
}
|
|
else if(fabs(xx0-xx2)<1e-6)
|
|
{
|
|
yc=(yy0+yy2)/2;
|
|
xc=(xx0*xx0-xx1*xx1+yy0*yy0-yy1*yy1+2*yy1*yc-2*yy0*yc)/(2*xx0-2*xx1);
|
|
r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
|
|
}
|
|
else if(fabs(xx1-xx2)<1e-6)
|
|
{
|
|
yc=(yy1+yy2)/2;
|
|
xc=(xx1*xx1-xx0*xx0+yy1*yy1-yy0*yy0+2*yy0*yc-2*yy1*yc)/(2*xx1-2*xx0);
|
|
r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
|
|
}
|
|
else if(fabs(yy0-yy1)<1e-6)
|
|
{
|
|
xc=(xx0+xx1)/2;
|
|
yc=(yy0*yy0-yy2*yy2+xx0*xx0-xx2*xx2+2*xx2*xc-2*xx0*xc)/(2*yy0-2*yy2);
|
|
r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
|
|
}
|
|
else if(fabs(yy0-yy2)<1e-6)
|
|
{
|
|
xc=(xx0+xx2)/2;
|
|
yc=(yy0*yy0-yy1*yy1+xx0*xx0-xx1*xx1+2*xx1*xc-2*xx0*xc)/(2*yy0-2*yy1);
|
|
r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
|
|
}
|
|
else if(fabs(yy1-yy2)<1e-6)
|
|
{
|
|
xc=(xx1+xx2)/2;
|
|
yc=(yy1*yy1-yy0*yy0+xx1*xx1-xx0*xx0+2*xx0*xc-2*xx1*xc)/(2*yy1-2*yy0);
|
|
r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
|
|
}
|
|
else
|
|
{
|
|
x20=xx0*xx0-xx1*xx1;
|
|
xh0=2*xx0-2*xx1;
|
|
y20=yy0*yy0-yy1*yy1;
|
|
yk0=2*yy0-2*yy1;
|
|
|
|
x21=xx1*xx1-xx2*xx2;
|
|
xh1=2*xx1-2*xx2;
|
|
y21=yy1*yy1-yy2*yy2;
|
|
yk1=2*yy1-2*yy2;
|
|
|
|
x2y20=x20+y20;
|
|
x2y21=x21+y21;
|
|
|
|
xnyn=x2y20;
|
|
ykn=yk0;
|
|
|
|
x2y20 *= xh1;
|
|
yk0 *= xh1;
|
|
|
|
x2y21 *= xh0;
|
|
yk1 *= xh0;
|
|
|
|
yc = (x2y20-x2y21)/(yk0-yk1);
|
|
xc = (xnyn-yc*ykn)/xh0;
|
|
|
|
xx0 -= xc;
|
|
yy0 -= yc;
|
|
|
|
r=sqrt(xx0*xx0+yy0*yy0);
|
|
}
|
|
|
|
#else
|
|
|
|
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]));
|
|
#endif
|
|
|
|
*pxc = xc;
|
|
*pyc = yc;
|
|
*pr = r;
|
|
|
|
return 0;
|
|
}
|
|
|
|
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度 向量夹角小于90度, 说明弧是大于半圆
|
|
// < 0 大于90度 向量夹角大于90度, 说明弧是小于半圆
|
|
// = 0 90 度 向量夹角等于90度, 说明弧是半圆
|
|
|
|
if (x[0] > xc && y[0] > yc) // 起点在第一象限
|
|
{
|
|
beg = 1;
|
|
}
|
|
else if (x[0] < xc && y[0] > yc) // 起点在第二象限
|
|
{
|
|
beg = 2;
|
|
}
|
|
else if (x[0] < xc && y[0] < yc) // 起点在第三象限
|
|
{
|
|
beg = 3;
|
|
}
|
|
else if (x[0] > xc && y[0] < yc) // 起点在第四象限
|
|
{
|
|
beg = 4;
|
|
}
|
|
else if (fabs(y[0]-yc) < 1e-6) // 起点在x轴上
|
|
{
|
|
if (x[0] > xc)
|
|
{
|
|
beg = 5; // x正半轴
|
|
}
|
|
else
|
|
{
|
|
beg = 6; // x负半轴
|
|
}
|
|
}
|
|
else if (fabs(x[0]-xc) < 1e-6) // 起点在y轴上
|
|
{
|
|
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) // 中点在第一象限
|
|
{
|
|
mid = 1;
|
|
}
|
|
else if (x[1] < xc && y[1] > yc) // 中点在第二象限
|
|
{
|
|
mid = 2;
|
|
}
|
|
else if (x[1] < xc && y[1] < yc) // 中点在第三象限
|
|
{
|
|
mid = 3;
|
|
}
|
|
else if (x[1] > xc && y[1] < yc) // 中点在第四象限
|
|
{
|
|
mid = 4;
|
|
}
|
|
else if (fabs(y[1]-yc)<1e-6) // 中点在x轴上
|
|
{
|
|
if (x[1] > xc) {mid = 5;} // x正半轴
|
|
else{ mid = 6; } // x负半轴
|
|
}
|
|
else if (fabs(x[1]-xc)<1e-6) // 中点在y轴上
|
|
{
|
|
if (y[1] > yc) // y正半轴
|
|
{
|
|
mid = 7;
|
|
}
|
|
else { mid = 8; } // y负半轴
|
|
}
|
|
else
|
|
{
|
|
printf("this is an new selection for second point\n");
|
|
}
|
|
|
|
if (x[2] > xc && y[2] > yc) // 终点在第一象限
|
|
{
|
|
end = 1;
|
|
}
|
|
else if (x[2] < xc && y[2] > yc) // 终点在第二象限
|
|
{
|
|
end = 2;
|
|
}
|
|
else if (x[2] < xc && y[2] < yc) // 终点在第三象限
|
|
{
|
|
end = 3;
|
|
}
|
|
else if (x[2] > xc && y[2] < yc) // 终点在第四象限
|
|
{
|
|
end = 4;
|
|
}
|
|
else if (fabs(y[2]-yc)<1e-6) // 终点在x轴上
|
|
{
|
|
if (x[2] > xc) {end = 5;} // x正半轴
|
|
else{end = 6;} // x负半轴
|
|
}
|
|
else if (fabs(x[2]-xc)<1e-6) // 终点在y轴上
|
|
{
|
|
if (y[2] > yc){ end = 7;} // y正半轴
|
|
else{end = 8;} // y负半轴
|
|
}
|
|
else
|
|
{
|
|
printf("this is an new selection for third point\n");
|
|
}
|
|
|
|
minx = S32_MAX;
|
|
maxx = S32_MIN;
|
|
miny = S32_MAX;
|
|
maxy = S32_MIN;
|
|
|
|
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;
|
|
}
|
|
|
|
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?\n");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
Point2D pointOnCubicBezier(Point2D* cp, double t)
|
|
{
|
|
#if(1)
|
|
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;
|
|
#endif
|
|
}
|
|
|
|
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 );
|
|
}
|
|
}
|
|
|
|
int getBezierMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy)
|
|
{
|
|
long k = 0;
|
|
double sx,sy;
|
|
long i = 0;
|
|
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;
|
|
}
|
|
|
|
if (k > 100) //对多100个点
|
|
{
|
|
k = 100;
|
|
}
|
|
|
|
Point2D curve[k];
|
|
|
|
computeBezier(cp, k, curve); //分割针步
|
|
|
|
minx = S32_MAX;
|
|
maxx = S32_MIN;
|
|
miny = S32_MAX;
|
|
maxy = S32_MIN;
|
|
|
|
//判断始末点
|
|
for (i = 0; i <4;i =i+3)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
for (i=0;i<k;i++)
|
|
{
|
|
if (minx > curve[i].x)
|
|
{
|
|
minx = curve[i].x;
|
|
}
|
|
if (maxx < curve[i].x)
|
|
{
|
|
maxx = curve[i].x;
|
|
}
|
|
if (miny > curve[i].y)
|
|
{
|
|
miny = curve[i].y;
|
|
}
|
|
if (maxy < curve[i].y)
|
|
{
|
|
maxy = curve[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;
|
|
}
|
|
|
|
int calcLine(double x0, double y0, double x1, double y1, s16 step, QByteArray &absAry, WORD datatype)
|
|
{
|
|
DsAbsItem absItem;
|
|
memset(&absItem,0,sizeof(DsAbsItem));
|
|
|
|
s32 dx, dy;
|
|
double length;
|
|
double tmp;
|
|
int count;
|
|
int i;
|
|
double stepx, stepy;
|
|
double sx, sy;
|
|
int actx, acty;
|
|
double k;
|
|
|
|
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;
|
|
}
|
|
|
|
if(datatype == QUI_TYPE_STEP || datatype == QUI_TYPE_HSTEP) // 跨步或翻头跨步
|
|
{
|
|
absItem.ctrl = DATA_OFFSET;
|
|
}
|
|
else
|
|
{
|
|
absItem.ctrl = DATA_SEWING; // 其他
|
|
}
|
|
|
|
// 开始分割针步
|
|
length = sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
|
|
|
|
tmp = length/step; /* 实际针步数 */
|
|
count = floor(tmp); /* 最少整针步数 */
|
|
|
|
if (tmp - count > 0.01)
|
|
{
|
|
count += 1;
|
|
}
|
|
|
|
if (count == 0 && length > 0) // 短直线
|
|
{
|
|
count = 1;
|
|
}
|
|
|
|
tmp = 0;
|
|
actx = x0;
|
|
acty = y0;
|
|
|
|
if (x1 != x0 && y1 == y0) // 横直线
|
|
{
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
tmp = ((i+1)*(length)/count)*sx+x0; // 实际针步
|
|
|
|
stepx = tmp - actx;
|
|
dx = (s32)(stepx+0.5*sx);
|
|
dy = 0;
|
|
actx += dx;
|
|
|
|
absItem.ax = tmp;
|
|
absItem.ay = y0;
|
|
absAry.append((char*)&absItem,sizeof(DsAbsItem));
|
|
}
|
|
}
|
|
else if (x1 == x0 && y1 != y0) // 竖直线
|
|
{
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
tmp = ((i+1)*(length)/count)*sy + y0; // 实际针步
|
|
|
|
stepy = tmp - acty;
|
|
|
|
dx = 0;
|
|
dy = (s32)(stepy+0.5*sy);
|
|
acty += dy;
|
|
|
|
absItem.ax = x0;
|
|
absItem.ay = tmp;
|
|
absAry.append((char*)&absItem,sizeof(DsAbsItem));
|
|
}
|
|
}
|
|
else if(x1 != x0 && y1 != y0) // 任意斜线
|
|
{
|
|
k = (y1-y0)/(x1-x0);
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
tmp = ((i+1)*(length)/count);
|
|
|
|
stepx = fabs(tmp*cos(atan(k)))*sx + x0; // 实际针步x
|
|
stepy = fabs(tmp*sin(atan(k)))*sy + y0; // 实际针步y
|
|
|
|
dx = (s32)(stepx-actx+0.5*sx);
|
|
dy = (s32)(stepy-acty+0.5*sy);
|
|
|
|
actx += dx;
|
|
acty += dy;
|
|
|
|
absItem.ax = stepx;
|
|
absItem.ay = stepy;
|
|
absAry.append((char*)&absItem,sizeof(DsAbsItem));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("what's this?\n");
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
int calcCurve(double threex[], double threey[], s16 step, QByteArray &absAry)
|
|
{
|
|
DsAbsItem absItem;
|
|
memset(&absItem,0,sizeof(DsAbsItem));
|
|
|
|
BYTE dx, dy;
|
|
int count = 0;
|
|
int i;
|
|
s32 ar = 0;
|
|
|
|
double distance, k;
|
|
double alph;
|
|
double increment;
|
|
double xc=0,yc=0,r=0;
|
|
int actx, acty;
|
|
int ddx, ddy;
|
|
|
|
i = isThreePointOnALine(threex, threey);
|
|
if(i == 1) // 3点共线
|
|
{
|
|
return calcLine(threex[0], threey[0], threex[2], threey[2], step, absAry, QUI_TYPE_LINE); // 作为直线
|
|
}
|
|
else if (i == 2)
|
|
{
|
|
return calcLine(threex[0], threey[0], threex[1], threey[1], step, absAry, QUI_TYPE_LINE); // 作为直线
|
|
}
|
|
|
|
getArcCenter(threex, threey, &xc, &yc, &r);
|
|
|
|
// printf("center=%.2f,%.2f,r=%.2f\n", xc, yc, r);
|
|
|
|
// 计算弦长和圆心角
|
|
distance = sqrt((threex[0]-threex[2])*(threex[0]-threex[2])+(threey[0]-threey[2])*(threey[0]-threey[2])); // 两点间距离就是弦长
|
|
k = (r*r+r*r-distance*distance)/(r*r+r*r);
|
|
if (k < -1)
|
|
{
|
|
k = -1;
|
|
}
|
|
else if (k > 1)
|
|
{
|
|
k = 1;
|
|
}
|
|
|
|
// printf("distance=%f, k=%f\n", distance, k);
|
|
|
|
alph = acos(k);
|
|
|
|
// 区分象限和方向
|
|
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度, 说明弧是小于等于半圆, 不需要处理
|
|
{
|
|
}
|
|
|
|
// printf("act alph=%f\n", alph);
|
|
|
|
// 计算每个针步对应的弧心角大小
|
|
if (fabs(2*r*r-step*step)/(2*r*r) > 1)
|
|
{
|
|
increment = alph;
|
|
}
|
|
else
|
|
{
|
|
increment = (acos((2*r*r-step*step)/(r*r+r*r)));
|
|
}
|
|
|
|
// 计算分割针步数
|
|
count = (int)(alph/increment+0.5);
|
|
if (count == 0)
|
|
{
|
|
count++;
|
|
}
|
|
|
|
// printf("1.count=%d, increment=%f\n", count, increment);
|
|
|
|
increment = alph/count; // 重新计算每个针步弧心角
|
|
|
|
increment *= arcDir(threex, threey); // 确定针步增加的角度和方向
|
|
|
|
// printf("2.count=%d, increment=%f\n", count, increment);
|
|
|
|
double curx, cury, lastx, lasty;
|
|
double xrot, yrot;
|
|
|
|
lastx = threex[0];
|
|
lasty = threey[0];
|
|
|
|
i = 0;
|
|
|
|
actx = (int)(lastx);
|
|
acty = (int)(lasty);
|
|
|
|
do
|
|
{
|
|
if (i == count-1)
|
|
{
|
|
// 最后一个针步
|
|
// printf("the last step\n");
|
|
curx = threex[2];
|
|
cury = threey[2];
|
|
}
|
|
else
|
|
{
|
|
// 点 (lastx, lasty) 在圆上旋转
|
|
// printf("before Rotatec point(%f, %f)\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)));
|
|
|
|
absItem.ctrl = DATA_SEWING;
|
|
absItem.ax = curx;
|
|
absItem.ay = cury;
|
|
|
|
double tar = atan2(dy,dx);
|
|
ar = (tar * 10000+0.5*(tar>0?1:-1));
|
|
absItem.ar = ar;
|
|
absAry.append((char*)&absItem,sizeof(DsAbsItem));
|
|
|
|
lastx = curx;
|
|
lasty = cury;
|
|
|
|
actx += dx;
|
|
acty += dy;
|
|
i++;
|
|
|
|
} while(i < count);
|
|
|
|
return count;
|
|
}
|
|
|
|
#define YUFENGE 20 //预分割步数
|
|
#define YUFENGE_BEGIN (YUFENGE*7/10) //扫描起点
|
|
|
|
int calcBezier(double threex[], double threey[], s16 step, QByteArray &absAry)
|
|
{
|
|
DsAbsItem absItem;
|
|
memset(&absItem,0,sizeof(DsAbsItem));
|
|
|
|
int dx, dy;
|
|
long k = 0;
|
|
double sx,sy;
|
|
long i , l;
|
|
Point2D cp[4];
|
|
int count = 0;
|
|
double curx, cury, lastx, lasty;
|
|
int actx, acty;
|
|
int ddx, ddy;
|
|
s32 ar = 0;
|
|
|
|
//传递参数
|
|
for (i = 0; i <4;i++)
|
|
{
|
|
cp[i].x = threex[i];
|
|
cp[i].y = threey[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)
|
|
}
|
|
|
|
k = (long)((k / step)+1) * YUFENGE; //预分割针步数,设置针步数*YUFENGE.
|
|
Point2D curve[k];
|
|
|
|
double dt;
|
|
dt = 1.0 / ( k - 1 ); //分割分辨率
|
|
|
|
lastx = cp[0].x;
|
|
lasty = cp[0].y;
|
|
|
|
for (i = YUFENGE_BEGIN ;i < k ; )
|
|
{
|
|
curve[i] = pointOnCubicBezier(cp, i*dt);
|
|
sx = curve[i].x - lastx;
|
|
sy = curve[i].y - lasty;
|
|
l = sqrt(sx*sx+sy*sy); //拟合针步长度
|
|
|
|
if(i == k-1)
|
|
{
|
|
//最后一针
|
|
actx = (int)(lastx);
|
|
acty = (int)(lasty);
|
|
curx = (int)(cp[3].x);
|
|
cury = (int)(cp[3].y);
|
|
|
|
ddx = curx-actx;
|
|
ddy = cury-acty;
|
|
|
|
dx = (int)(abs(ddx)+0.5);
|
|
dy = (int)(abs(ddy)+0.5);
|
|
|
|
lastx = curx;
|
|
lasty = cury;
|
|
|
|
absItem.ctrl = DATA_SEWING;
|
|
absItem.ax = curx;
|
|
absItem.ay = cury;
|
|
|
|
double tar = atan2(dy,dx);
|
|
ar = (tar * 10000+0.5*(tar>0?1:-1));
|
|
absItem.ar = ar;
|
|
|
|
absAry.append((char*)&absItem,sizeof(DsAbsItem));
|
|
|
|
count++;
|
|
break;
|
|
}
|
|
else if(l >= (step-1))
|
|
{
|
|
actx = (int)(lastx);
|
|
acty = (int)(lasty);
|
|
curx = (int)(curve[i].x);
|
|
cury = (int)(curve[i].y);
|
|
|
|
ddx = curx-actx;
|
|
ddy = cury-acty;
|
|
|
|
dx = (int)(abs(ddx)+0.5);
|
|
dy = (int)(abs(ddy)+0.5);
|
|
|
|
lastx = curx;
|
|
lasty = cury;
|
|
count++;
|
|
|
|
if ((i + YUFENGE_BEGIN) >= k-1)
|
|
{
|
|
i = k-1;
|
|
}
|
|
else
|
|
{
|
|
i=i+YUFENGE_BEGIN;
|
|
}
|
|
|
|
absItem.ctrl = DATA_SEWING;
|
|
absItem.ax = curx;
|
|
absItem.ay = cury;
|
|
|
|
double tar = atan2(dy,dx);
|
|
ar = (tar * 10000+0.5*(tar>0?1:-1));
|
|
absItem.ar = ar;
|
|
|
|
absAry.append((char*)&absItem,sizeof(DsAbsItem));
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
void getSplineNew(QList<QPointF> &ptList, QList<QPointF> &splineList)
|
|
{
|
|
//读取样条线拟合控制点
|
|
QPointF pSuPoint;
|
|
int i = 0;
|
|
int iCountPoint = ptList.size();
|
|
|
|
//绘制二次累加弦长曲线
|
|
QPointF pPoint[iCountPoint];
|
|
double dfMinX, dfMinY;
|
|
|
|
dfMinX = dfMinY= 0;
|
|
|
|
while (i < iCountPoint)
|
|
{
|
|
pSuPoint = ptList.at(i);
|
|
|
|
pPoint[i].setX(pSuPoint.x());
|
|
pPoint[i].setY(pSuPoint.y());
|
|
if (i == 0)
|
|
{
|
|
dfMinX = pPoint[i].x();
|
|
dfMinY = pPoint[i].y();
|
|
}
|
|
else
|
|
{
|
|
if (dfMinX > pPoint[i].x())
|
|
dfMinX = pPoint[i].x();
|
|
|
|
if (dfMinY > pPoint[i].y())
|
|
dfMinY = pPoint[i].y();
|
|
}
|
|
i++;
|
|
}
|
|
|
|
for (i = 0; i < iCountPoint; i++)
|
|
{
|
|
double x = pPoint[i].x() - dfMinX;
|
|
double y = pPoint[i].y() - dfMinY;
|
|
pPoint[i].setX(x);
|
|
pPoint[i].setY(y);
|
|
}
|
|
|
|
getShap(iCountPoint, pPoint, splineList, dfMinX, dfMinY);
|
|
}
|
|
|
|
void getShap(int nCtrlPntNum, QPointF *pPoint, QList<QPointF> &splineList, double dfMinX, double dfMinY)
|
|
{
|
|
int i,j,k,stp,leg, m = nCtrlPntNum-1;
|
|
double t0,t1,r0,r1, *o, *p, *q;
|
|
QPointF *u, *v;
|
|
|
|
o = new double [nCtrlPntNum + 1];
|
|
p = new double [nCtrlPntNum + 1];
|
|
q = new double [nCtrlPntNum + 1];
|
|
u = new QPointF [nCtrlPntNum + 1];
|
|
v = new QPointF [nCtrlPntNum + 1];
|
|
|
|
do // 计算弦长
|
|
{
|
|
j = 0;
|
|
for (i = 1; i<= m; i++)
|
|
{
|
|
t0 = pPoint[i].x() - pPoint[i-1].x();
|
|
t1 = pPoint[i].y() - pPoint[i-1].y();
|
|
o[i] = sqrt(t0 * t0 + t1 * t1);
|
|
if (o[i] < 2)
|
|
{
|
|
j = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (j > 0)
|
|
{
|
|
for (i = j; i <= m; i++)
|
|
{
|
|
pPoint[i].setX(pPoint[i+1].x());
|
|
pPoint[i].setY(pPoint[i+1].y());
|
|
}
|
|
m--;
|
|
}
|
|
} while (j!=0);
|
|
|
|
t0 = o[1] + o[2];
|
|
t1 = 2*o[1] * o[2]; // 边界条件 m[o] 和 m[N] 的构造
|
|
|
|
u[0].setX((t0 * t0 * pPoint[1].x() - o[2] * o[2] * pPoint[0].x() - o[1] * o[1] * pPoint[2].y()) / t1 - pPoint[0].x());
|
|
u[0].setY((t0 * t0 * pPoint[1].y() - o[2] * o[2] * pPoint[0].y() - o[1] * o[1] * pPoint[2].y()) / t1 - pPoint[0].y());
|
|
t0 = sqrt(u[0].x() * u[0].x() + u[0].y() * u[0].y());
|
|
|
|
u[0].setX(u[0].x() / t0);
|
|
u[0].setY(u[0].y() / t0);
|
|
t0 = o[m-1] + o[m];
|
|
t1 = 2*o[m-1] * o[m];
|
|
|
|
r0 = (t0 * t0 * pPoint[m-1].x() - o[m] * o[m] * pPoint[m-2].x() - o[m-1] * o[m-1] * pPoint[m].x()) / t1;
|
|
r1 = (t0 * t0 * pPoint[m-1].y() - o[m] * o[m] * pPoint[m-2].y() - o[m-1] * o[m-1] * pPoint[m].y()) / t1;
|
|
u[m].setX(pPoint[m].x() - r0);
|
|
u[m].setY(pPoint[m].y() - r1);
|
|
t0 = sqrt(u[m].x() * u[m].x() + u[m].y() * u[m].y());
|
|
u[m].setX(u[m].x() / t0);
|
|
u[m].setY(u[m].y() / t0);
|
|
|
|
//计算 m 连续方程系数 C[i]
|
|
p[1] = o[2] / (o[1] + o[2]);
|
|
q[1] = 3;
|
|
t0 = p[1] * (pPoint[1].x() - pPoint[0].x()) / o[1];
|
|
t1 = p[1] * (pPoint[1].y() - pPoint[0].y()) / o[1];
|
|
v[1].setX(4 * (t0 + (1-p[1]) * (pPoint[2].x() - pPoint[1].x()) / o[1+1]));
|
|
v[1].setY(4 * (t1 + (1-p[1]) * (pPoint[2].y() - pPoint[1].y()) / o[1+1]));
|
|
|
|
for (i=2; i<= (m-1); i++)
|
|
{
|
|
p[i] = o[i+1] / (o[i]+o[i+1]);
|
|
q[i] = 3 - p[i] * (1 - p[i-1]) / q[i-1];
|
|
|
|
t0 = p[i] * (pPoint[i].x() - pPoint[i-1].x()) / o[i];
|
|
t1 = p[i] * (pPoint[i].y() - pPoint[i-1].y()) / o[i];
|
|
|
|
v[i].setX(4 * (t0 + (1 - p[i]) * (pPoint[i+1].x() - pPoint[i].x()) / o[i+1]));
|
|
v[i].setY(4 * (t1 + (1 - p[i]) * (pPoint[i+1].y() - pPoint[i].y()) / o[i+1]));
|
|
}
|
|
|
|
v[1].setX(v[1].x() - p[1] * u[0].x());
|
|
v[1].setY(v[1].y() - p[1] * u[0].y());
|
|
v[m-1].setX(v[m-1].x() - (1 - p[m-1]) * u[m].x());
|
|
v[m-1].setY(v[m-1].y() - (1 - p[m-1]) * u[m].y());
|
|
|
|
// 求解 m 连续方程, 获得 m[i]
|
|
u[1].setX(v[1].x() / q[1]);
|
|
u[1].setY(v[1].y() / q[1]);
|
|
|
|
for (i = 2; i <= m-1; i++)
|
|
{
|
|
u[i].setX((v[i].x() - p[i] * u[i-1].x()) / q[i]);
|
|
u[i].setY((v[i].y() - p[i] * u[i-1].y()) / q[i]);
|
|
}
|
|
|
|
for (i = m-2; i >= 1; i--)
|
|
{
|
|
u[i].setX(u[i].x() - u[i+1].x() * (1 - p[i]) / q[i]);
|
|
u[i].setY(u[i].y() - u[i+1].y() * (1 - p[i]) / q[i]);
|
|
}
|
|
|
|
// 求得 M[j] j=0,1,...,N
|
|
v[0].setX(4 * (pPoint[1].x() - pPoint[0].x()) / (o[1] * o[1]) - (3 * u[0].x() + u[1].x()) / o[1]);
|
|
v[0].setY(4 * (pPoint[1].y() - pPoint[0].y()) / (o[1] * o[1]) - (3 * u[0].y() + u[1].y()) / o[1]);
|
|
q[0]=0;
|
|
|
|
for (i=1; i<= m; i++)
|
|
{
|
|
q[i] = 0;
|
|
t0 = o[i] * o[i];
|
|
v[i].setX(-4 * (pPoint[i].x() - pPoint[i-1].x()) / t0 + (3 * u[i].x() + u[i-1].x()) / o[i]);
|
|
v[i].setY(-4 * (pPoint[i].y() - pPoint[i-1].y()) / t0 + (3 * u[i].y() + u[i-1].y()) / o[i]);
|
|
for (j=1; j<= i; j++)
|
|
q[i] = q[i] + o[j];
|
|
}
|
|
|
|
// o[j] j=0,1,...,N 表示半节点
|
|
o[0] = q[0];
|
|
o[m+1] = q[m];
|
|
|
|
for (i = 1; i<= m; i++)
|
|
o[i] = (q[i-1] + q[i]) / 2;
|
|
|
|
// 显示或绘之曲线
|
|
QPointF suPoint;
|
|
suPoint.setX(pPoint[0].x() + dfMinX);
|
|
suPoint.setY(pPoint[0].y() + dfMinY);
|
|
splineList.append(suPoint);
|
|
// pDC->MoveTo(lx1,ly1);
|
|
|
|
for (i = 0; i< m; i++)
|
|
{
|
|
leg = (int)(o[i+1] - o[i]);
|
|
stp = leg / 10;
|
|
|
|
if (leg> 600)
|
|
stp = leg / 60;
|
|
|
|
if (leg> 900)
|
|
stp = leg / 80;
|
|
|
|
if (leg>1200)
|
|
stp = leg / 100;
|
|
|
|
if (leg > 2400)
|
|
stp = leg / 120;
|
|
|
|
if (leg>4800)
|
|
stp = leg / 140;
|
|
|
|
if (stp)
|
|
k = leg/stp;
|
|
else
|
|
k = 0;
|
|
|
|
for (j = 0; j<= k; j++)
|
|
{
|
|
r0 = o[i] + stp * j - q[i];
|
|
suPoint.setX(pPoint[i].x() + r0 * (u[i].x() + v[i].x() / 2 * r0) + dfMinX);
|
|
suPoint.setY(pPoint[i].y() + r0 * (u[i].y() + v[i].y() / 2 * r0) + dfMinY);
|
|
splineList.append(suPoint);
|
|
//pDC->LineTo(lx1,ly1);
|
|
}
|
|
}
|
|
|
|
suPoint.setX(pPoint[m].x() + dfMinX);
|
|
suPoint.setY(pPoint[m].y() + dfMinY);
|
|
splineList.append(suPoint);
|
|
//pDC->LineTo(lx1,ly1);
|
|
|
|
delete o;
|
|
delete p;
|
|
delete q;
|
|
delete u;
|
|
delete v;
|
|
}
|
|
|
|
void getCurvePointFillLine(QList<QPointF> &inList, double indRunLen, QList<QPointF> &outList, int iSumParm, BYTE biLenLimit)
|
|
{
|
|
QPointF dPoint1, dPoint2, dPoint3;
|
|
double dTatol, dLen1, dLen2, dSpace;
|
|
long lSum, lCount;
|
|
|
|
//计算总的线段长
|
|
int iCountPoint = inList.size();
|
|
if(iCountPoint <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
getTotalDistanceFillLine(&inList, dTatol);
|
|
if(dTatol == 0)
|
|
return;
|
|
|
|
if (biLenLimit == ADJUSTLINE_ADD_DUAN_LIMIT)
|
|
{
|
|
lSum = iSumParm;
|
|
if (lSum < 1)
|
|
lSum = 1;
|
|
dSpace = dTatol / lSum;
|
|
}
|
|
else if (iSumParm > 2)
|
|
{
|
|
lSum = iSumParm;
|
|
dSpace = dTatol / (double)lSum;
|
|
}
|
|
else
|
|
{
|
|
if (biLenLimit == OBJECT_STITCHLEN_NEW_BIG)
|
|
{
|
|
lSum = int(dTatol / indRunLen);
|
|
dSpace = dTatol / lSum;
|
|
|
|
if(lSum == 0)
|
|
lSum = 1;
|
|
}
|
|
else if (biLenLimit == OBJECT_STITCHLEN_NEW_SAMALL)
|
|
{
|
|
lSum = doubleToLong(dTatol / indRunLen + 0.1667);
|
|
dSpace = dTatol / (double)lSum;
|
|
if(lSum == 0)
|
|
lSum = 1;
|
|
}
|
|
else if (biLenLimit == OBJECT_STITCHLEN_NEW_SAME)
|
|
{
|
|
lSum = int(dTatol / indRunLen);
|
|
dSpace = indRunLen;
|
|
if(lSum == 0)
|
|
lSum = 1;
|
|
}
|
|
else if (biLenLimit == LINEDUAN_STITCHLEN_LIMIT ||
|
|
biLenLimit == LINEDUAN_STITCHLEN_LIMIT_END)
|
|
{
|
|
lSum = int(dTatol / indRunLen);
|
|
dSpace = indRunLen;
|
|
}
|
|
else if (biLenLimit == LINEDUAN_NUM_LIMIT)
|
|
{
|
|
lSum = int(dTatol / indRunLen);
|
|
dSpace = dTatol / (double)lSum;
|
|
}
|
|
else
|
|
{
|
|
if (biLenLimit)
|
|
{
|
|
lSum = int(dTatol / indRunLen);
|
|
if (lSum < 1)
|
|
lSum = doubleToLong(dTatol / indRunLen + 0.1667);
|
|
}
|
|
else
|
|
lSum = doubleToLong(dTatol / indRunLen + 0.1667);
|
|
|
|
if(lSum == 0)
|
|
lSum = 1;
|
|
|
|
dSpace = dTatol / (double)lSum;
|
|
}
|
|
}
|
|
|
|
dPoint1 = inList[0];
|
|
outList.append(dPoint1);//添加第一个点
|
|
|
|
pointToPoint(dPoint1, dPoint2);
|
|
dLen1 = dSpace;
|
|
dLen2 = 0;
|
|
int i = 0;
|
|
for(lCount = 0; lCount < lSum; lCount++)
|
|
{
|
|
while(i < inList.size()-1 && dLen2 < dLen1)
|
|
{
|
|
dLen1 -= dLen2;
|
|
pointToPoint(dPoint2, dPoint1);
|
|
i++;
|
|
dPoint2 = inList[i];
|
|
distPointToPoint(dPoint1, dPoint2, dLen2);
|
|
}
|
|
if(dLen1 < dLen2)
|
|
{
|
|
getPointInSectFillLine(dPoint1, dPoint2, dLen1, dPoint3);
|
|
}
|
|
else
|
|
{
|
|
dPoint3.setX(dPoint2.x());
|
|
dPoint3.setY(dPoint2.y());
|
|
}
|
|
outList.append(dPoint3);
|
|
dLen2 -= dLen1;
|
|
dLen1 = dSpace;
|
|
pointToPoint(dPoint3, dPoint1);
|
|
}
|
|
|
|
if (biLenLimit == LINEDUAN_STITCHLEN_LIMIT_END ||
|
|
biLenLimit == OBJECT_STITCHLEN_NEW_SAME)
|
|
{
|
|
if (fabs((lSum * indRunLen) - dTatol) > ZERO)
|
|
{
|
|
outList.append(inList.last());
|
|
}
|
|
}
|
|
}
|
|
|
|
int getTotalDistanceFillLine(QList<QPointF> *pPointList, double &dTotal)
|
|
{
|
|
QPointF dPoint, dNext;
|
|
double d;
|
|
dTotal = 0;
|
|
int i = 0;
|
|
long lSum = (long)pPointList->count();
|
|
if(lSum > 1)
|
|
{
|
|
while(i < pPointList->size())
|
|
{
|
|
dPoint = pPointList->at(i);
|
|
i++;
|
|
if(i < pPointList->size())
|
|
{
|
|
dNext = pPointList->at(i);
|
|
distPointToPoint(dPoint, dNext, d);
|
|
dTotal += d;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return ERROR_NOTHING;
|
|
}
|
|
|
|
void pointToPoint(const QPointF &inPoint, QPointF &outPoint)
|
|
{
|
|
outPoint.setX(inPoint.x());
|
|
outPoint.setY(inPoint.y());
|
|
}
|
|
|
|
long doubleToLong(double indValue)
|
|
{
|
|
return (long)round(indValue);
|
|
}
|
|
|
|
double round(double indValue)
|
|
{
|
|
return floor(indValue + 0.5);
|
|
}
|
|
|
|
void distPointToPoint(const QPointF &p1, const QPointF &p2, double &outd)
|
|
{
|
|
outd = disPointToPoint(p1.x(), p1.y(), p2.x(), p2.y());
|
|
}
|
|
|
|
bool getPointInSectFillLine(const QPointF &p1, const QPointF &p2, const double &d, QPointF &outp)
|
|
{
|
|
bool bRes;
|
|
QPointF dpoint[3];
|
|
|
|
dpoint[0].setX(p1.x());
|
|
dpoint[0].setY(p1.y());
|
|
dpoint[1].setX(p2.x());
|
|
dpoint[1].setY(p2.y());
|
|
dpoint[2].setX(outp.x());
|
|
dpoint[2].setY(outp.y());
|
|
|
|
bRes = getPointAtSect(dpoint[0], dpoint[1], d, dpoint[2]);
|
|
outp.setX(dpoint[2].x());
|
|
outp.setY(dpoint[2].y());
|
|
|
|
return bRes;
|
|
}
|
|
|
|
bool getPointAtSect(const QPointF &p1, const QPointF &p2, const double &d, QPointF &outp)
|
|
{
|
|
double s = disPointToPoint(p1.x(), p1.y(), p2.x(), p2.y());
|
|
if(fabs(s) < ZERO)
|
|
{
|
|
if(d < ZERO)
|
|
{
|
|
outp.setX(p1.x());
|
|
outp.setY(p1.y());
|
|
}
|
|
return false;
|
|
}
|
|
outp.setX((p2.x() - p1.x()) * d / s + p1.x());
|
|
outp.setY((p2.y() - p1.y()) * d / s + p1.y());
|
|
|
|
return true;
|
|
}
|
|
|
|
double disPointToPoint(double x1, double y1, double x2, double y2)
|
|
{
|
|
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
|
}
|
|
|
|
void getBezierPointList(double threex[], double threey[], s16 step, QList<QPointF> &outList)
|
|
{
|
|
long k = 0;
|
|
double sx,sy;
|
|
Point2D cp[4];
|
|
|
|
//传递参数
|
|
for (s16 i = 0; i < 4; i++)
|
|
{
|
|
cp[i].x = threex[i];
|
|
cp[i].y = threey[i];
|
|
}
|
|
|
|
//求控制点总长
|
|
for (s16 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)
|
|
}
|
|
|
|
k = (long)((k / step)+1) * YUFENGE; //分割针步数
|
|
Point2D curve;
|
|
|
|
double dt;
|
|
dt = 1.0 / ( k - 1 ); //分割分辨率
|
|
|
|
QPointF p;
|
|
for (int i = 0; i < k; i++)
|
|
{
|
|
curve = pointOnCubicBezier(cp, i*dt);
|
|
p.setX(curve.x);
|
|
p.setY(curve.y);
|
|
outList.append(p);
|
|
}
|
|
}
|
|
|
|
int getSplineMinMax(QList<QPointF> &ptList, double *pminx, double *pmaxx, double *pminy, double *pmaxy)
|
|
{
|
|
QList<QPointF> splineListXY;//拟合后的点
|
|
splineListXY.clear();
|
|
|
|
double minx, miny, maxx, maxy;
|
|
minx = S32_MAX;
|
|
maxx = S32_MIN;
|
|
miny = S32_MAX;
|
|
maxy = S32_MIN;
|
|
|
|
//读取样条线拟合控制点
|
|
QPointF pSuPoint;
|
|
int i = 0;
|
|
int iCountPoint = ptList.size();
|
|
|
|
//绘制二次累加弦长曲线
|
|
QPointF pPoint[iCountPoint];
|
|
double dfMinX, dfMinY;
|
|
|
|
dfMinX = dfMinY= 0;
|
|
|
|
while (i < iCountPoint)
|
|
{
|
|
pSuPoint = ptList.at(i);
|
|
|
|
pPoint[i].setX(pSuPoint.x());
|
|
pPoint[i].setY(pSuPoint.y());
|
|
if (i == 0)
|
|
{
|
|
dfMinX = pPoint[i].x();
|
|
dfMinY = pPoint[i].y();
|
|
}
|
|
else
|
|
{
|
|
if (dfMinX > pPoint[i].x())
|
|
dfMinX = pPoint[i].x();
|
|
|
|
if (dfMinY > pPoint[i].y())
|
|
dfMinY = pPoint[i].y();
|
|
}
|
|
i++;
|
|
}
|
|
|
|
for (i = 0; i < iCountPoint; i++)
|
|
{
|
|
double x = pPoint[i].x() - dfMinX;
|
|
double y = pPoint[i].y() - dfMinY;
|
|
pPoint[i].setX(x);
|
|
pPoint[i].setY(y);
|
|
}
|
|
|
|
getShap(iCountPoint, pPoint, splineListXY, dfMinX, dfMinY);
|
|
|
|
for (i=0;i<splineListXY.size();i++)
|
|
{
|
|
if (minx > splineListXY[i].x())
|
|
{
|
|
minx = splineListXY[i].x();
|
|
}
|
|
if (maxx < splineListXY[i].x())
|
|
{
|
|
maxx = splineListXY[i].x();
|
|
}
|
|
if (miny > splineListXY[i].y())
|
|
{
|
|
miny = splineListXY[i].y();
|
|
}
|
|
if (maxy < splineListXY[i].y())
|
|
{
|
|
maxy = splineListXY[i].y();
|
|
}
|
|
}
|
|
|
|
if (minx < *pminx)
|
|
{
|
|
*pminx = minx;
|
|
}
|
|
|
|
if (miny < *pminy)
|
|
{
|
|
*pminy = miny;
|
|
}
|
|
|
|
if (maxx > *pmaxx)
|
|
{
|
|
*pmaxx = maxx;
|
|
}
|
|
|
|
if (maxy > *pmaxy)
|
|
{
|
|
*pmaxy = maxy;
|
|
}
|
|
|
|
return 0;
|
|
}
|