public MinimalCycle Compose(MinimalCycle thatCycle, Segment extended) { MinimalCycle composed = new MinimalCycle(); List <Point> thisPts = this.GetPointsBookEndedBySegment(extended); List <Point> thatPts = thatCycle.GetPointsBookEndedBySegment(extended); // Add all points from this; composed.AddAll(thisPts); // Add all points from that (excluding endpoints) for (int p = thatPts.Count - 2; p > 0; p--) { composed.Add(thatPts[p]); } return(composed); }
public MinimalCycle Compose(MinimalCycle thatCycle, Segment extended) { MinimalCycle composed = new MinimalCycle(); List<Point> thisPts = this.GetPointsBookEndedBySegment(extended); List<Point> thatPts = thatCycle.GetPointsBookEndedBySegment(extended); // Add all points from this; composed.AddAll(thisPts); // Add all points from that (excluding endpoints) for (int p = thatPts.Count - 2; p > 0; p--) { composed.Add(thatPts[p]); } return composed; }
// // If a cycle has an edge that is EXTENDED, there exist two regions, one on each side of the segment; compose the two segments. // // Fixed point algorithm: while there exists a cycle with an extended segment, compose. private static void ComposeCycles(UndirectedPlanarGraph.PlanarGraph graph, List <MinimalCycle> cycles) { for (int cycleIndex = HasComposableCycle(graph, cycles); cycleIndex != -1; cycleIndex = HasComposableCycle(graph, cycles)) { // Get the cycle and remove it from the list. MinimalCycle thisCycle = cycles[cycleIndex]; cycles.RemoveAt(cycleIndex); // Get the extended segment which is the focal segment of composition. GeometryTutorLib.ConcreteAST.Segment extendedSeg = thisCycle.GetExtendedSegment(graph); // Find the matching cycle that has the same Extended segment int otherIndex = GetComposableCycleWithSegment(graph, cycles, extendedSeg); MinimalCycle otherCycle = cycles[otherIndex]; cycles.RemoveAt(otherIndex); // Compose the two cycles into a single cycle. MinimalCycle composed = thisCycle.Compose(otherCycle, extendedSeg); // Add the new, composed cycle cycles.Add(composed); } }
// // Extract a minimal cycle or a filament // void ExtractPrimitive(Point v0, OrderedPointList heap) { List <Point> visited = new List <Point>(); List <Point> sequence = new List <Point>(); sequence.Add(v0); // Create an initial line as (downward) vertical w.r.t. v0; v1 is based on the vertical line through v0 Point v1 = GetFirstNeighbor(v0); // GetClockwiseMost(new Point("", v0.X, v0.Y + 1), v0); Point vPrev = v0; Point vCurr = v1; int v0Index = graph.IndexOf(v0); int v1Index = graph.IndexOf(v1); // Loop until we have a cycle or we have a null (filament) while (vCurr != null && !vCurr.Equals(v0) && !visited.Contains(vCurr)) { sequence.Add(vCurr); visited.Add(vCurr); Point vNext = GetTightestCounterClockwiseNeighbor(vPrev, vCurr); vPrev = vCurr; vCurr = vNext; } // // Filament: hit an endpoint // if (vCurr == null) { // Filament found, not necessarily rooted at v0. ExtractFilament(v0, graph.nodes[v0Index].edges[0].target, heap); } // // Minimal cycle found. // else if (vCurr.Equals(v0)) { MinimalCycle primitive = new MinimalCycle(); primitive.AddAll(sequence); primitives.Add(primitive); if (Utilities.ATOMIC_REGION_GEN_DEBUG) { Debug.WriteLine(primitive.ToString()); } // Mark that these edges are a part of a cycle for (int p = 0; p < sequence.Count; p++) { graph.MarkCycleEdge(sequence[p], sequence[p + 1 < sequence.Count ? p + 1 : 0]); } graph.RemoveEdge(v0, v1); // // Check filaments for v0 and v1 // if (graph.nodes[v0Index].NodeDegree() == 1) { // Remove the filament rooted at v0. ExtractFilament(v0, graph.nodes[v0Index].edges[0].target, heap); } // // indices may have changed; update. // v1Index = graph.IndexOf(v1); if (v1Index != -1) { if (graph.nodes[v1Index].NodeDegree() == 1) { // Remove the filament rooted at v1. ExtractFilament(v1, graph.nodes[v1Index].edges[0].target, heap); } } } // // vCurr was visited earlier // else { // A cycle has been found, but is not guaranteed to be a minimal // cycle. This implies v0 is part of a filament. Locate the // starting point for the filament by traversing from v0 away // from the initial v1. while (graph.nodes[v0Index].NodeDegree() == 2) { // Choose between the the two neighbors if (graph.nodes[v0Index].edges[0].target.Equals(v1)) { v1 = v0; v0 = graph.nodes[v0Index].edges[1].target; } else { v1 = v0; v0 = graph.nodes[v0Index].edges[0].target; } // Find the next v0 index v0Index = graph.IndexOf(v0); } ExtractFilament(v0, v1, heap); } }
// // Extract a minimal cycle or a filament // void ExtractPrimitive(Point v0, OrderedPointList heap) { List<Point> visited = new List<Point>(); List<Point> sequence = new List<Point>(); sequence.Add(v0); // Create an initial line as (downward) vertical w.r.t. v0; v1 is based on the vertical line through v0 Point v1 = GetFirstNeighbor(v0); // GetClockwiseMost(new Point("", v0.X, v0.Y + 1), v0); Point vPrev = v0; Point vCurr = v1; int v0Index = graph.IndexOf(v0); int v1Index = graph.IndexOf(v1); // Loop until we have a cycle or we have a null (filament) while (vCurr != null && !vCurr.Equals(v0) && !visited.Contains(vCurr)) { sequence.Add(vCurr); visited.Add(vCurr); Point vNext = GetTightestCounterClockwiseNeighbor(vPrev, vCurr); vPrev = vCurr; vCurr = vNext; } // // Filament: hit an endpoint // if (vCurr == null) { // Filament found, not necessarily rooted at v0. ExtractFilament(v0, graph.nodes[v0Index].edges[0].target, heap); } // // Minimal cycle found. // else if (vCurr.Equals(v0)) { MinimalCycle primitive = new MinimalCycle(); primitive.AddAll(sequence); primitives.Add(primitive); if (Utilities.ATOMIC_REGION_GEN_DEBUG) { Debug.WriteLine(primitive.ToString()); } // Mark that these edges are a part of a cycle for (int p = 0; p < sequence.Count; p++) { graph.MarkCycleEdge(sequence[p], sequence[p+1 < sequence.Count ? p+1 : 0]); } graph.RemoveEdge(v0, v1); // // Check filaments for v0 and v1 // if (graph.nodes[v0Index].NodeDegree() == 1) { // Remove the filament rooted at v0. ExtractFilament(v0, graph.nodes[v0Index].edges[0].target, heap); } // // indices may have changed; update. // v1Index = graph.IndexOf(v1); if (v1Index != -1) { if (graph.nodes[v1Index].NodeDegree() == 1) { // Remove the filament rooted at v1. ExtractFilament(v1, graph.nodes[v1Index].edges[0].target, heap); } } } // // vCurr was visited earlier // else { // A cycle has been found, but is not guaranteed to be a minimal // cycle. This implies v0 is part of a filament. Locate the // starting point for the filament by traversing from v0 away // from the initial v1. while (graph.nodes[v0Index].NodeDegree() == 2) { // Choose between the the two neighbors if (graph.nodes[v0Index].edges[0].target.Equals(v1)) { v1 = v0; v0 = graph.nodes[v0Index].edges[1].target; } else { v1 = v0; v0 = graph.nodes[v0Index].edges[0].target; } // Find the next v0 index v0Index = graph.IndexOf(v0); } ExtractFilament(v0, v1, heap); } }