static IEnumerable <Point> GetPointsInBetween(LinkedPoint a, LinkedPoint b) { for (var i = a.Next; i != b; i = i.Next) { yield return(i.Point); } }
static void TrySplitVerticalPoint(LinkedPoint linkedPoint, Point point) { Debug.Assert(ApproximateComparer.Close(linkedPoint.X, linkedPoint.Next.X)); if (Low(linkedPoint) + ApproximateComparer.DistanceEpsilon < point.Y && point.Y + ApproximateComparer.DistanceEpsilon < High(linkedPoint)) { linkedPoint.SetNewNext(point); } }
internal void SetNewNext(Point p) { var nv = new LinkedPoint(p); var tmp = Next; Next = nv; nv.Next = tmp; Debug.Assert(CompassVector.IsPureDirection(Point, Next.Point)); }
void CleanDisappearedPiece(LinkedPoint a, LinkedPoint b, Path loopingPath) { foreach (var point in GetPointsInBetween(a, b)) { var pathOffset = verticesToPathOffsets[point]; Debug.Assert(pathOffset.ContainsKey(loopingPath)); pathOffset.Remove(loopingPath); } }
/// <summary> /// checks that a is before b in the path /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns>true is a is before b in the path</returns> static bool Before(LinkedPoint a, LinkedPoint b) { for (a = a.Next; a != null; a = a.Next) { if (a == b) { return(true); } } return(false); }
static LinkedPoint TrySplitHorizontalPoint(LinkedPoint horizontalPoint, Point point, bool xAligned) { Debug.Assert(ApproximateComparer.Close(horizontalPoint.Y, horizontalPoint.Next.Y)); if (xAligned && horizontalPoint.X + ApproximateComparer.DistanceEpsilon < point.X && point.X + ApproximateComparer.DistanceEpsilon < horizontalPoint.Next.X || !xAligned && horizontalPoint.Next.X + ApproximateComparer.DistanceEpsilon < point.X && point.X + ApproximateComparer.DistanceEpsilon < horizontalPoint.X) { horizontalPoint.SetNewNext(point); return(horizontalPoint.Next); } return(horizontalPoint); }
void ReplacePiece(LinkedPoint a, LinkedPoint b, IEnumerable <Point> points, Path loopingPath) { var prevPoint = a; foreach (var point in points) { var lp = new LinkedPoint(point); prevPoint.Next = lp; prevPoint = lp; var pathOffset = verticesToPathOffsets[point]; Debug.Assert(!pathOffset.ContainsKey(loopingPath)); pathOffset[loopingPath] = prevPoint; } prevPoint.Next = b; }
// bool Correct() { // foreach (var kv in verticesToPathOffsets) { // Point p = kv.Key; // Dictionary<Path, LinkedPoint> pathOffs = kv.Value; // foreach (var pathOff in pathOffs) { // var path = pathOff.Key; // var linkedPoint = pathOff.Value; // if (linkedPoint.Point != p) // return false; // if (FindLinkedPointInPath(path, p) == null) { // return false; // } // } // } // return true; // } void CollapseLoopingPath(Path loopingPath, LinkedPoint departureFromLooping, LinkedPoint arrivalToLooping, Path stemPath, LinkedPoint arrivalToStem) { var departurePointOnStem = FindLinkedPointInPath(stemPath, departureFromLooping.Point); IEnumerable <Point> pointsToInsert = GetPointsInBetween(departurePointOnStem, arrivalToStem); if (Before(departureFromLooping, arrivalToLooping)) { CleanDisappearedPiece(departureFromLooping, arrivalToLooping, loopingPath); ReplacePiece(departureFromLooping, arrivalToLooping, pointsToInsert, loopingPath); } else { CleanDisappearedPiece(arrivalToLooping, departureFromLooping, loopingPath); ReplacePiece(arrivalToLooping, departureFromLooping, pointsToInsert.Reverse(), loopingPath); } }
void ProcessEvent(LinkedPoint linkedPoint, double z) { if (ApproximateComparer.Close(linkedPoint.Next.Point.X, linkedPoint.Point.X)) { if (z == Low(linkedPoint)) { ProcessLowLinkedPointEvent(linkedPoint); } else { ProcessHighLinkedPointEvent(linkedPoint); } } else { IntersectWithTree(linkedPoint); } }
void IntersectWithTree(LinkedPoint horizontalPoint) { double left, right; bool xAligned; Debug.Assert(ApproximateComparer.Close(horizontalPoint.Y, horizontalPoint.Next.Y)); var y = horizontalPoint.Y; if (horizontalPoint.Point.X < horizontalPoint.Next.Point.X) { left = horizontalPoint.Point.X; right = horizontalPoint.Next.Point.X; xAligned = true; } else { right = horizontalPoint.Point.X; left = horizontalPoint.Next.Point.X; xAligned = false; } if (xAligned) { for (var node = tree.FindFirst(p => left <= p.Point.X); node != null && node.Item.Point.X <= right; node = tree.Next(node)) { var p = new Point(node.Item.Point.X, y); horizontalPoint = TrySplitHorizontalPoint(horizontalPoint, p, true); TrySplitVerticalPoint(node.Item, p); } } else //xAligned==false { for (var node = tree.FindLast(p => p.Point.X <= right); node != null && node.Item.Point.X >= left; node = tree.Previous(node)) { var p = new Point(node.Item.Point.X, y); horizontalPoint = TrySplitHorizontalPoint(horizontalPoint, p, false); TrySplitVerticalPoint(node.Item, p); } } }
static double High(LinkedPoint vertPoint) { return(Math.Max(vertPoint.Point.Y, vertPoint.Next.Point.Y)); }
static double Low(LinkedPoint vertPoint) { return(Math.Min(vertPoint.Point.Y, vertPoint.Next.Point.Y)); }
void ProcessLowLinkedPointEvent(LinkedPoint linkedPoint) { tree.Insert(linkedPoint); }
void ProcessHighLinkedPointEvent(LinkedPoint linkedPoint) { tree.Remove(linkedPoint); }