QuiltingHMI/datafile/dataoperat.cpp
2024-02-06 15:10:48 +08:00

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;
}