/// <summary> /// 找出离给定点最近的线段 /// </summary> /// <param name="pos">指定点的坐标</param> /// <param name="sqrDistance">距离的平方</param> /// <returns>找到线段在列表中的索引值,或-1表示未找到</returns> private int FindNearestLine(XYGridPos pos, out float sqrDistance) { sqrDistance = float.MaxValue; int index = -1; for (int i = 0; i < list_.Count; ++i) { XYObstacleLine line = list_[i]; Vector2 v = new Vector2(line.End.x - line.Begin.x, line.End.y - line.Begin.y); Vector2 v2 = new Vector2(pos.x - line.Begin.x, pos.y - line.Begin.y); float t = Vector2.Dot(v, v2) / v.sqrMagnitude; if (t >= 0 && t <= 1) { Vector2 v3 = v * t; v3.x += line.Begin.x; v3.y += line.Begin.y; v3.x = pos.x - v3.x; v3.y = pos.y - v3.y; float dist = v3.sqrMagnitude; if (dist < sqrDistance) { sqrDistance = dist; index = i; } } } return(index); }
private int FindWithPos(XYGridPos pos) { for (int i = list_.Count - 1; i >= 0; --i) { XYObstacleLine line = list_[i]; if (line.Begin == pos || line.End == pos) { return(i); } if (0 == XYGridPos.RelativeCCW(line.Begin, line.End, pos)) { return(i); } } // 找离该点最近的线 float sqrDistance; int index = FindNearestLine(pos, out sqrDistance); if (index >= 0 && sqrDistance <= 1) { return(index); } else { return(-1); } }
public static XYObstacleLine Read(BinaryReader reader) { XYGridPos p1 = XYGridPos.Read(reader); XYGridPos p2 = XYGridPos.Read(reader); return(new XYObstacleLine(p1, p2)); }
public bool RemoveWithPos(XYGridPos pos, out XYObstacleLine line) { int index = FindWithPos(pos); if (index >= 0) { line = list_[index]; //计算奇数点 if (PointList.ContainsKey(line.Begin)) { PointList[line.Begin].RemoveBegin(); } if (PointList.ContainsKey(line.End)) { PointList[line.End].RemoveEnd(); } list_.RemoveAt(index); return(true); } else { Debug.LogWarning("remove 失败"); line = new XYObstacleLine(); return(false); } }
// 判断两线是否相交 private static bool LinesIntersect(XYGridPos p1, XYGridPos p2, XYGridPos p3, XYGridPos p4) { return( (XYGridPos.RelativeCCW(p1, p2, p3) * XYGridPos.RelativeCCW(p1, p2, p4) <= 0) && (XYGridPos.RelativeCCW(p3, p4, p1) * XYGridPos.RelativeCCW(p3, p4, p2) <= 0) ); }
public XYObstacleLine(XYGridPos begin, XYGridPos end) { if (begin == end) { throw new EInvalidLine(begin, end); } begin_ = begin; end_ = end; }
private static int GetPointIndex(List <XYGridPos> pointList, XYGridPos point) { int index = pointList.IndexOf(point); if (index >= 0) { return(index); } else { pointList.Add(point); return(pointList.Count - 1); } }
// 判断点是不是在线上(不包含端点) public bool IsPosInLineAndNotAtEndPoint(XYGridPos pos) { for (int i = 0; i < list_.Count; ++i) { XYObstacleLine line = list_[i]; if (line.Begin != pos && line.End != pos) { if (0 == XYGridPos.RelativeCCW(line.Begin, line.End, pos)) { return(true); } } } return(false); }
public override bool Equals(object obj) { if (obj == null) { return(false); } if (object.ReferenceEquals(this, obj)) { return(true); } if (this.GetType() != obj.GetType()) { return(false); } XYGridPos pos = (XYGridPos)obj; return(pos.x == x && pos.y == y); }
// 判断一个点是否在线内 public bool PosInLine(XYGridPos pos) { return(XYGridPos.RelativeCCW(begin_, end_, pos) == 0); }
public EInvalidLine(XYGridPos p1, XYGridPos p2) : base(string.Format("Invalid line (({0},{1}) - ({2},{3}))", p1.x, p1.y, p2.x, p2.y)) { }
//public static bool operator <(XYGridPos p1, XYGridPos p2) { // return (p1.x < p2.x) // || ((p1.x == p2.x) && (p1.y < p2.y)); //} //public static bool operator >(XYGridPos p1, XYGridPos p2) { // return (p1.x > p2.x) // || ((p1.x == p2.x) && (p1.y > p2.y)); //} //public static bool operator >=(XYGridPos p1, XYGridPos p2) { // return p1.x >= p2.x && p1.y >= p2.y; //} //public static bool operator <=(XYGridPos p1, XYGridPos p2) { // return p1.x <= p2.x && p1.y <= p2.y; //} public static int RelativeCCW(XYGridPos p1, XYGridPos p2, XYGridPos p3) { return(RelativeCCW(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y)); }