Esempio n. 1
0
        //
        // Find all regions that overlap this region.
        //
        private static void GetInterestingRegions(List <AtomicRegion> atoms, AtomicRegion theAtom,
                                                  out List <AtomicRegion> intersecting, out List <AtomicRegion> contained)
        {
            intersecting = new List <AtomicRegion>();
            contained    = new List <AtomicRegion>();

            foreach (AtomicRegion atom in atoms)
            {
                // An atom should not intersect itself.
                if (!theAtom.Equals(atom))
                {
                    if (theAtom.Contains(atom))
                    {
                        contained.Add(atom);
                    }
                    //else if (theAtom.StrictlyContains(atom))
                    //{
                    //    contained.Add(theAtom);
                    //}
                    else if (theAtom.OverlapsWith(atom))
                    {
                        intersecting.Add(atom);
                    }
                }
            }
        }
        //
        // Look at all nodes in the graph. If we can combine this atomic region with any region, add edges and nodes.
        //
        private void RegionComposition(Region currAtomRegion, List <ShapeRegion> shapeRegions, Queue <Region> worklist)
        {
            AtomicRegion atom = currAtomRegion.atoms[0];

            // Look at all nodes in the graph
            int graphSize = graph.Size();

            for (int n = 0; n < graphSize; n++)
            {
                Region node = graph.vertices[n].data;

                // If the region in the graph does NOT have this atom, perform construction.
                if (!node.HasAtom(atom))
                {
                    // Make the sum-set of atoms.
                    List <AtomicRegion> sumAtoms = new List <AtomicRegion>(node.atoms);
                    sumAtoms.Add(atom);

                    // Construct the shape: Shape = atoms + atom
                    Region sumRegion = GetShapeRegion(shapeRegions, sumAtoms);
                    if (sumRegion == null)
                    {
                        sumRegion = new Region(sumAtoms);
                    }

                    // Add to the worklist if we have added something new.
                    if (CreateAddNodesEdges(sumRegion, node, currAtomRegion))
                    {
                        // Add the smaller regions to the worklist.
                        worklist.Enqueue(sumRegion);
                    }
                }
            }
        }
Esempio n. 3
0
        private static bool AddAtom(List <AtomicRegion> atoms, AtomicRegion atom)
        {
            if (atoms.Contains(atom))
            {
                return(false);
            }

            atoms.Add(atom);

            return(true);
        }
Esempio n. 4
0
        public void AddAtomicRegion(AtomicRegion atom)
        {
            // Avoid adding an atomic region which is itself
            //if (atom is ShapeAtomicRegion)
            //{
            //    if ((atom as ShapeAtomicRegion).shape.StructurallyEquals(this)) return;
            //}

            if (atoms.Contains(atom)) return;

            atoms.Add(atom);
        }
Esempio n. 5
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;
        }
Esempio n. 6
0
        //
        // Does the atom have a connection which intersects the sides of the polygon.
        //
        public override bool Covers(AtomicRegion atom)
        {
            foreach (Connection conn in atom.connections)
            {
                if (conn.type == ConnectionType.SEGMENT)
                {
                    if (Covers(conn.segmentOrArc as Segment))
                    {
                        return(true);
                    }
                }
                else if (conn.type == ConnectionType.ARC)
                {
                    if (Covers(conn.segmentOrArc as Arc))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        //
        // Take the curr region and deconstruct it into all its atoms to place in the hypergraph.
        //
        private void RegionDecomposition(Region currRegion, List <ShapeRegion> shapeRegions, Queue <Region> worklist)
        {
            for (int a = 0; a < currRegion.atoms.Count; a++)
            {
                AtomicRegion currAtom = currRegion.atoms[a];

                if (currAtom is ShapeAtomicRegion)
                {
                    // Make the difference-set of atoms.
                    List <AtomicRegion> diffSet = new List <AtomicRegion>(currRegion.atoms);
                    diffSet.RemoveAt(a);

                    // Deconstruct the shape: Shape = atoms \ atom
                    Region diffRegion = GetShapeRegion(shapeRegions, diffSet);
                    if (diffRegion == null)
                    {
                        diffRegion = new Region(diffSet);
                    }

                    Region atomRegion = GetShapeRegion(shapeRegions, Utilities.MakeList <AtomicRegion>(currAtom));
                    if (atomRegion == null)
                    {
                        atomRegion = new Region(currAtom);
                    }

                    // Add to the worklist if we have added something new.
                    if (CreateAddNodesEdges(currRegion, diffRegion, atomRegion))
                    {
                        // Add the smaller regions to the worklist.
                        AddToWorklist(worklist, diffRegion);

                        // They can't be broken down, but they can be constructed.
                        AddToWorklist(worklist, atomRegion);
                    }
                }
            }
        }
Esempio n. 8
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 */ } {
Esempio n. 9
0
 /// <summary>
 /// Create a new ShadedRegion
 /// </summary>
 /// <param name="region">The region to shade</param>
 public ShadedRegion(AtomicRegion region)
 {
     Region = region;
 }
Esempio n. 10
0
 public virtual bool Covers(AtomicRegion a) { throw new NotImplementedException(); }