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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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