// // 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); } } } }
private static bool AddAtom(List <AtomicRegion> atoms, AtomicRegion atom) { if (atoms.Contains(atom)) { return(false); } atoms.Add(atom); return(true); }
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); }
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; }
// // 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); } } } }
// // 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 */ } {
/// <summary> /// Create a new ShadedRegion /// </summary> /// <param name="region">The region to shade</param> public ShadedRegion(AtomicRegion region) { Region = region; }
public virtual bool Covers(AtomicRegion a) { throw new NotImplementedException(); }