Esempio n. 1
0
        private Atomizer.AtomicRegion PolygonDefinesRegion(UndirectedPlanarGraph.PlanarGraph graph)
        {
            List <Segment> sides = new List <Segment>();

            //
            // All connections between adjacent connections MUST be segments.
            //
            for (int p = 0; p < points.Count; p++)
            {
                Segment segment = new Segment(points[p], points[(p + 1) % points.Count]);

                sides.Add(segment);

                if (graph.GetEdge(points[p], points[(p + 1) % points.Count]).edgeType != UndirectedPlanarGraph.EdgeType.REAL_SEGMENT)
                {
                    return(null);
                }
            }

            //
            // All iterative connections cannot be arcs.
            //
            for (int p1 = 0; p1 < points.Count - 1; p1++)
            {
                // We want to check for a direct cycle, therefore, p2 starts at p1 not p1 + 1
                for (int p2 = p1; p2 < points.Count; p2++)
                {
                    UndirectedPlanarGraph.PlanarGraphEdge edge = graph.GetEdge(points[p1], points[(p2 + 1) % points.Count]);

                    if (edge != null)
                    {
                        if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_ARC)
                        {
                            return(null);
                        }
                    }
                }
            }

            //
            // Make the Polygon
            //
            Polygon poly = Polygon.MakePolygon(sides);

            if (poly == null)
            {
                throw new ArgumentException("Real segments should define a polygon; they did not.");
            }

            return(new ShapeAtomicRegion(poly));
        }
Esempio n. 2
0
        //
        // Collect all arcs attributed to this this cycle;
        //
        private List <MinorArc> CollectStrictArcs(List <Circle> circles, UndirectedPlanarGraph.PlanarGraph graph)
        {
            List <MinorArc> minors = new List <MinorArc>();

            for (int p = 0; p < points.Count; p++)
            {
                UndirectedPlanarGraph.PlanarGraphEdge edge = graph.GetEdge(points[p], points[(p + 1) % points.Count]);

                if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_ARC)
                {
                    // Find the applicable circle.
                    Circle theCircle = null;
                    foreach (Circle circle in circles)
                    {
                        if (circle.HasArc(points[p], points[(p + 1) % points.Count]))
                        {
                            theCircle = circle;
                            break;
                        }
                    }

                    minors.Add(new MinorArc(theCircle, points[p], points[(p + 1) % points.Count]));
                }
            }

            return(minors);
        }
Esempio n. 3
0
        //
        // Based on the two points, extract the circle which results in the connection (if the connection exists).
        //
        private List <AtomicRegion> HandleConnection(UndirectedPlanarGraph.PlanarGraph graph, List <Circle> circles, Point pt1, Point pt2)
        {
            List <AtomicRegion> atoms = new List <AtomicRegion>();

            UndirectedPlanarGraph.PlanarGraphEdge edge = graph.GetEdge(pt1, pt2);

            if (edge == null)
            {
                return(atoms);
            }

            //
            // Find the one circle that applies to this set of points.
            //
            Circle theCircle = null;

            foreach (Circle circle in circles)
            {
                if (circle.PointLiesOn(pt1) && circle.PointLiesOn(pt2))
                {
                    theCircle = circle;
                }
            }

            switch (edge.edgeType)
            {
            case UndirectedPlanarGraph.EdgeType.REAL_ARC:
            case UndirectedPlanarGraph.EdgeType.REAL_DUAL:
                atoms.AddRange(CreateSectors(theCircle, pt1, pt2));
//                    atoms.AddRange(CreateSemiCircleRegions());
                break;
            }

            return(atoms);
        }
Esempio n. 4
0
        private List <Atomizer.AtomicRegion> SectorOrTruncationDefinesRegion(List <Circle> circles, UndirectedPlanarGraph.PlanarGraph graph)
        {
            //
            // Do there exist any real-dual edges or extended segments? If so, this is not a sector.
            //
            for (int p = 0; p < points.Count; p++)
            {
                UndirectedPlanarGraph.PlanarGraphEdge edge = graph.GetEdge(points[p], points[(p + 1) % points.Count]);

                if (edge.edgeType == UndirectedPlanarGraph.EdgeType.EXTENDED_SEGMENT)
                {
                    return(null);
                }
                else if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_DUAL)
                {
                    return(null);
                }
            }

            //
            // Collect all segments; split into two collinear lists.
            //
            List <Segment>         segments            = CollectSegments(graph);
            List <List <Segment> > collinearSegmentSet = SplitSegmentsIntoCollinearSequences(segments);

            // A sector requires one (semicircl) or two sets of segments ('normal' arc).
            if (collinearSegmentSet.Count > 2)
            {
                return(null);
            }

            //
            // Collect all arcs.
            //
            List <MinorArc>         arcs            = CollectStrictArcs(circles, graph);
            List <List <MinorArc> > collinearArcSet = SplitArcsIntoCollinearSequences(arcs);

            // A sector requires one set of arcs (no more, no less).
            if (collinearArcSet.Count != 1)
            {
                return(null);
            }

            // Semicircle has one set of sides
            if (collinearSegmentSet.Count == 1)
            {
                return(ConvertToTruncationOrSemicircle(collinearSegmentSet[0], collinearArcSet[0]));
            }

            // Pacman shape created with a circle results in Sector
            return(ConvertToGeneralSector(collinearSegmentSet[0], collinearSegmentSet[1], collinearArcSet[0]));
        }
Esempio n. 5
0
        //
        // Collect all segments attributed to this this cycle
        //
        private List <Segment> CollectSegments(UndirectedPlanarGraph.PlanarGraph graph)
        {
            List <Segment> segments = new List <Segment>();

            for (int p = 0; p < points.Count; p++)
            {
                UndirectedPlanarGraph.PlanarGraphEdge edge = graph.GetEdge(points[p], points[(p + 1) % points.Count]);

                if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_SEGMENT)
                {
                    segments.Add(new Segment(points[p], points[(p + 1) % points.Count]));
                }
            }

            return(segments);
        }
Esempio n. 6
0
        private List <Atomizer.AtomicRegion> MixedArcChordedRegion(List <Circle> thatCircles, UndirectedPlanarGraph.PlanarGraph graph)
        {
            List <AtomicRegion> regions = new List <AtomicRegion>();

            // Every segment may be have a set of circles. (on each side) surrounding it.
            // Keep parallel lists of: (1) segments, (2) (real) arcs, (3) left outer circles, and (4) right outer circles
            Segment[] regionsSegments   = new Segment[points.Count];
            Arc[]     arcSegments       = new Arc[points.Count];
            Circle[]  leftOuterCircles  = new Circle[points.Count];
            Circle[]  rightOuterCircles = new Circle[points.Count];

            //
            // Populate the parallel arrays.
            //
            int currCounter = 0;

            for (int p = 0; p < points.Count;)
            {
                UndirectedPlanarGraph.PlanarGraphEdge edge = graph.GetEdge(points[p], points[(p + 1) % points.Count]);
                Segment currSegment = new Segment(points[p], points[(p + 1) % points.Count]);

                //
                // If a known segment, seek a sequence of collinear segments.
                //
                if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_SEGMENT)
                {
                    Segment actualSeg = currSegment;

                    bool collinearExists = false;
                    int  prevPtIndex;
                    for (prevPtIndex = p + 1; prevPtIndex < points.Count; prevPtIndex++)
                    {
                        // Make another segment with the next point.
                        Segment nextSeg = new Segment(points[p], points[(prevPtIndex + 1) % points.Count]);

                        // CTA: This criteria seems invalid in some cases....; may not have collinearity

                        // We hit the end of the line of collinear segments.
                        if (!currSegment.IsCollinearWith(nextSeg))
                        {
                            break;
                        }

                        collinearExists = true;
                        actualSeg       = nextSeg;
                    }

                    // If there exists an arc over the actual segment, we have an embedded circle to consider.
                    regionsSegments[currCounter] = actualSeg;

                    if (collinearExists)
                    {
                        UndirectedPlanarGraph.PlanarGraphEdge collEdge = graph.GetEdge(actualSeg.Point1, actualSeg.Point2);
                        if (collEdge != null)
                        {
                            if (collEdge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_ARC)
                            {
                                // Find all applicable circles
                                List <Circle> circles = GetAllApplicableCircles(thatCircles, actualSeg.Point1, actualSeg.Point2);

                                // Get the exact outer circles for this segment (and create any embedded regions).
                                regions.AddRange(ConvertToCircleCircle(actualSeg, circles, out leftOuterCircles[currCounter], out rightOuterCircles[currCounter]));
                            }
                        }
                    }

                    currCounter++;
                    p = prevPtIndex;
                }
                else if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_DUAL)
                {
                    regionsSegments[currCounter] = new Segment(points[p], points[(p + 1) % points.Count]);

                    // Get the exact chord and set of circles
                    Segment chord = regionsSegments[currCounter];

                    // Find all applicable circles
                    List <Circle> circles = GetAllApplicableCircles(thatCircles, points[p], points[(p + 1) % points.Count]);

                    // Get the exact outer circles for this segment (and create any embedded regions).
                    regions.AddRange(ConvertToCircleCircle(chord, circles, out leftOuterCircles[currCounter], out rightOuterCircles[currCounter]));

                    currCounter++;
                    p++;
                }
                else if (edge.edgeType == UndirectedPlanarGraph.EdgeType.REAL_ARC)
                {
                    //
                    // Find the unique circle that contains these two points.
                    // (if more than one circle has these points, we would have had more intersections and it would be a direct chorded region)
                    //
                    List <Circle> circles = GetAllApplicableCircles(thatCircles, points[p], points[(p + 1) % points.Count]);

                    if (circles.Count != 1)
                    {
                        throw new Exception("Need ONLY 1 circle for REAL_ARC atom id; found (" + circles.Count + ")");
                    }

                    arcSegments[currCounter++] = new MinorArc(circles[0], points[p], points[(p + 1) % points.Count]);

                    p++;
                }
            }

            //
            // Check to see if this is a region in which some connections are segments and some are arcs.
            // This means there were no REAL_DUAL edges.
            //
            List <AtomicRegion> generalRegions = GeneralAtomicRegion(regionsSegments, arcSegments);

            if (generalRegions.Any())
            {
                return(generalRegions);
            }

            // Copy the segments into a list (ensuring no nulls)
            List <Segment> actSegments = new List <Segment>();

            foreach (Segment side in regionsSegments)
            {
                if (side != null)
                {
                    actSegments.Add(side);
                }
            }

            // Construct a polygon out of the straight-up segments
            // This might be a polygon that defines a pathological region.
            Polygon poly = Polygon.MakePolygon(actSegments);

            // Determine which outermost circles apply inside of this polygon.
            Circle[] circlesCutInsidePoly = new Circle[actSegments.Count];
            for (int p = 0; p < actSegments.Count; p++)
            {
                if (leftOuterCircles[p] != null && rightOuterCircles[p] == null)
                {
                    circlesCutInsidePoly[p] = CheckCircleCutInsidePolygon(poly, leftOuterCircles[p], actSegments[p].Point1, actSegments[p].Point2);
                }
                else if (leftOuterCircles[p] == null && rightOuterCircles[p] != null)
                {
                    circlesCutInsidePoly[p] = CheckCircleCutInsidePolygon(poly, rightOuterCircles[p], actSegments[p].Point1, actSegments[p].Point2);
                }
                else if (leftOuterCircles[p] != null && rightOuterCircles[p] != null)
                {
                    circlesCutInsidePoly[p] = CheckCircleCutInsidePolygon(poly, leftOuterCircles[p], actSegments[p].Point1, actSegments[p].Point2);

                    if (circlesCutInsidePoly[p] == null)
                    {
                        circlesCutInsidePoly[p] = rightOuterCircles[p];
                    }
                }
                else
                {
                    circlesCutInsidePoly[p] = null;
                }
            }

            bool isStrictPoly = true;

            for (int p = 0; p < actSegments.Count; p++)
            {
                if (circlesCutInsidePoly[p] != null || arcSegments[p] != null)
                {
                    isStrictPoly = false;
                    break;
                }
            }

            // This is just a normal shape region: polygon.
            if (isStrictPoly)
            {
                regions.Add(new ShapeAtomicRegion(poly));
            }
            // A circle cuts into the polygon.
            else
            {
                //
                // Now that all interior arcs have been identified, construct the atomic (probably pathological) region
                //
                AtomicRegion pathological = new AtomicRegion();
                for (int p = 0; p < actSegments.Count; p++)
                {
                    //
                    // A circle cutting inside the polygon
                    //
                    if (circlesCutInsidePoly[p] != null)
                    {
                        Arc theArc = null;

                        if (circlesCutInsidePoly[p].DefinesDiameter(regionsSegments[p]))
                        {
                            Point midpt = circlesCutInsidePoly[p].Midpoint(regionsSegments[p].Point1, regionsSegments[p].Point2);

                            if (!poly.IsInPolygon(midpt))
                            {
                                midpt = circlesCutInsidePoly[p].OppositePoint(midpt);
                            }

                            theArc = new Semicircle(circlesCutInsidePoly[p], regionsSegments[p].Point1, regionsSegments[p].Point2, midpt, regionsSegments[p]);
                        }
                        else
                        {
                            theArc = new MinorArc(circlesCutInsidePoly[p], regionsSegments[p].Point1, regionsSegments[p].Point2);
                        }

                        pathological.AddConnection(regionsSegments[p].Point1, regionsSegments[p].Point2, ConnectionType.ARC, theArc);
                    }
                    //
                    else
                    {
                        // We have a direct arc
                        if (arcSegments[p] != null)
                        {
                            pathological.AddConnection(regionsSegments[p].Point1, regionsSegments[p].Point2,
                                                       ConnectionType.ARC, arcSegments[p]);
                        }
                        // Use the segment
                        else
                        {
                            pathological.AddConnection(regionsSegments[p].Point1, regionsSegments[p].Point2,
                                                       ConnectionType.SEGMENT, regionsSegments[p]);
                        }
                    }
                }

                regions.Add(pathological);
            }


            return(regions);
        }