Exemple #1
0
        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);
        }
Exemple #2
0
        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);
            }
        }
Exemple #4
0
        //
        // 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);
            }
        }