void ComputeVisiblePartOfTheHole(Polyline hole) { //find a separating edge PolylinePoint a; var needToGoCounterclockWise = true; for (a = hole.StartPoint; !HoleSideIsVisibleFromQ(hole, a); a = hole.Next(a)) { Debug.Assert(needToGoCounterclockWise || a != hole.StartPoint); //check that we have not done the full circle needToGoCounterclockWise = false; } PolylinePoint b = hole.Next(a); //now the side a, a.Next - is separating if (needToGoCounterclockWise) { while (HoleSideIsVisibleFromQ(hole, hole.Prev(a))) { a = hole.Prev(a); } } //go clockwise starting from b for (; HoleSideIsVisibleFromQ(hole, b); b = hole.Next(b)) { } visibleBoundaries[hole] = new Stem(a, b); }
IEnumerable <Stem> GetInitialVisibleBoundaryStemsAndInsertActiveSides() { foreach (var keyValuePair in visibleBoundaries) { Polyline hole = keyValuePair.Key; Stem stem = keyValuePair.Value; bool crosses = false; foreach (PolylinePoint side in stem.Sides) { PolylinePoint source = side; if (source.Point.Y < q.Y) { if (side.NextOnPolyline.Point.Y >= q.Y) { TriangleOrientation orientation = Point.GetTriangleOrientation(q, source.Point, side.NextOnPolyline.Point); if (orientation == TriangleOrientation.Counterclockwise || orientation == TriangleOrientation.Collinear) { crosses = true; //we have two stems here yield return(new Stem(stem.Start, side)); yield return(new Stem(side.NextOnPolyline, stem.End)); RegisterActiveSide(side); break; } } } else if (source.Point.Y > q.Y) { break; } else if (side.Point.X >= q.X) { //we have pp.Y==q.Y crosses = true; //we need to add one or two stems here yield return(new Stem(side, stem.End)); if (side != stem.Start) { yield return(new Stem(stem.Start, hole.Prev(source))); } RegisterActiveSide(side); break; } } //there is no intersection with the ray if (!crosses) { yield return(stem); } } }
PolylinePoint GetOutgoingSide(PolylinePoint v) { Stem visibleStem = visibleBoundaries[v.Polyline]; if (v == visibleStem.End) { return(null); } return(v); }
void SortSAndInitActiveSides() { InitHeapAndInsertActiveSides(); for (Stem stem = heapForSorting.GetMinimum();; stem = heapForSorting.GetMinimum()) { sortedListOfPolypoints.Add(stem.Start); if (stem.MoveStartClockwise()) { heapForSorting.ChangeMinimum(stem); } else { heapForSorting.Dequeue(); } if (heapForSorting.Count == 0) { break; } } }
void ComputeVisiblePartOfTheHole(Polyline hole) { //find a separating edge PolylinePoint a; var needToGoCounterclockWise = true; for (a = hole.StartPoint; !HoleSideIsVisibleFromQ(hole, a); a = hole.Next(a)) { Debug.Assert(needToGoCounterclockWise || a != hole.StartPoint); //check that we have not done the full circle needToGoCounterclockWise = false; } PolylinePoint b = hole.Next(a); //now the side a, a.Next - is separating if (needToGoCounterclockWise) while (HoleSideIsVisibleFromQ(hole, hole.Prev(a))) a = hole.Prev(a); //go clockwise starting from b for (; HoleSideIsVisibleFromQ(hole, b); b = hole.Next(b)) {} visibleBoundaries[hole] = new Stem(a, b); }