// // SWPosPointcut.c // DrawTest // // Created by 王阳阳 on 2022/9/6. // #include "SWPosPointcut.h" #include #define MaxPoints 6000.f #define MaxSegment 100.f #define MaxWidthScale 1.5f #define MinRadius 0.3f #define MaxSteps 0.13f #define MinShake 130 #define MaxShake 170 #define M_PI 3.14159265358979323846264338327950288f #define RadianTodegrees(x) (x * 180.f / M_PI) static SWPosPoint lastePos; static SWLineSegment *curLeftLine = NULL; static SWLineSegment *curRightLine = NULL; static int pointStep = 0; void SWPosRest(SWPosPoint pos) { lastePos = pos; pointStep = 0; SWLineSegment *onSegment = curLeftLine; if (curLeftLine != NULL) { while (onSegment) { SWLineSegment *tempSeg = (SWLineSegment *)onSegment->preSegment; onSegment->preSegment = NULL; free(onSegment); if (tempSeg != NULL) { onSegment = tempSeg; } else { onSegment = NULL; } } } onSegment = curRightLine; if (curRightLine != NULL) { while (onSegment) { SWLineSegment *tempSeg = (SWLineSegment *)onSegment->preSegment; onSegment->preSegment = NULL; free(onSegment); if (tempSeg != NULL) { onSegment = tempSeg; } else { onSegment = NULL; } } } curLeftLine = NULL; curRightLine = NULL; } SWPosRet SWGetTangentcurPoint(SWPosPoint prevPoint,SWPosPoint curPoint, SWLineSegment leftLine,SWLineSegment rightLine, int circle) { double distance = GetPointDistance(prevPoint, curPoint); double radiusDistance = (prevPoint.radius + curPoint.radius); if ((distance < radiusDistance) || distance < 1) { if (prevPoint.realPoint.x != lastePos.realPoint.x && prevPoint.realPoint.y != lastePos.realPoint.y){ double rads = SWBetweenLinesrads(lastePos.realPoint, prevPoint.realPoint, curPoint.realPoint, prevPoint.realPoint); double angle = RadianTodegrees(rads); if (angle > 150) { SWPosRet retPos; retPos.prevLeftPoint = SWPointCutMake(0, 0); retPos.prevLeftIntersectPoint = SWPointCutMake(0, 0); retPos.prevRightPoint = SWPointCutMake(0, 0); retPos.prevRightIntersectPoint = SWPointCutMake(0, 0); retPos.curLeftPoint = SWPointCutMake(0, 0); retPos.curRightPoint = SWPointCutMake(0, 0); retPos.circlePoints.clear(); retPos.circleCount = 0; retPos.status = SWPosRetFail; return retPos; } } } if (circle == 1 || pointStep == 0) { return getCircleSegments(prevPoint, curPoint, leftLine, rightLine, distance,pointStep); } if (distance > fabs(prevPoint.radius - curPoint.radius)) { SWPointcut pointFa= {0,0};//左侧切点 SWPointcut pointFa1 = {0,0};//右侧切点 SWPointcut pointFb = {0,0};//左侧切点 SWPointcut pointFb1 = {0,0};//右侧切点 double base = atan2(curPoint.realPoint.y - prevPoint.realPoint.y, curPoint.realPoint.x - prevPoint.realPoint.x); double ang = acos((prevPoint.radius - curPoint.radius) / distance); pointFa = GetMaleTangentPointValue(prevPoint, base + ang); pointFb = GetMaleTangentPointValue(curPoint, base + ang); pointFb1 = GetMaleTangentPointValue(curPoint, base - ang); pointFa1 = GetMaleTangentPointValue(prevPoint, base - ang); SWPointcut pointLeftIntersect = {0,0};//左侧切点 SWPointcut pointRightIntersect = {0,0};//右侧切点 if (leftLine.status == SWPosRetFail && rightLine.status == SWPosRetFail) { pointStep++; lastePos = prevPoint; SWPosRet retPos1; retPos1.prevLeftPoint = pointFa;//左侧切点 retPos1.prevLeftIntersectPoint = pointLeftIntersect;//左侧切点交点 retPos1.prevRightPoint = pointFa1;//右侧切点 retPos1.prevRightIntersectPoint = pointRightIntersect;//右侧切点交点 retPos1.curLeftPoint = pointFb;//当前点左侧切点 retPos1.curRightPoint = pointFb1;//当前点右侧切点 retPos1.circlePoints.clear(); retPos1.circleCount = 0; retPos1.status = SWPosRetSuccess;//计算结果状态 return retPos1; } pointRightIntersect = SWgetEdgePoint(rightLine.startPoint,rightLine.endPoint,pointFa1,pointFb1,prevPoint.realPoint,0); pointLeftIntersect = SWgetEdgePoint(leftLine.startPoint,leftLine.endPoint,pointFa,pointFb,prevPoint.realPoint,1); if ((pointRightIntersect.x == 0 && pointRightIntersect.y ==0) || (pointLeftIntersect.x == 0 && pointLeftIntersect.y == 0)) { return getCircleSegments(prevPoint, curPoint, leftLine, rightLine, distance,pointStep); } /** * 处理切点极端情况(0,0) */ double lDistance = GetPointDistance(prevPoint,SWPosPointMake(pointLeftIntersect.x,pointLeftIntersect.y,0)); if (lDistance > prevPoint.radius*10) { pointLeftIntersect = SWPointCutMake((leftLine.endPoint.x + pointFa.x)/2.f,(leftLine.endPoint.y + pointFa.y)/2.f); } double rDistance = GetPointDistance(prevPoint,SWPosPointMake(pointRightIntersect.x,pointRightIntersect.y,0)); if (rDistance > prevPoint.radius*10) { pointRightIntersect = SWPointCutMake((rightLine.endPoint.x + pointFa1.x)/2.f,(rightLine.endPoint.y + pointFa1.y)/2.f); } SWPosRet retPos2; retPos2.prevLeftPoint = pointFa;//左侧切点 retPos2.prevLeftIntersectPoint = pointLeftIntersect;//左侧切点交点 retPos2.prevRightPoint = pointFa1;//右侧切点 retPos2.prevRightIntersectPoint = pointRightIntersect;//右侧切点交点 retPos2.curLeftPoint = pointFb;//当前点左侧切点 retPos2.curRightPoint = pointFb1;//当前点右侧切点 retPos2.circlePoints.clear(); retPos2.circleCount = 0; retPos2.status = SWPosRetSuccess;//计算结果状态 lastePos = prevPoint; pointStep++; return retPos2; } SWPosRet retPos; retPos.prevLeftPoint = SWPointCutMake(0, 0); retPos.prevLeftIntersectPoint = SWPointCutMake(0, 0); retPos.prevRightPoint = SWPointCutMake(0, 0); retPos.prevRightIntersectPoint = SWPointCutMake(0, 0); retPos.curLeftPoint = SWPointCutMake(0, 0); retPos.curRightPoint = SWPointCutMake(0, 0); retPos.circlePoints.clear(); retPos.circleCount = 0; retPos.status = SWPosRetFail; return retPos; } SWPosRet getCircleSegments(SWPosPoint prevPoint,SWPosPoint curPoint,SWLineSegment leftLine, SWLineSegment rightLine,double distance,int step) { SWPointcut controlPoint = SWPointCutMake(prevPoint.realPoint.x, prevPoint.realPoint.y); int segements = distance/0.2f; if (segements < 5) { segements = 5; } double preRadius = 0; if (leftLine.status == SWPosRetSuccess && rightLine.status == SWPosRetSuccess) { preRadius = GetPointDistance(SWPosPointMake(leftLine.endPoint.x, leftLine.endPoint.y, 0), SWPosPointMake(rightLine.endPoint.x, rightLine.endPoint.y, 0))/2.f; } else { preRadius = prevPoint.radius; } double circleRadius = curPoint.radius - preRadius; QList circleAry; for (int i = 0; i < segements; i ++) { if (i == 0) { SWCirclePoint cPoint = SWCircleMake(SWPosPointMake(prevPoint.realPoint.x, prevPoint.realPoint.y, preRadius)); circleAry.append(cPoint); } else if (i == (segements - 1)) { SWCirclePoint cPoint = SWCircleMake(SWPosPointMake(curPoint.realPoint.x, curPoint.realPoint.y, preRadius + circleRadius)); circleAry.append(cPoint); } else { double t = (double)i/segements; double x = pow(1 - t, 2) * prevPoint.realPoint.x + 2.0 * (1 - t) * t * controlPoint.x + t * t * curPoint.realPoint.x; double y = pow(1 - t, 2) * prevPoint.realPoint.y + 2.0 * (1 - t) * t * controlPoint.y + t * t * curPoint.realPoint.y; SWCirclePoint cPoint = SWCircleMake(SWPosPointMake(x, y, preRadius + circleRadius*t)); circleAry.append(cPoint); } } pointStep++; SWPosRet retPos; retPos.prevLeftPoint = SWPointCutMake(0, 0);//左侧切点 retPos.prevLeftIntersectPoint = SWPointCutMake(0, 0);//左侧切点交点 retPos.prevRightPoint = SWPointCutMake(0, 0);//右侧切点 retPos.prevRightIntersectPoint = SWPointCutMake(0, 0);//右侧切点交点 retPos.curLeftPoint = SWPointCutMake(0, 0);//当前点左侧切点 retPos.curRightPoint = SWPointCutMake(0, 0);//当前点右侧切点 retPos.circlePoints = circleAry; retPos.circleCount = segements; retPos.status = SWPosRetSuccess;//计算结果状态 return retPos; } QList fillPoints(SWPosPoint prevPoint,SWPosPoint curPoint,double distance) { SWPointcut controlPoint = SWPointCutMake(prevPoint.realPoint.x, prevPoint.realPoint.y); int segements = distance/0.5f; double preRadius = prevPoint.radius; double circleRadius = curPoint.radius - preRadius; QList circleAry; for (int i = 0; i < segements; i ++) { double t = (double)i/segements; double x = pow(1 - t, 2) * prevPoint.realPoint.x + 2.0 * (1 - t) * t * controlPoint.x + t * t * curPoint.realPoint.x; double y = pow(1 - t, 2) * prevPoint.realPoint.y + 2.0 * (1 - t) * t * controlPoint.y + t * t * curPoint.realPoint.y; SWPosPoint cPoint = SWPosPointMake(x, y, preRadius + circleRadius*t); circleAry.append(cPoint); } return circleAry; } SWPosStatus IsPointInMatrix(SWPointcut p1 ,SWPointcut p2,SWPointcut p3 ,SWPointcut p4,SWPointcut p) { if (GetCross(p1,p2,p) * GetCross(p3,p4,p) >= 0 && GetCross(p2,p3,p) * GetCross(p4,p1,p) >= 0) { return SWPosRetSuccess; } else { return SWPosRetFail; } } double GetCross(SWPointcut p1, SWPointcut p2,SWPointcut p) { return (p2.x - p1.x) * (p.y - p1.y) -(p.x - p1.x) * (p2.y - p1.y); } SWPointcut SWratioPoint(SWPointcut startPoint, SWPointcut endPoint, double ratio) { SWPointcut ret = {0,0}; double x = endPoint.x - startPoint.x; double y = endPoint.y - startPoint.y; ret.x = x*ratio + startPoint.x; ret.y = y*ratio + startPoint.y; return ret; } SWPointcut SWrotatePoint(SWPointcut point, SWPointcut center, double angle) { SWPointcut ret = {0,0}; double x = point.x - center.x; double y = point.y - center.y; ret.x = (x*cos(angle) - y*sin(angle)) + center.x; ret.y = (x*sin(angle) + y*cos(angle)) + center.y; return ret; } SWPointcut GetMaleTangentPointValue(SWPosPoint point, double a) { SWPointcut ret = {0,0}; ret.x = (double) (point.realPoint.x + point.radius * cos(a)); ret.y = (double) (point.realPoint.y + point.radius * sin(a)); return ret; } SWPointcut SWgetEdgePoint(SWPointcut a, SWPointcut b, SWPointcut c,SWPointcut d,SWPointcut e,int leftLine) { double dx1 = a.x - b.x; double dy1 = a.y - b.y; double dx2 = d.x - c.x; double dy2 = d.y - c.y; SWPointcut edgePointf = {0,0}; SWPointcut pointf = {0,0}; if (dx1 == 0 && dx2 != 0) {//ab垂直x轴 double k2 = dy2 / dx2;//第二条直线斜率 double h2 = d.y - k2 * d.x;//第二条直线截距 //交点在a.x或者b.x double x = a.x; double y = k2 * x + h2; pointf = SWPointCutMake(x,y); if (isPointOnLine(x, y, a, b) == 1 && isPointOnLine(x, y, c, d) == 1) {//焦点在线段上 edgePointf = pointf; } } else if (dx1 != 0 && dx2 == 0) {//cd垂直x轴 double k1 = dy1 / dx1;//第一条直线斜率 double h1 = b.y - k1 * b.x;//第一条直线的截距 //交点在c.x或者d.x double x = c.x; double y = k1 * x + h1; pointf = SWPointCutMake(x,y); if (isPointOnLine(x, y, a, b) == 1 && isPointOnLine(x, y, c, d) == 1) {//焦点在线段上 edgePointf = pointf; } } else if (dx1 == 0 && dx2 == 0) {//ab cd都垂直x轴 //无交点 } else { double k1 = dy1 / dx1;//第一条直线斜率 double h1 = b.y - k1 * b.x;//第一条直线的截距 double k2 = dy2 / dx2;//第二条直线斜率 double h2 = d.y - k2 * d.x;//第二条直线截距 if (k1 == k2) {//两直线平行 if (h1 == h2) {//重合 } else {//平行 } } else { double x = (h1 - h2) / (k2 - k1); double y = k1 * x + h1; pointf = SWPointCutMake(x,y); if (isPointOnLine(x, y, a, b) == 1 && isPointOnLine(x, y, c, d) == 1) {//焦点在线段上 edgePointf = pointf; } } } if (edgePointf.x > 0 && edgePointf.y > 0) {//有交点 return edgePointf; } else {//无交点 // // 向量1的坐标:(x1,y1),向量2的坐标:(x2,y2); 则 double tmpDegree = getAngle(dx1, dy1, dx2, dy2); if ((pointf.x > 0 && pointf.y > 0) && tmpDegree >= 90 && tmpDegree < 180) { return pointf; } else if (tmpDegree == 180) { return b; } else { //角度小于阈值进行补点操作 if (tmpDegree <= 90) { return SWPointCutMake(0,0); } else { double rads = SWBetweenLinesrads(b, e, c, e); double angle = RadianTodegrees(rads); if (leftLine == 1) { return SWrotatePoint(b,e,angle/2.f); } else { return SWrotatePoint(c,e,angle/2.f); } } } } } int isPointOnLine(double x, double y, SWPointcut start, SWPointcut end) { if (start.x <= end.x) { if (x < start.x || x > end.x) return 0; } else { if (x < end.x || x > start.x) return 0; } if (start.y <= end.y) { if (y < start.y || y > end.y) return 0; } else { if (y < end.y || y > start.y) return 0; } return 1; } double getAngle(double x1, double y1, double x2, double y2) { float value = (x1 * x2 + y1 * y2) / (hypot(x1, y1) * hypot(x2, y2)); // 余弦值 if(value < -1) { value = -1; } if(value > 1) { value = 1; } double angle = RadianTodegrees(acos(value)); // 角度 return angle; } SWPointcut getSamllAngleVertex(SWPointcut b, SWPointcut c,double cosAngle) { double dx = c.x - b.x; double dy = c.y - b.y; // double disBC = Math.hypot(dx, dy); // double betweenP = Math.cos((45f / 180f) * Math.PI) * disBC; double ratio = (double) cos((cosAngle / 180.f) * M_PI); SWPointcut betweenP = SWPointCutMake(b.x + dx * ratio, b.y + dy * ratio); SWPointcut anglePointf = calcNewPoint(betweenP, b, (cosAngle / 180.f) * M_PI); return anglePointf; } SWPointcut SWExtendPoint(SWPointcut a, SWPointcut b, SWPointcut c,SWPointcut d) { SWPointcut point = {0,0}; double k1 = 0; double k2 = 0; int k1Vaild = 0; int k2Vaild = 0; double b1 = 0; double b2 = 0; if (b.x != a.x) { k1 = (b.y - a.y)/(b.x - a.x); k1Vaild = 1; } if (d.x != c.x) { k2 = (d.y - c.y)/(d.x - c.x); k2Vaild = 1; } if ( (k1Vaild == k2Vaild) && k1 == k2) { return point; } if (k1Vaild == 1) { b1 = (b.x*a.y - a.x*b.y)/(b.x - a.x); } if (k2Vaild == 1) { b2 = (d.x*c.y - c.x*d.y)/(d.x - c.x); } if (k1Vaild == 0) { point.x = a.x; point.y = k2 * point.x + b2; } else if (k2Vaild == 0) { point.x = c.x; point.y = k1 *point.x + b1; } else if (k1 == 0) { point.x = (a.y - b2)/k2; point.y = a.y; } else if (k2 == 0) { point.x = (c.y - b1)/k1; point.y = c.y; } else { point.x = (double)((b2 - b1) / (k1 - k2)); point.y = (double)((k2 * b1 - k1 * b2) / (k2 - k1)); } return point; } double GetPointDistance(SWPosPoint start, SWPosPoint end) { return sqrtf(pow((start.realPoint.x - end.realPoint.x), 2) + pow((start.realPoint.y - end.realPoint.y), 2))/1.f; } SWPointcut SWPointCutMake(double x,double y) { SWPointcut pointCut = {x,y}; return pointCut; } SWPosPoint SWPosPointMake(double x,double y,double radius) { SWPosPoint posPoint = {{x,y},radius}; return posPoint; } SWPointcut calcNewPoint(SWPointcut p, SWPointcut pCenter, double theta) { double cosv = (double) cos(theta); double sinv = (double) sin(theta); // calc new point double newX = (p.x - pCenter.x) * cosv - (p.y - pCenter.y) * sinv + pCenter.x; double newY = (p.x - pCenter.x) * sinv + (p.y - pCenter.y) * cosv + pCenter.y; return SWPointCutMake(newX, newY); } SWLineSegment SWLineMake(double x1,double y1,double x2, double y2) { // SWLineSegment linePoint = {{x1,y1},{x2,y2},SWPosRetSuccess,NULL}; SWLineSegment linePoint; // linePoint.startPoint = {x1,y1}; linePoint.startPoint.x = x1; linePoint.startPoint.y = y1; // linePoint.endPoint = {x2,y2}; linePoint.endPoint.x = x2; linePoint.endPoint.y = y2; linePoint.status = SWPosRetSuccess; return linePoint; } SWLineSegment SWLineMakeZero(void) { // SWLineSegment linePoint = {{0,0},{0,0},SWPosRetFail,NULL}; SWLineSegment linePoint; // linePoint.startPoint = {0,0}; linePoint.startPoint.x = 0; linePoint.startPoint.y = 0; // linePoint.endPoint = {0,0}; linePoint.endPoint.x = 0; linePoint.endPoint.y = 0; linePoint.status = SWPosRetFail; return linePoint; } double SWBetweenLinesrads(SWPointcut line1Start, SWPointcut line1End, SWPointcut line2Start, SWPointcut line2End) { double a = line1End.x - line1Start.x; double b = line1End.y - line1Start.y; double c = line2End.x - line2Start.x; double d = line2End.y - line2Start.y; float value = ((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))); if(value < -1) { value = -1; } if(value > 1) { value = 1; } float rads = acos(value); return rads; } double CalculatePointradius(double speed,double prevPointradius, double radius,double force ,double maxForce, double stressSpl,int forceEnable, double distance) { if (speed > MaxPoints) { speed = MaxPoints; } if (forceEnable == 1) { double forceScale = force/maxForce; forceScale = forceScale * (1 + stressSpl); double newRadius = radius*forceScale; double dropSize = newRadius - prevPointradius ; if (dropSize > prevPointradius *MaxSteps) { dropSize = prevPointradius *MaxSteps; } if (dropSize < - prevPointradius *MaxSteps) { dropSize = - prevPointradius *MaxSteps; } newRadius = prevPointradius + dropSize; newRadius = newRadius > MaxWidthScale*radius ? MaxWidthScale*radius : newRadius; if(newRadius < 0.7f) { newRadius = 0.7f; } return newRadius; } else { double speedScale = MaxPoints/MaxSegment; double fragments = speed/speedScale; double radiusScale = fragments/MaxSegment; double newRadius = radius - radius*radiusScale; double dropSize = prevPointradius - newRadius; if (dropSize > prevPointradius *MaxSteps) { dropSize = prevPointradius *MaxSteps; } if (dropSize < - prevPointradius *MaxSteps) { dropSize = - prevPointradius *MaxSteps; } newRadius = prevPointradius - dropSize; newRadius = newRadius < MinRadius*radius ? MinRadius*radius : newRadius; if(newRadius < 0.7f) { newRadius = 0.7f; } return newRadius; } } SWPosPoint *CalculateStroke(SWPosPoint posAry[],int length,double preRadius) { for (int k = 0; k < length; k ++) { SWPosPoint pos = posAry[k]; double pointRadius = preRadius /(length - 1); pos.radius = preRadius - pointRadius*k; if (pos.radius <= 0.4) { pos.radius = 0.4f; } posAry[k] = pos; } return posAry; } SWPosStatus CalculateShake(SWPosPoint prePoint,SWPosPoint curPoint,SWPosPoint nextPoint) { double distance = GetPointDistance(curPoint, nextPoint); double rads = SWBetweenLinesrads(SWPointCutMake(prePoint.realPoint.x, prePoint.realPoint.y), SWPointCutMake(curPoint.realPoint.x, curPoint.realPoint.y), SWPointCutMake(nextPoint.realPoint.x, nextPoint.realPoint.y), SWPointCutMake(curPoint.realPoint.x, curPoint.realPoint.y)); double angle = RadianTodegrees(rads); if (angle > MinShake && angle < MaxShake && distance < 1) { return SWPosRetFail; } return SWPosRetFail; } SWPosStatus SWPosEqualToPos(SWPosPoint pos1,SWPosPoint pos2) { if (pos1.realPoint.x == pos2.realPoint.x && pos1.realPoint.y == pos2.realPoint.y) { return SWPosRetSuccess; } else { return SWPosRetFail; } } SWPosPoint SWPosPointMakeZero(void) { return SWPosPointMake(0, 0, 0); } SWPointcut ExPandLine(SWPointcut pt1,SWPointcut pt2,double nLen) { SWPointcut OutPt = SWPointCutMake(0, 0); if (pt1.x - pt2.x == 0) { OutPt.x = pt1.x; if (pt1.y - pt2.y > 0) { OutPt.y = pt2.y - nLen; } else { OutPt.y = pt2.y + nLen; } } else if (pt1.y - pt2.y == 0) { OutPt.y = pt1.y; if (pt1.x - pt2.x > 0) { OutPt.x = pt2.x - nLen; } else { OutPt.x = pt2.x + nLen; } } else { double k = 0.0; double b = 0.0; k = (pt1.y - pt2.y)/(pt1.x-pt2.x); b = pt1.y - k * pt1.x; double zoom = 0.0; zoom = nLen/sqrt((pt2.x-pt1.x)*(pt2.x-pt1.x)+(pt2.y-pt1.y)*(pt2.y-pt1.y)); if(k > 0) { if (pt1.x-pt2.x > 0) { OutPt.x = pt2.x - zoom * (pt1.x-pt2.x); OutPt.y = k*OutPt.x + b; } else { OutPt.x = pt2.x + zoom * (pt2.x-pt1.x); OutPt.y = k*OutPt.x + b; } } else { if (pt1.x-pt2.x > 0) { OutPt.x = pt2.x - zoom * (pt1.x-pt2.x) ; OutPt.y = k*OutPt.x + b; } else { OutPt.x = pt2.x + zoom * (pt2.x - pt1.x); OutPt.y = k*OutPt.x + b; } } } return OutPt; } SWCirclePoint SWCircleMake(SWPosPoint center) { double radian = 2*M_PI/4.f; double cosa = cos(radian); double sina = sin(radian); double h = center.radius*(4*(1 - cos(radian/2.f)))/(3*sin(radian/2.f)); SWPointcut pointA = SWPointCutMake(center.radius + center.realPoint.x, center.realPoint.y); SWPointcut pointB = SWPointCutMake(center.radius + center.realPoint.x, center.realPoint.y - h); SWPointcut pointC = SWPointCutMake(center.radius*cosa + h*sina + center.realPoint.x, center.realPoint.y - (center.radius*sina - h*cosa)); SWPointcut pointD = SWPointCutMake(center.realPoint.x,center.realPoint.y - center.radius); SWPointcut pointE = SWPointCutMake(center.realPoint.x - (center.radius*cosa + h*sina), pointC.y); SWPointcut pointF = SWPointCutMake(center.realPoint.x - center.radius, pointB.y); SWPointcut pointG = SWPointCutMake(center.realPoint.x - center.radius, center.realPoint.y); SWPointcut pointH = SWPointCutMake(pointF.x, center.realPoint.y + h); SWPointcut pointI = SWPointCutMake(pointE.x, center.realPoint.y + (center.radius*sina - h*cosa)); SWPointcut pointJ = SWPointCutMake(center.realPoint.x, center.realPoint.y + center.radius); SWPointcut pointK = SWPointCutMake(pointC.x, pointI.y); SWPointcut pointL = SWPointCutMake(pointB.x, pointH.y); SWPointcut pointM = SWPointCutMake(center.radius + center.realPoint.x, center.realPoint.y); SWCirclePoint cPoint = {pointA,pointB,pointC,pointD,pointE,pointF,pointG,pointH,pointI,pointJ,pointK,pointL,pointM}; return cPoint; }