using Newtonsoft.Json; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Misc { /// <summary> /// double范围类, /// </summary> public class RangeF : INotifyPropertyChanged { #region property /// <summary> /// 开始 /// </summary> public double Begin { get; set; } /// <summary> /// 结束 /// </summary> public double End { get; set; } #endregion #region just get property /// <summary> /// 本范围 中心位置 /// </summary> [JsonIgnore] public double Mid { get { if (IsValid) return (End + Begin) / 2; else return double.NaN; } } /// <summary> /// 本范围宽度 /// </summary> [JsonIgnore] public double Width { get { if (IsValid) return End - Begin; else return double.NaN; } } /// <summary> /// 是否有效 /// </summary> [JsonIgnore] public bool IsValid { get { if (!double.IsNaN(Begin) && !double.IsNaN(End)) return true; else return false; } } #endregion /// <summary> /// 使用无效值初始化 /// </summary> public RangeF() { Reset(); } #region methods /// <summary> /// 范围 r 在 本范围内 /// </summary> /// <param name="r"></param> /// <returns></returns> public bool Contain(RangeF r) { if ((Begin <= r.Begin) && (r.End <= End)) return true; else return false; } /// <summary> /// 点 p 在 本范围内 /// </summary> /// <param name="p"></param> /// <returns></returns> public bool Contain(double p) { if ((Begin <= p) && (p <= End)) return true; else return false; } /// <summary> /// 平移 /// </summary> /// <param name="offset"></param> public void Move(double offset) { Begin += offset; End += offset; } /// <summary> /// 复位为无效 /// </summary> public void Reset() { Begin = double.NaN; End = double.NaN; } /// <summary> /// 范围并集 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static RangeF operator |(RangeF a, RangeF b) { return new RangeF() { Begin = (a.Begin < b.Begin) ? a.Begin : b.Begin, End = (a.End > b.End) ? a.End : b.End }; } /// <summary> /// 范围交集 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static RangeF operator &(RangeF a, RangeF b) { RangeF r = new RangeF() { Begin = (a.Begin > b.Begin) ? a.Begin : b.Begin, End = (a.End < b.End) ? a.End : b.End }; if (r.End < r.Begin) { return new RangeF(); } else { return r; } } /// <summary> /// 范围 a小于b /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool operator <(RangeF a, RangeF b) { if (a.End < b.Begin)//[a.b,a.e] [b.b,b.e] { return true; } else { return false; } } /// <summary> /// 范围 a大于b /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static bool operator >(RangeF a, RangeF b) { if (b.End < (a.Begin))// [b.b,b.e][a.b,a.e] { return true; } else { return false; } } public static bool operator <(double p, RangeF r) { if (p < r.Begin) { return true; } else { return false; } } public static bool operator >(double p, RangeF r) { if (p > r.End) { return true; } else { return false; } } public static bool operator <(RangeF r, double p) { if (r.End < p) { return true; } else { return false; } } public static bool operator >(RangeF r, double p) { if (r.Begin > p) { return true; } else { return false; } } /// <summary> /// 是否有交集 /// </summary> /// <param name="r"></param> /// <returns></returns> public bool HasIntersection(RangeF r) { if (Contain(r.Begin)) return true; if (Contain(r.End)) return true; if (r.Contain(Begin)) return true; if (r.Contain(End)) return true; return false; } /// <summary> /// 可以合并 /// </summary> /// <returns></returns> public bool CanUnion(RangeF r) { if (HasIntersection(r)) return true; if (End == (r.Begin - 1)) return true; if (Begin == (r.End + 1)) return true; return false; } /// <summary> /// 复制 r 的值到 本范围内 /// </summary> /// <param name="r"></param> public void Copy(RangeF r) { Begin = r.Begin; End = r.End; } /// <summary> /// 克隆 /// </summary> /// <returns></returns> public RangeF Clone() { RangeF r = new RangeF(); r.Copy(this); return r; } #endregion /// <summary> /// /// </summary> /// <returns></returns> public override string ToString() { return "[" + Begin.ToString() + "," + End.ToString() + "]=" + Width.ToString(); } #region INotifyPropertyChanged 成员 public event PropertyChangedEventHandler PropertyChanged; #endregion } /// <summary> /// Range 比较器 /// </summary> public class RangeFEqualityComparer : IEqualityComparer<RangeF> { /// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public bool Equals(RangeF x, RangeF y) { if ((x.Begin == y.Begin) && (x.End == y.End)) { return true; } else return false; } /// <summary> /// /// </summary> /// <param name="obj"></param> /// <returns></returns> public int GetHashCode(RangeF obj) { int hashCode = obj.Begin.GetHashCode(); int hashCode2 = obj.End.GetHashCode(); if (hashCode != hashCode2) { hashCode ^= hashCode2; } return hashCode; } } /// <summary> /// RangeF 辅助类 /// </summary> public static class EListRangeF { /// <summary> /// rlist 必须是由小到大排列 /// </summary> /// <param name="rlist"></param> /// <param name="r"></param> public static void Union(this List<RangeF> rlist, RangeF r) { for (int i = 0; i < rlist.Count(); i++) { RangeF r_dest = rlist[i]; if (r < r_dest)//在 r_dest 前面 { rlist.Insert(i, r); return;//完成 } else if (r.CanUnion(r_dest)) //r 与 r_dest 有交集 { //r 与 r_dest 合体 r = r | r_dest; rlist.RemoveAt(i); i--; //还需要继续判断 } } //r 在 rlist 的后面 rlist.Add(r); } /// <summary> /// 联合 /// </summary> /// <param name="rlist1"></param> /// <param name="rlist2"></param> public static void Union(this List<RangeF> rlist1, List<RangeF> rlist2) { for (int i = 0; i < rlist2.Count(); i++) { rlist1.Union(rlist2[i]); } } } }