You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

797 lines
25 KiB

//
// SWPosPointcut.c
// DrawTest
//
// Created by 王阳阳 on 2022/9/6.
//
#include "SWPosPointcut.h"
#include <QDebug>
#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);
}
/**
* 00
*/
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<SWCirclePoint> 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<SWPosPoint> 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<SWPosPoint> 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;
}