예제 #1
0
        public virtual bool Contains(List<Point> figurePoints, AtomicRegion atom)
        {
            // A figure contains itself.
            ShapeAtomicRegion shapeAtom = atom as ShapeAtomicRegion;
            if (shapeAtom != null)
            {
                if (this.StructurallyEquals(shapeAtom.shape)) return true;
            }

            //
            // Do all vertices of that lie on the interior of this figure
            //
            List<Point> thatVertices = atom.GetVertices();
            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesInOrOn(vertex)) return false;
            }

            //
            // Check all midpoints of conenctions are on the interior.
            //
            foreach (Connection thatConn in atom.connections)
            {
                if (!this.PointLiesInOrOn(thatConn.Midpoint())) return false;
            }

            //
            // For any intersections between the atomic regions, the resultant points of intersection must be on the perimeter.
            //
            AtomicRegion thisFigureRegion = this.GetFigureAsAtomicRegion();
            List<AtomicRegion.IntersectionAgg> intersections = thisFigureRegion.GetIntersections(figurePoints, atom);
            foreach (AtomicRegion.IntersectionAgg agg in intersections)
            {
                if (agg.overlap)
                {
                    // No-Op
                }
                else
                {
                    // An approximation may result in an intersection inside the figure (although we would expect on)
                    if (!this.PointLiesInOrOn(agg.intersection1)) return false;
                    if (agg.intersection2 != null)
                    {
                        if (!this.PointLiesInOrOn(agg.intersection2)) return false;
                    }
                }
            }

            return true;
        }
예제 #2
0
        //
        // Using a single atomic region as a set of bounds:
        //    (1) Find all interesting regions (contained and intersecting)
        //    (2) Recursively compose all contained regions.
        //    (3) Combine all into the original boundary region.
        //
        private static List <AtomicRegion> ComposeSingleRegion(List <Point> figurePoints, AtomicRegion outerBounds, List <AtomicRegion> allRegions,
                                                               List <AtomicRegion> knownAtomicRegions, List <AtomicRegion> knownNonAtomicRegions,
                                                               List <List <AtomicRegion> > setsForNonAtomicRegions, Dictionary <Circle, int> circGranularity)
        {
            //
            // Base cases: we have already processed this atom as a sub-atom in a previous iteration.
            //
            if (knownAtomicRegions.Contains(outerBounds))
            {
                return(Utilities.MakeList <AtomicRegion>(outerBounds));
            }
            // We've processed this atom already.
            int index = knownNonAtomicRegions.IndexOf(outerBounds);

            if (index != -1)
            {
                return(setsForNonAtomicRegions[index]);
            }

            //
            // Acquire the current set of regions under consideration.
            //
            List <AtomicRegion> currentAtoms = new List <AtomicRegion>(allRegions);

            AddRange(currentAtoms, knownAtomicRegions);

            //
            // Collect all interesting regions for this region: those that intersect with it and those that are contained inside.
            //
            List <AtomicRegion> intersectingSet = null;
            List <AtomicRegion> containedSet    = null;

            GetInterestingRegions(currentAtoms, outerBounds, out intersectingSet, out containedSet);

            // If we have have no interactions, this is a truly atomic region.
            if (!intersectingSet.Any() && !containedSet.Any())
            {
                return(Utilities.MakeList <AtomicRegion>(outerBounds));
            }

            //
            // Recur on all containing regions.
            //
            List <AtomicRegion> newContainedAtoms = new List <AtomicRegion>();

            foreach (AtomicRegion containedAtom in containedSet)
            {
                if (knownAtomicRegions.Contains(containedAtom))
                {
                    AddAtom(newContainedAtoms, containedAtom);
                }
                else if (knownNonAtomicRegions.Contains(containedAtom))
                {
                    AddRange(newContainedAtoms, setsForNonAtomicRegions[knownNonAtomicRegions.IndexOf(containedAtom)]);
                }
                else
                {
                    // Get all regions using containedAtom as the boundary region.
                    List <AtomicRegion> newContainedBoundedAtoms = ComposeSingleRegion(figurePoints, containedAtom, currentAtoms,
                                                                                       knownAtomicRegions, knownNonAtomicRegions, setsForNonAtomicRegions, circGranularity);

                    AddRange(newContainedAtoms, newContainedBoundedAtoms);

                    //
                    // This is a true atomic region that cannot be split.
                    //
                    if (newContainedBoundedAtoms.Count == 1)
                    {
                        AddAtom(knownAtomicRegions, containedAtom);
                    }
                    //
                    // The boundary atom is replaced by all of the newAtoms
                    else
                    {
                        // Save all of the contained atomic regions for this atom.
                        if (AddAtom(knownNonAtomicRegions, containedAtom))
                        {
                            setsForNonAtomicRegions.Add(newContainedBoundedAtoms);
                        }

                        // Indicate all found regions are truly atomic
                        AddRange(knownAtomicRegions, newContainedBoundedAtoms);
                    }
                }
            }

            //
            // Now that all contained regions are atomized, combine ALL intersections and atomic regions.
            //
            //  Collect all segments and arcs (with explicit endpoints).
            //  Extend only if they do not touch the sides of the boundaries.
            //

            // inside of the boundaries; determine all intersection points.
            //
            //  (1) All intersecting regions.
            //      (a) For all vertices inside the boundaries, extend to the closest atom.
            //      (b) For all sides that pass through determine any intersections.
            //  (2) All contained atoms
            //      (a) For each side of a region, extend to the closest region.
            //      (b) If a single circle or concentric circles, extend a diameter from the closest point inside the region, through the center.
            //      (c) If several non-intersecting circles, extend diameters through the centers of each pair.
            //
            List <Point>   points   = new List <Point>();
            List <Segment> segments = new List <Segment>();
            List <Arc>     arcs     = new List <Arc>();

            //
            // Add the outer boundaries.
            //
            points.AddRange(outerBounds.GetVertices());
            foreach (Connection boundaryConn in outerBounds.connections)
            {
                if (boundaryConn.type == ConnectionType.ARC)
                {
                    arcs.Add(boundaryConn.segmentOrArc as Arc);
                }
                if (boundaryConn.type == ConnectionType.SEGMENT)
                {
                    segments.Add(boundaryConn.segmentOrArc as Segment);
                }
            }

            //
            // Regions that intersect the boundaries; selectively take connections.
            //
            foreach (AtomicRegion intersecting in intersectingSet)
            {
                List <AtomicRegion.IntersectionAgg> intersections = outerBounds.GetIntersections(figurePoints, intersecting);

                // Determine which intersections are interior to the boundaries.
                foreach (AtomicRegion.IntersectionAgg agg in intersections)
                {
                    if (agg.overlap) /* No-op */ } {