#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]x[1] && y[1]>y[0]) || (x[2]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 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 &ptList, QList &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 &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 &inList, double indRunLen, QList &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 *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 &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 &ptList, double *pminx, double *pmaxx, double *pminy, double *pmaxy) { QList 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[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; }