Пример #1
0
        public static List<AtomicRegion> GetAtomicRegions(List<Point> figurePoints,
                                                          List<Circle> circles,
                                                          List<Polygon>[] polygons)
        {
            List<AtomicRegion> originalAtoms = new List<AtomicRegion>();
            Dictionary<Circle, int> circGranularity = new Dictionary<Circle, int>();

            //
            // Convert all circles to atomic regions identifying their chord / radii substructure.
            //
            if (circles.Any())
            {
                // Construct the granularity for when we construct arcs.
                circles = new List<Circle>(circles.OrderBy(c => c.radius));
                double currRadius = circles[0].radius;
                int gran = 1;

                foreach (Circle circle in circles)
                {
                    List<AtomicRegion> circleAtoms = circle.Atomize(figurePoints);

                    // Make this circle the owner of the atomic regions.
                    foreach (AtomicRegion atom in circleAtoms)
                    {
                        atom.AddOwner(circle);
                        circle.AddAtomicRegion(atom);
                    }
                    originalAtoms.AddRange(circleAtoms);

                    //
                    // Granularity
                    //
                    if (circle.radius > currRadius) gran++;
                    circGranularity[circle] = gran;
                }
            }

            //
            // Make all of the polygons an atomic region.
            // Also, convert any concave polygon into atoms by extending sides inward.
            //
            for (int n = Polygon.MIN_POLY_INDEX; n < Polygon.MAX_EXC_POLY_INDEX; n++)
            {
                foreach (Polygon poly in polygons[n])
                {
                    // Handle any concave polygons.
                    ConcavePolygon concave = poly as ConcavePolygon;
                    if (concave != null)
                    {
                        List<AtomicRegion> concaveAtoms = concave.Atomize(figurePoints);
                        originalAtoms.AddRange(concaveAtoms);
                        poly.AddAtomicRegions(concaveAtoms);
                    }

                    // Basic polygon: make it a shape atomic region.
                    else
                    {
                        ShapeAtomicRegion shapeAtom = new ShapeAtomicRegion(poly);
                        shapeAtom.AddOwner(poly);
                        originalAtoms.Add(shapeAtom);
                    }
                }
            }

            //
            // Since circles and Concave Polygons were atomized, there may be duplicate atomic regions.
            //
            originalAtoms = RemoveDuplicates(originalAtoms);
            List<AtomicRegion> workingAtoms = new List<AtomicRegion>(originalAtoms);

            //
            // Combine all of the atomic regions together.
            //
            List<AtomicRegion> composed = ComposeAllRegions(figurePoints, workingAtoms, circGranularity);
            composed = RemoveContained(composed);

            //
            // Run the graph-based algorithm one last time to identify any pathological regions (exterior to all shapes).
            //
            // Identify those pathological regions as well as any lost (major arcs).
            //
            List<AtomicRegion> lost = new List<AtomicRegion>();
            List<AtomicRegion> pathological = new List<AtomicRegion>();
            List<AtomicRegion> pathologicalID = IdentifyPathological(figurePoints, composed, circles, circGranularity);
            pathologicalID = RemoveRedundantSemicircle(pathologicalID);
            foreach (AtomicRegion atom in composed)
            {
                if (!pathologicalID.Contains(atom))
                {
                    bool containment = false;
                    foreach (AtomicRegion pathAtom in pathologicalID)
                    {
                        if (atom.Contains(pathAtom))
                        {
                            containment = true;
                            break;
                        }
                    }
                    if (!containment) lost.Add(atom);
                }
            }

            foreach (AtomicRegion atom in pathologicalID)
            {
                if (!composed.Contains(atom)) pathological.Add(atom);
            }

            List<AtomicRegion> finalAtomSet = new List<AtomicRegion>();
            finalAtomSet.AddRange(composed);
            finalAtomSet.AddRange(pathological);

            return finalAtomSet;
        }