namespace IStation.Curve
|
{
|
/// <summary>
|
/// 直线辅助类
|
/// </summary>
|
public static class CurveLineHelper
|
{
|
/// <summary>
|
/// 是否垂直
|
/// </summary>
|
/// <param name="k"></param>
|
/// <returns></returns>
|
public static bool IsVerticalK(double k)
|
{
|
if (k >= _verticalK - 1)
|
return true;
|
else
|
return false;
|
}
|
private const double _verticalK = 100000000;//垂直时K的值
|
|
/// <summary>
|
/// 获取插值Y
|
/// </summary>
|
public static double GetInsertY(double x1, double y1, double x2, double y2, double x)
|
{
|
return new CurveLine(x1, y1, x2, y2).GetInsertY(x);
|
}
|
|
/// <summary>
|
/// 是否一个点向x轴的射线穿透线段,有交点且在线的左边
|
/// </summary>
|
public static bool IsIntersectLeft(CurvePoint pt1, CurvePoint pt2, CurvePoint pt)
|
{
|
return new CurveLine(pt1, pt2).IsIntersectLeft(pt);
|
}
|
|
/// <summary>
|
/// 是否一个点向x轴的射线穿透线段,有交点且在线的左边
|
/// </summary>
|
public static bool IsIntersectLeft(double x1, double y1, double x2, double y2, double x, double y)
|
{
|
return new CurveLine(x1, y1, x2, y2).IsIntersectLeft(new CurvePoint(x, y));
|
}
|
|
/// <summary>
|
/// X1和X2之间连一条线, 在比率ratio处点的坐标
|
/// </summary>
|
public static double GetInnerX(double x1, double x2, double ratio)
|
{
|
double x = x1 + ratio * (x2 - x1);
|
return x;
|
}
|
|
/// <summary>
|
/// X1,Y1和X2 Y2之间连一条线,在X处点的Y坐标
|
/// </summary>
|
public static double GetYbyX(double x1, double y1, double x2, double y2, double x)
|
{
|
return new CurveLine(x1, y1, x2, y2).GetYByX(x);
|
}
|
|
/// <summary>
|
/// X1,Y1和X2 Y2之间连一条线,在Y处点的X坐标
|
/// </summary>
|
public static double GetXbyY(double x1, double y1, double x2, double y2, double y)
|
{
|
return new CurveLine(x1, y1, x2, y2).GetXByY(y);
|
}
|
|
/// <summary>
|
/// 输入(X1,Y1),(X1,Y1)生成直线,返回直线的k和b y=kx+b
|
/// </summary>
|
public static bool GetKandB(double x1, double y1, double x2, double y2, out double k, out double b, double ignore = 0.000001)
|
{
|
return new CurveLine(x1, y1, x2, y2).GetKandB(out k, out b, ignore);
|
}
|
|
/// <summary>
|
/// 通过2点,得到通过这2点的直线的k,b 线的形式是 y=k*x+b,竖直返回false
|
/// </summary>
|
public static bool GetKandB(CurvePoint pt1, CurvePoint pt2, out double k, out double b, double ignore = 0.000001)
|
{
|
return new CurveLine(pt1, pt2).GetKandB(out k, out b, ignore);
|
}
|
|
/// <summary>
|
/// 取中间点
|
/// </summary>
|
public static CurvePoint GetMiddlePoint(CurvePoint pt1, CurvePoint pt2)
|
{
|
return new CurveLine(pt1, pt2).GetMiddlePoint();
|
}
|
|
/// <summary>
|
/// 取内部点
|
/// </summary>
|
public static CurvePoint GetInnerPoint(CurvePoint startPt, CurvePoint endPt, double ratio)
|
{
|
return new CurveLine(startPt, endPt).GetInnerPoint(ratio);
|
}
|
|
/// <summary>
|
/// 是否是内部点
|
/// </summary>
|
public static bool IsInnerByX(CurvePoint startPt, CurvePoint endPt, double x)
|
{
|
return new CurveLine(startPt, endPt).IsInnerByX(x);
|
}
|
|
/// <summary>
|
/// 三个点在同一条直线上,输入(X1,Y1),(X2,Y2)以及沿(X2,Y2)侧延长Length,得到的点(X3,Y3)
|
/// </summary>
|
public static CurvePoint GetExtendPoint(CurvePoint startPt, CurvePoint endPt, double length)
|
{
|
return new CurveLine(startPt, endPt).GetExtendPoint(length);
|
}
|
|
/// <summary>
|
/// 求直线外一点到该直线的投影点
|
/// </summary>
|
/// <param name="pl">线上任一点</param>
|
/// <param name="k">直线斜率</param>
|
/// <param name="pout">线外指定点</param>
|
public static CurvePoint GetProjectivePoint(CurvePoint pl, double k, CurvePoint pout)
|
{
|
CurvePoint pProject = new CurvePoint();
|
if (k == 0) //垂线斜率不存在情况
|
{
|
pProject.X = pout.X;
|
pProject.Y = pl.Y;
|
}
|
else
|
{
|
pProject.X = (float)((k * pl.X + pout.X / k + pout.Y - pl.Y) / (1 / k + k));
|
pProject.Y = (float)(-1 / k * (pProject.X - pout.X) + pout.Y);
|
}
|
return pProject;
|
}
|
|
/// <summary>
|
/// 求直线外一点到该直线的投影点
|
/// </summary>
|
/// <param name="pLine1"></param>
|
/// <param name="pLine2"></param>
|
/// <param name="pOut"></param>
|
/// <returns></returns>
|
public static CurvePoint GetProjectivePoint(CurvePoint pLine1, CurvePoint pLine2, CurvePoint pOut)
|
{
|
if (!GetKandB(pLine1, pLine2, out double k, out double b))
|
return default;
|
return GetProjectivePoint(pLine1, k, pOut);
|
}
|
|
/// <summary>
|
/// 点到线的距离, 注意不一定是垂直距离,点只在(line_start和line_end之间
|
/// </summary>
|
public static double Distance(CurvePoint line_start, CurvePoint line_end, CurvePoint point)
|
{
|
return new CurveLine(line_start, line_end).Distance(point);
|
}
|
|
/// <summary>
|
/// 计算交点(没有 就返回null)
|
/// </summary>
|
public static IStation.Curve.CurvePoint GetCrossPoint(IStation.Curve.CurvePoint startPt1, IStation.Curve.CurvePoint endPt1, IStation.Curve.CurvePoint startPt2, IStation.Curve.CurvePoint endPt2)
|
{
|
if (startPt1 == null || endPt1 == null)
|
return null;
|
if (startPt2 == null || endPt2 == null)
|
return null;
|
|
double k1, b1;
|
GetKandB(startPt1, endPt1, out k1, out b1);
|
|
double k2, b2;
|
GetKandB(startPt2, endPt2, out k2, out b2);
|
|
if (Math.Abs(k1 - k2) < 0.000001)
|
return null;
|
|
if (k1 == _verticalK)
|
{//垂直
|
return new IStation.Curve.CurvePoint(startPt1.X, startPt1.X * k2 + b2);
|
}
|
if (k2 == _verticalK)
|
{//垂直
|
return new IStation.Curve.CurvePoint(startPt2.X, startPt2.X * k1 + b1);
|
}
|
|
double sect_x = (b2 - b1) / (k1 - k2);
|
return new IStation.Curve.CurvePoint(sect_x, sect_x * k1 + b1);
|
}
|
|
|
/// <summary>
|
/// 是否平行
|
/// </summary>
|
/// <param name="startPt1"></param>
|
/// <param name="endPt1"></param>
|
/// <param name="startPt2"></param>
|
/// <param name="endPt2"></param>
|
/// <returns></returns>
|
public static bool IsParallel(IStation.Curve.CurvePoint startPt1, IStation.Curve.CurvePoint endPt1, IStation.Curve.CurvePoint startPt2, IStation.Curve.CurvePoint endPt2)
|
{
|
if (startPt1 == null || endPt1 == null)
|
return false;
|
if (startPt2 == null || endPt2 == null)
|
return false;
|
|
double k1, b1;
|
GetKandB(startPt1, endPt1, out k1, out b1);
|
|
double k2, b2;
|
GetKandB(startPt2, endPt2, out k2, out b2);
|
|
if (Math.Abs(k1 - k2) < 0.000001)
|
return true;
|
else
|
return false;
|
}
|
|
|
}
|
}
|