int FindStaircaseStart(Point[] pts, out bool canHaveStaircase) { canHaveStaircase = false; if (pts.Length < 5) // At least five points make a staircase return -1; var segs = new[] { new SegWithIndex(pts, 0), new SegWithIndex(pts, 1), new SegWithIndex(pts, 2), new SegWithIndex(pts, 3) }; int segToReplace = 0; for (int i = 0;;) { bool canHaveStaircaseAtI; if (IsStaircase(pts, i, segs, out canHaveStaircaseAtI)) { canHaveStaircase = true; return i; } canHaveStaircase = canHaveStaircase || canHaveStaircaseAtI; i++; if (pts.Length < i + 5)// At least five points make a staircase return -1; segs[segToReplace] = new SegWithIndex(pts, i + 3); segToReplace += 1; segToReplace %= 4; } }
int FindStaircaseStart(Point[] pts, out bool canHaveStaircase) { canHaveStaircase = false; if (pts.Length < 5) // At least five points make a staircase { return(-1); } var segs = new[] { new SegWithIndex(pts, 0), new SegWithIndex(pts, 1), new SegWithIndex(pts, 2), new SegWithIndex(pts, 3) }; int segToReplace = 0; for (int i = 0;;) { bool canHaveStaircaseAtI; if (IsStaircase(pts, i, segs, out canHaveStaircaseAtI)) { canHaveStaircase = true; return(i); } canHaveStaircase = canHaveStaircase || canHaveStaircaseAtI; i++; if (pts.Length < i + 5)// At least five points make a staircase { return(-1); } segs[segToReplace] = new SegWithIndex(pts, i + 3); segToReplace += 1; segToReplace %= 4; } }
/// <summary> /// ignoring crossing at a /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="segsToIgnore"></param> /// <returns></returns> bool Crossing(Point a, Point b, SegWithIndex[] segsToIgnore) { return IsCrossing(new LineSegment(a, b), segTree, segsToIgnore); }
static Rectangle Rect(SegWithIndex seg) { return new Rectangle(seg.Start,seg.End); }
void InsSeg(Point[] pts, int i) { var seg = new SegWithIndex(pts, i); segTree.Add(Rect(seg), seg); }
void RemoveSeg(SegWithIndex seg) { segTree.Remove(Rect(seg), seg); }
bool IsStaircase(Point[] pts, int offset, SegWithIndex[] segsToIgnore, out bool canHaveStaircaseAtI) { var a = pts[offset]; var b = pts[offset + 1]; var c = pts[offset + 2]; var d = pts[offset + 3]; var f = pts[offset + 4]; canHaveStaircaseAtI = false; if (CompassVector.DirectionsFromPointToPoint(a, b) != CompassVector.DirectionsFromPointToPoint(c, d) || CompassVector.DirectionsFromPointToPoint(b, c) != CompassVector.DirectionsFromPointToPoint(d, f)) return false; c = GetFlippedPoint(pts, offset); if (IntersectObstacleHierarchy(b, c, d)) return false; canHaveStaircaseAtI = true; return !Crossing(b, c, segsToIgnore); }
/// <summary> /// ignoring crossing at ls.Start /// </summary> /// <param name="ls"></param> /// <param name="rTree"></param> /// <param name="segsToIgnore"></param> /// <returns></returns> static bool IsCrossing(LineSegment ls, RTree<SegWithIndex> rTree, SegWithIndex[] segsToIgnore) { return rTree.GetAllIntersecting(ls.BoundingBox).Where(seg => !segsToIgnore.Contains(seg)).Any(); }
static Rectangle Rect(SegWithIndex seg) { return(new Rectangle(seg.Start, seg.End)); }