static public bool Checkfloat(float f1, float f2, float span = 1)
{
float fspan = Math.Abs(f1 - f2);
if (fspan <= span)
{
return true;
}
return false;
}
///
/// 计算直线的长度
///
/// 直线起点
/// 直线终点
///
static public double GetLineLength(PointF startPt, PointF endPt)
{
double distance = 0;
if (startPt != null && endPt != null && startPt != endPt)
{
distance = (double)Math.Pow((Math.Pow((endPt.X - startPt.X), 2) + Math.Pow((endPt.Y - startPt.Y), 2)), 1.0 / 2);
}
return distance;
}
///
/// 求线段夹角和交点
///
/// 直线1的起点
/// 直线1的终点
/// 直线2的起点
/// 直线2的终点
/// 线段是否延伸(true)
/// 线段交点
///
static public float Caltwolineangle(PointF line1startpt, PointF line1endpt, PointF line2startpt, PointF line2endpt, bool extend, ref PointF CrossPt)
{
bool flag = true;
if (line1startpt == null || line1endpt == null || line2startpt == null || line2endpt == null)
{
return 0.0f;
}
float fangle = Get2LineAngle(line1startpt, line1endpt, line2startpt, line2endpt);
Get2LineCrossPt(line1startpt, line1endpt, line2startpt, line2endpt, flag, ref CrossPt);
return fangle;
}
///
/// 两条带方向直线夹角求取,范围[0,180],同向为0
///
/// 直线1的起点
/// 直线1的终点
/// 直线2的起点
/// 直线2的终点
///
static public float Get2LineAngle(PointF line1startpt, PointF line1endpt, PointF line2startpt, PointF line2endpt)
{
double fangle = 0.0f;
double angle1 = 0.0f;
double angle2 = 0.0f;
if (line1startpt == null || line1endpt == null || line2startpt == null || line2endpt == null)
{
return 0.0f;
}
angle1 = GetLineAngle(line1startpt, line1endpt);
angle2 = GetLineAngle(line2startpt, line2endpt);
if (Math.Abs(angle1 - angle2) > Math.PI)
{
fangle = 2 * Math.PI - Math.Abs(angle1 - angle2);
}
else
{
fangle = Math.Abs(angle1 - angle2);
}
return (float)fangle;
}
///
/// 获取直线相对于X轴角度[0-360)
///
/// 直线起点
/// 直线终点
///
static public float GetLineAngle(PointF startPt, PointF endPt)
{
double angle = 0;
if (startPt == null || endPt == null)
{
return 0.0f;
}
if (Checkfloat(endPt.X, startPt.X))
{
if (endPt.Y > startPt.Y)
{
angle = 3 * Math.PI / 2;
}
else
{
angle = Math.PI / 2;
}
}
else if (endPt.X > startPt.X)
{
double k2 = (endPt.Y - startPt.Y) / (endPt.X - startPt.X);
angle = -Math.Atan(k2);
if (angle < 0)
{
angle += 2 * Math.PI;
}
}
else
{
float k2 = (endPt.Y - startPt.Y) / (endPt.X - startPt.X);
angle = -Math.Atan(k2);
angle += Math.PI;
}
return (float)angle;
}
///
/// 两条直线交点的求取,直线平行返回false
///
/// 直线1的起点
/// 直线1的终点
/// 直线2的起点
/// 直线2的终点
/// 直线交点
///
static public bool Get2LineCrossPt(PointF line1startpt, PointF line1endpt, PointF line2startpt, PointF line2endpt, bool extend, ref PointF CrossPt)
{
CrossPt = new PointF(0, 0);
if (line1startpt == null || line1endpt == null || line2startpt == null || line2endpt == null)
{
return false;
}
if ((line1endpt.X != line1startpt.X) || (line2endpt.X != line2startpt.X))
{
if ((line1endpt.X == line1startpt.X) && (line2endpt.X != line2startpt.X))
{
float k2 = (line2endpt.Y - line2startpt.Y) / (line2endpt.X - line2startpt.X);
CrossPt.X = line1startpt.X;
CrossPt.Y = k2 * CrossPt.X - k2 * line2startpt.X + line2startpt.Y;
}
else if ((line1endpt.X != line1startpt.X) && (line2endpt.X == line2startpt.X))
{
float k1 = (line1endpt.Y - line1startpt.Y) / (line1endpt.X - line1startpt.X);
CrossPt.X = line2startpt.X;
CrossPt.Y = k1 * CrossPt.X - k1 * line1startpt.X + line1startpt.Y;
}
else
{
float k1 = (line1endpt.Y - line1startpt.Y) / (line1endpt.X - line1startpt.X);
float k2 = (line2endpt.Y - line2startpt.Y) / (line2endpt.X - line2startpt.X);
if (k1 == k2)
{
return false;
}
CrossPt.X = (k1 * line1startpt.X - k2 * line2startpt.X - line1startpt.Y + line2startpt.Y) / (k1 - k2);
CrossPt.Y = k1 * CrossPt.X - k1 * line1startpt.X + line1startpt.Y;
}
//两直线不扩展
#region
if (extend != true)
{
float a1 = Math.Abs(GetLineAngle(line1endpt, CrossPt) - GetLineAngle(CrossPt, line1startpt));
float a2 = Math.Abs(GetLineAngle(line2endpt, CrossPt) - GetLineAngle(CrossPt, line2startpt));
if (a1 < 1E-3 && a2 < 1E-3)
{
return true;
}
else
{
return false;
}
}
#endregion
//直线扩展
#region
else
{
return true;
}
#endregion
}
else
{
return false;
}
}
///
/// 点到直线距离
///
/// 直线起点
/// 直线终点
/// 任意点
///
static public float GetLengthPtToLine(PointF startPt, PointF endPt, PointF Pt)
{
double length = 0;
//点在直线上
if (startPt == null || endPt == null || Pt == null)
{
return 0.0f;
}
#region
if (Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) < 1E-3 || Math.Abs(Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) - Math.PI) < 1E-3)
{
}
#endregion
//点在直线外
#region
else
{
double a = GetLineLength(startPt, Pt);
double b = GetLineLength(endPt, Pt);
double c = GetLineLength(startPt, endPt);
double p = (a + b + c) / 2;
if (c == 0)
{
return 0;
}
length = (double)Math.Pow(p * (p - a) * (p - b) * (p - c), 1.0 / 2) * 2 / c;
}
#endregion
return (float)length;
}
///
/// 点到线段最近的点
///
/// 直线起点
/// 直线终点
/// 任意点
/// 线段是否延伸
///
static public PointF GetClosePt(PointF startPt, PointF endPt, PointF Pt, bool extend)
{
PointF NearPt = new PointF();
//点在直线上(线段内部)
if (startPt == null || endPt == null || Pt == null)
{
return NearPt;
}
#region
if (Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) < 1E-3)
{
NearPt = Pt;
}
#endregion
//点在直线上(线段外部)
#region
else if (Math.Abs(Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) - Math.PI) < 1E-3)
{
if (GetLineLength(endPt, Pt) < GetLineLength(startPt, Pt))
{
if (extend == true)
{
NearPt = Pt;
}
else
{
NearPt = endPt;
}
}
else
{
if (extend == true)
{
NearPt = Pt;
}
else
{
NearPt = startPt;
}
}
}
#endregion
//点不在直线上
#region
else
{
//计算垂足
#region
float spanx = endPt.X - startPt.X;
float spany = endPt.Y - startPt.Y;
if (spanx <= 1 && spanx >= -1)
{
endPt.X = startPt.X;
}
if (spany <= 1 && spany >= -1)
{
endPt.Y = startPt.Y;
}
if (endPt.X != startPt.X)
{
if (endPt.Y != startPt.Y)
{
double k1 = (endPt.Y - startPt.Y) / (endPt.X - startPt.X);
double k2 = -1 / k1;
NearPt.X = (float)((Pt.Y - startPt.Y - k2 * Pt.X + k1 * startPt.X) / (k1 - k2));
NearPt.Y = (float)(k2 * NearPt.X + Pt.Y - k2 * Pt.X);
}
else
{
NearPt.X = Pt.X;
NearPt.Y = endPt.Y;
}
}
else
{
NearPt.X = endPt.X;
NearPt.Y = Pt.Y;
}
#endregion
//垂足不在线段内,最近点为端点,延伸后是垂足
#region
if (Math.Abs(GetLineAngle(endPt, NearPt) - GetLineAngle(NearPt, startPt)) < 1E-3)
{
}
else
{
if (extend == false)
{
if (GetLineLength(endPt, NearPt) < GetLineLength(startPt, NearPt))
{
NearPt = endPt;
}
else
{
NearPt = startPt;
}
}
}
#endregion
}
#endregion
return NearPt;
}
///
/// 点到线段最近的点,并返回长度
///
/// 直线起点
/// 直线终点
/// 任意点
/// 线段是否延伸
/// 返回长度
///
static public PointF GetClosePt(PointF startPt, PointF endPt, PointF Pt, bool extend, ref float distance)
{
PointF NearPt = new PointF();
if (startPt == null || endPt == null || Pt == null)
{
return NearPt;
}
//点在直线上(线段内部)
#region
if (Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) < 1E-3)
{
NearPt = Pt;
}
#endregion
//点在直线上(线段外部)
#region
else if (Math.Abs(Math.Abs(GetLineAngle(endPt, Pt) - GetLineAngle(Pt, startPt)) - Math.PI) < 1E-3)
{
if (GetLineLength(endPt, Pt) < GetLineLength(startPt, Pt))
{
if (extend == true)
{
NearPt = Pt;
}
else
{
NearPt = endPt;
}
}
else
{
if (extend == true)
{
NearPt = Pt;
}
else
{
NearPt = startPt;
}
}
}
#endregion
//点不在直线上
#region
else
{
//计算垂足
#region
float spanx = endPt.X - startPt.X;
float spany = endPt.Y - startPt.Y;
if (spanx <= 1 && spanx >= -1)
{
endPt.X = startPt.X;
}
if (spany <= 1 && spany >= -1)
{
endPt.Y = startPt.Y;
}
if (endPt.X != startPt.X)
{
if (endPt.Y != startPt.Y)
{
double k1 = (endPt.Y - startPt.Y) / (endPt.X - startPt.X);
double k2 = -1 / k1;
NearPt.X = (float)((Pt.Y - startPt.Y - k2 * Pt.X + k1 * startPt.X) / (k1 - k2));
NearPt.Y = (float)(k2 * NearPt.X + Pt.Y - k2 * Pt.X);
}
else
{
NearPt.X = Pt.X;
NearPt.Y = endPt.Y;
}
}
else
{
NearPt.X = endPt.X;
NearPt.Y = Pt.Y;
}
#endregion
//垂足不在线段内,最近点为端点,延伸后是垂足
#region
if (Math.Abs(GetLineAngle(endPt, NearPt) - GetLineAngle(NearPt, startPt)) < 1E-3)
{
}
else
{
if (extend == false)
{
if (GetLineLength(endPt, NearPt) < GetLineLength(startPt, NearPt))
{
NearPt = endPt;
}
else
{
NearPt = startPt;
}
}
}
#endregion
}
#endregion
distance = (float)GetLineLength(NearPt, Pt);
return NearPt;
}
///
/// 获取两个点的中心点
///
/// 开始点
/// 种植点
/// 返回点
public static PointF GetPointCenter(PointF star, PointF end)
{
return new PointF((star.X + end.X) / 2, (star.Y + end.Y) / 2);
}
///
/// 得到两个点的中间点坐标
///
///
///
///
public static PointF Get2PointCenter(PointF one, PointF two)
{
PointF centerPT = new PointF();
if (one != null && two != null)
{
centerPT = new PointF((one.X + two.X) / 2, (one.Y + two.Y) / 2);
}
return centerPT;
}
///
/// 已知一条直线,一个长度,求距离开始点长度的,直线上的坐标
///
///
///
///
///
public static PointF Get_PointMovePoint(PointF startPT, PointF endPT, double length)
{
var ang =GetLineAngle(startPT, endPT);
var a = length * Math.Cos(ang);
var b = -length * Math.Sin(ang);
var newPT = new PointF((Single)(startPT.X + a), (Single)(startPT.Y + b));
return newPT;
}
public static float GetMin(float x, float y)
{
if (x < y)
return x;
else
return y;
}
public static float GetMax(float x, float y)
{
if (x > y)
return x;
else
return y;
}
///
/// 判断点是否在线段上
///
///
///
///
///
public static bool Get_PointInLine(PointF P1, PointF P2, PointF Q)
{
var k1 = (Q.X - P1.X) * (P2.Y - P1.Y);
var k2 = (P2.X - P1.X) * (Q.Y - P1.Y);
if ((int)(k1 / 10) == (int)(k2 / 10))
{
if ((GetMin(P1.X, P2.X) <= Q.X && Q.X <= GetMax(P1.X, P2.X)) && GetMin(P1.Y, P2.Y) <= Q.Y && Q.Y <= GetMax(P1.Y, P2.Y))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
///
/// PointF转化为Point
///
///
///
public static List<Point> PointFToPoint(List<PointF> pths)
{
List<Point> ps = new List<Point>();
foreach (var item in pths)
{
ps.Add(new Point((int)item.X, (int)item.Y));
}
return ps;
}
///
/// 检测点是否在一定范围内
///
///
///
///
public static bool TestPointInGraph(List<PointF> allpt, PointF needpt)
{
var pts = PointFToPoint(allpt);
pts.Add(pts[0]);
using (GraphicsPath path = new GraphicsPath())
{
path.AddLines(pts.ToArray());
Region reg = new Region(path);
if (reg.IsVisible(needpt))
{
return true;
}
}
return false;
}