using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Runtime.Serialization;
|
|
|
namespace IStation.Model
|
{
|
/// <summary>
|
/// 曲线点
|
/// </summary>
|
[DataContract]
|
public partial class CurvePoint : ICloneable
|
{
|
#region 构造函数
|
|
public CurvePoint() { }
|
public CurvePoint(int x, int y)
|
{
|
this.X = x;
|
this.Y = y;
|
}
|
public CurvePoint(float x, float y)
|
{
|
this.X = x;
|
this.Y = y;
|
}
|
public CurvePoint(double x, double y)
|
{
|
this.X = x;
|
this.Y = y;
|
}
|
public CurvePoint(decimal x, decimal y)
|
{
|
this.X = Convert.ToDouble(x);
|
this.Y = Convert.ToDouble(y);
|
}
|
public CurvePoint(CurvePoint rhs)
|
{
|
this.X = rhs.X;
|
this.Y = rhs.Y;
|
}
|
public CurvePoint(System.Drawing.Point p) : this(p.X, p.Y) { }
|
public CurvePoint(System.Drawing.PointF p) : this(p.X, p.Y) { }
|
public CurvePoint(string strParas)
|
{
|
if (string.IsNullOrEmpty(strParas))
|
return;
|
var strParas_split_array = strParas.Split(new string[] { Separator1 }, StringSplitOptions.RemoveEmptyEntries);
|
if (strParas_split_array.Count() != 2)
|
return;
|
if (double.TryParse(strParas_split_array[0], out double x))
|
{
|
this.X = x;
|
}
|
if (double.TryParse(strParas_split_array[1], out double y))
|
{
|
this.Y = y;
|
}
|
}
|
|
public static CurvePoint ToParameter(string strParas)
|
{
|
if (string.IsNullOrEmpty(strParas))
|
return null;
|
var strParas_split_array = strParas.Split(new string[] { Separator1 }, StringSplitOptions.RemoveEmptyEntries);
|
if (strParas_split_array.Count() != 2)
|
return null;
|
CurvePoint pt = new CurvePoint();
|
if (double.TryParse(strParas_split_array[0], out double x))
|
{
|
pt.X = x;
|
}
|
else
|
{
|
return null;
|
}
|
if (double.TryParse(strParas_split_array[1], out double y))
|
{
|
pt.Y = y;
|
}
|
else
|
{
|
return null;
|
}
|
return pt;
|
}
|
#endregion
|
|
#region 静态
|
|
public const string Separator1 = ",";
|
public const string Separator2 = "|";
|
|
|
|
public const double Missing = double.MaxValue;
|
public const string Format = "N2";
|
|
#endregion
|
|
#region 属性
|
|
/// <summary>
|
/// X
|
/// </summary>
|
[DataMember]
|
public double X
|
{
|
get { return x; }
|
set { x = value; }
|
}
|
protected double x = Missing;
|
|
/// <summary>
|
/// Y
|
/// </summary>
|
[DataMember]
|
public double Y
|
{
|
get { return y; }
|
set { y = value; }
|
}
|
protected double y = Missing;
|
|
#endregion
|
|
/// <summary>
|
/// 转换为DS
|
/// </summary>
|
public string ToDsString()
|
{
|
return $"{this.X}{Separator1}{this.Y}";
|
}
|
|
/// <summary>
|
/// 偏置
|
/// </summary>
|
public CurvePoint Offset(double x, double y)
|
{
|
return new CurvePoint(this.X + x, this.Y + y);
|
}
|
|
/// <summary>
|
/// ToString
|
/// </summary>
|
public override string ToString()
|
{
|
return $"X:{this.X}{Separator1}Y:{this.Y}";
|
}
|
|
/// <summary>
|
/// ToString
|
/// </summary>
|
public string ToString(string format)
|
{
|
return $"X:{this.X.ToString(format)}{Separator1}Y:{this.Y.ToString(format)}";
|
}
|
|
/// <summary>
|
/// ToString
|
/// </summary>
|
public string ToString(string formatx, string formaty)
|
{
|
return $"X:{this.X.ToString(formatx)}{Separator1}Y:{this.Y.ToString(formaty)}";
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public bool IsMissing()
|
{
|
return this.X == Missing || this.Y == Missing;
|
}
|
|
/// <summary>
|
/// 是否无效
|
/// </summary>
|
public bool IsInvalid()
|
{
|
return this.X == Missing ||
|
this.Y == Missing ||
|
double.IsInfinity(this.X) ||
|
double.IsInfinity(this.Y) ||
|
double.IsNaN(this.X) ||
|
double.IsNaN(this.Y);
|
}
|
//判断是否是0点,用于判断函数是否成功返回
|
internal static bool IsZeroPt(CurvePoint pt)
|
{
|
if (Math.Abs(pt.X) < 0.0001 && Math.Abs(pt.Y) < 0.0001)
|
return true;
|
else
|
return false;
|
|
}
|
/// <summary>
|
///
|
/// </summary>
|
public bool IsZeroPt()
|
{
|
if ((Math.Abs(x) < 0.0001) && (Math.Abs(y) < 0.0001))
|
return true;
|
else
|
return false;
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public static CurvePoint ToModel(string strParas)
|
{
|
return new CurvePoint(strParas);
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public CurvePoint Copy()
|
{
|
return new CurvePoint(this);
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public static CurvePoint Copy(CurvePoint pt)
|
{
|
if (pt == null)
|
return null;
|
return new CurvePoint(pt);
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public static List<CurvePoint> Copy(IEnumerable<CurvePoint> src_list)
|
{
|
if (src_list == null)
|
return null;
|
var list = new List<CurvePoint>();
|
foreach (var pt in src_list)
|
{
|
list.Add(new CurvePoint(pt));
|
}
|
|
return list;
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public static bool IsValueInvalid(double value)
|
{
|
return (value == Missing ||
|
double.IsInfinity(value) ||
|
double.IsNaN(value));
|
}
|
|
/// <summary>
|
/// 距离
|
/// </summary>
|
public double Distance(CurvePoint pt)
|
{
|
if (pt == null)
|
return double.MaxValue;
|
return Math.Sqrt((pt.X - this.X) * (pt.X - this.X) + (pt.Y - this.Y) * (pt.Y - this.Y));
|
}
|
|
/// <summary>
|
/// 距离
|
/// </summary>
|
public double Distance(IEnumerable<CurvePoint> list)
|
{
|
if (list == null || list.Count() < 1)
|
return double.MaxValue;
|
|
return list.Select(x => this.Distance(x)).Min();
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public static string ToDsString(IEnumerable<CurvePoint> src_list)
|
{
|
if (src_list == null || src_list.Count() < 1)
|
return default;
|
var str_list = src_list.Select(x => x.ToDsString());
|
return string.Join(Separator2, str_list);
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public static List<CurvePoint> ToList(string strParas)
|
{
|
if (string.IsNullOrEmpty(strParas))
|
return default;
|
var str_list = strParas.Split(new string[] { Separator2 }, StringSplitOptions.RemoveEmptyEntries);
|
List<CurvePoint> points = new List<CurvePoint>(str_list.Count());
|
foreach (var s in str_list)
|
{
|
var pt = IStation.Model.CurvePoint.ToParameter(s);
|
if (pt != null)
|
points.Add(pt);
|
}
|
return points;
|
}
|
public static List<CurvePoint> ToList(string strParas, string[] endChar)
|
{
|
if (string.IsNullOrEmpty(strParas))
|
return default;
|
if (endChar == null || endChar.Length == 0)
|
return ToList(strParas);
|
var str_list = strParas.Split(new string[] { Separator2 }, StringSplitOptions.RemoveEmptyEntries);
|
List<CurvePoint> points = new List<CurvePoint>(str_list.Count());
|
foreach (var s in str_list)
|
{
|
if (endChar.Contains(s))
|
break;
|
var pt = IStation.Model.CurvePoint.ToParameter(s);
|
if (pt != null)
|
points.Add(pt);
|
}
|
return points;
|
}
|
/// <summary>
|
/// 是否向x轴的射线穿透线段,有交点且在线的左边
|
/// </summary>
|
public bool IsIntersectLineLeft(CurvePoint p1, CurvePoint p2)
|
{
|
if (p1 == null || p2 == null)
|
return default;
|
double y_max = p1.y > p2.y ? p1.y : p2.y;
|
double y_min = p1.y > p2.y ? p2.y : p1.y;
|
|
if (Math.Abs(p1.y - p2.y) < 0.0001)
|
{
|
if (Math.Abs(y - p1.y) < 0.0001)
|
return true;
|
else
|
return false;
|
}
|
|
bool isLeft = false;
|
if (y < y_max && y >= y_min)
|
{
|
if (x <= (p1.x + (p2.x - p1.x) * (y - p1.y) / (p2.y - p1.y)))
|
{
|
isLeft = true;
|
}
|
}
|
return isLeft;
|
}
|
|
|
|
#region Clone
|
public CurvePoint Clone()
|
{
|
return new CurvePoint(x, y);
|
}
|
object ICloneable.Clone()
|
{
|
return this.Clone();
|
}
|
|
#endregion
|
|
#region Equals
|
public override int GetHashCode()
|
{
|
return base.GetHashCode();
|
}
|
public override bool Equals(object obj)
|
{
|
var rhs = obj as CurvePoint;
|
if (rhs == null)
|
return default;
|
return this.X == rhs.X && this.Y == rhs.Y;
|
}
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|