Exemple #1
0
        //
        // Do all the endpoints in that region lie within this region?
        // And, are all intersection points, if any, on this perimeter?
        //
        public virtual bool Contains(AtomicRegion that)
        {
            //
            // Do all vertices of that lie on the interior of this atomic region?
            //
            List <Point> thatVertices = that.GetVertices();

            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesOnOrInside(vertex))
                {
                    return(false);
                }
            }

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

            //
            // For any intersections between the atomic regions, the resultant points of intersection must be on the perimeter.
            //
            List <IntersectionAgg> intersections = this.GetIntersections(that);

            foreach (IntersectionAgg agg in intersections)
            {
                if (agg.overlap)
                {
                    // No-Op
                }
                else
                {
                    if (!this.PointLiesOn(agg.intersection1))
                    {
                        return(false);
                    }
                    if (agg.intersection2 != null)
                    {
                        if (!this.PointLiesOn(agg.intersection2))
                        {
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
Exemple #2
0
        //
        // All vertices of that region on the perimeter of this.
        // Number of intersections must equate to the number of vertices.
        //
        public bool Inscribed(AtomicRegion that)
        {
            List <Point> thatVertices = that.GetVertices();

            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesOn(vertex))
                {
                    return(false);
                }
            }

            return(this.GetIntersections(that).Count == thatVertices.Count);
        }
Exemple #3
0
        //
        // A region (that) lies inside this with one intersection.
        //
        public bool ContainsWithGreaterOneInscription(AtomicRegion that)
        {
            //
            // Do all vertices of that lie on the interior of this atomic region?
            //
            List <Point> thatVertices = that.GetVertices();

            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesOnOrInside(vertex))
                {
                    return(false);
                }
            }

            // There should be only ONE intersection
            return(this.GetIntersections(that).Count > 1);
        }
Exemple #4
0
        //
        // Do all the endpoints in that region lie within this region?
        // There should be no intersection points.
        //
        public bool StrictlyContains(AtomicRegion that)
        {
            //
            // Do all vertices of that lie on the interior of this atomic region?
            //
            List <Point> thatVertices = that.GetVertices();

            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesInside(vertex))
                {
                    return(false);
                }
            }

            // There should be no intersections
            return(!this.GetIntersections(that).Any());
        }
Exemple #5
0
        //
        // If there is no interaction between these atomic regions OR just touching
        //
        public bool InteriorOfWithTouching(AtomicRegion that)
        {
            List <IntersectionAgg> intersections = this.GetIntersections(that);

            // All vertices cannot be interior to the region.
            List <Point> thatVertices = that.GetVertices();

            foreach (Point vertex in thatVertices)
            {
                if (this.PointLiesOnOrInside(vertex))
                {
                    return(false);
                }
            }

            // All intersections must overlap; only point-based intersections which are on the perimeter.
            foreach (IntersectionAgg agg in intersections)
            {
                if (agg.overlap)
                {
                    // No-Op
                }
                else
                {
                    if (PointLiesExterior(agg.intersection1))
                    {
                        return(false);
                    }
                    if (agg.intersection2 != null)
                    {
                        if (PointLiesExterior(agg.intersection2))
                        {
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
Exemple #6
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;
        }
Exemple #7
0
        //
        // Do all the endpoints in that region lie within this region?
        // There should be no intersection points.
        //
        public bool StrictlyContains(AtomicRegion that)
        {
            //
            // Do all vertices of that lie on the interior of this atomic region?
            //
            List<Point> thatVertices = that.GetVertices();
            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesInside(vertex)) return false;
            }

            // There should be no intersections
            return !this.GetIntersections(that).Any();
        }
Exemple #8
0
        //
        // All vertices of that region on the perimeter of this.
        // Number of intersections must equate to the number of vertices.
        //
        public bool Inscribed(AtomicRegion that)
        {
            List<Point> thatVertices = that.GetVertices();
            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesOn(vertex)) return false;
            }

            return this.GetIntersections(that).Count == thatVertices.Count;
        }
Exemple #9
0
        //
        // If there is no interaction between these atomic regions OR just touching
        //
        public bool OnExteriorOf(AtomicRegion that)
        {
            List<IntersectionAgg> intersections = this.GetIntersections(that);

            // All vertices cannot be interior to the region.
            List<Point> thatVertices = that.GetVertices();
            foreach (Point vertex in thatVertices)
            {
                if (this.PointLiesInside(vertex)) return false;
            }

            // All intersections must be overlap; only point-based intersections which are on the perimeter.
            foreach (IntersectionAgg agg in intersections)
            {
                if (!agg.overlap)
                {
                    if (agg.intersection2 != null) return false;
                    if (!this.PointLiesOn(agg.intersection1)) return false;
                }
                else // agg.overlap
                {
                    // No-Op
                }
            }

            return true;
        }
Exemple #10
0
        //
        // A region (that) lies inside this with one intersection.
        //
        public bool ContainsWithOneInscription(AtomicRegion that)
        {
            //
            // Do all vertices of that lie on the interior of this atomic region?
            //
            List<Point> thatVertices = that.GetVertices();
            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesOnOrInside(vertex)) return false;
            }

            // There should be only ONE intersection
            return this.GetIntersections(that).Count == 1;
        }
Exemple #11
0
        //
        // Do all the endpoints in that region lie within this region?
        // And, are all intersection points, if any, on this perimeter?
        //
        public virtual bool Contains(AtomicRegion that)
        {
            //
            // Do all vertices of that lie on the interior of this atomic region?
            //
            List<Point> thatVertices = that.GetVertices();
            foreach (Point vertex in thatVertices)
            {
                if (!this.PointLiesOnOrInside(vertex)) return false;
            }

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

            //
            // For any intersections between the atomic regions, the resultant points of intersection must be on the perimeter.
            //
            List<IntersectionAgg> intersections = this.GetIntersections(that);
            foreach (IntersectionAgg agg in intersections)
            {
                if (agg.overlap)
                {
                    // No-Op
                }
                else
                {
                    if (!this.PointLiesOn(agg.intersection1)) return false;
                    if (agg.intersection2 != null)
                    {
                        if (!this.PointLiesOn(agg.intersection2)) return false;
                    }
                }
            }

            return true;
        }
        //
        // 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 */ }
                    else
                    {
                        if (agg.intersection1 != null)
                        {
                            if (outerBounds.PointLiesOnOrInside(agg.intersection1))
                            {
                                if (!outerBounds.NotInteriorTo(agg.thatConn))
                                {
                                    if (agg.thatConn.type == ConnectionType.ARC) GeometryTutorLib.Utilities.AddUnique<Arc>(arcs, agg.thatConn.segmentOrArc as Arc);
                                    if (agg.thatConn.type == ConnectionType.SEGMENT)
                                        GeometryTutorLib.Utilities.AddUnique<Segment>(segments, agg.thatConn.segmentOrArc as Segment);
                                }
                                GeometryTutorLib.Utilities.AddUnique<Point>(points, agg.intersection1);
                            }
                        }
                        if (agg.intersection2 != null)
                        {
                            if (outerBounds.PointLiesOnOrInside(agg.intersection2))
                            {
                                GeometryTutorLib.Utilities.AddUnique<Point>(points, agg.intersection2);
                            }
                        }
                    }
                }
            }

            //
            // Deal with contained regions.
            //
            // TO BE COMPLETED: Deal with isolated circles.
            foreach (AtomicRegion contained in newContainedAtoms)
            {
                List<Point> verts = contained.GetVertices();
                GeometryTutorLib.Utilities.AddUniqueList<Point>(points, verts);

                foreach (Connection conn in contained.connections)
                {
                    if (conn.type == ConnectionType.ARC) Utilities.AddUnique<Arc>(arcs, conn.segmentOrArc as Arc);
                    if (conn.type == ConnectionType.SEGMENT)
                    {
                        Utilities.AddUnique<Segment>(segments, conn.segmentOrArc as Segment);
                    }
                }
            }

            //
            // Find all intersections...among segments and arcs.
            //
            foreach (Segment segment in segments)
            {
                segment.ClearCollinear();
            }
            foreach (Arc arc in arcs)
            {
                arc.ClearCollinear();
            }

            HandleSegmentSegmentIntersections(figurePoints, points, segments, outerBounds);
            HandleSegmentArcIntersections(figurePoints, points, segments, arcs, outerBounds);
            HandleArcArcIntersections(figurePoints, points, arcs, outerBounds);
            // Returns the list of maximal segments.
            segments = HandleCollinearSubSegments(segments);
            // HandleCollinearSubArcs(arcs);

            //
            // Construct the Planar graph for atomic region identification.
            //
            GeometryTutorLib.Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph graph = new GeometryTutorLib.Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph();

            // Add the points as nodes in the graph.
            foreach (Point pt in points)
            {
                graph.AddNode(pt);
            }

            //
            // Edges are based on all the collinear relationships.
            // To ensure we are taking ONLY the closest extended intersections, choose ONLY the 1 point around the actual endpoints of the arc or segment.
            //
            foreach (Segment segment in segments)
            {
                for (int p = 0; p < segment.collinear.Count - 1; p++)
                {
                    if (outerBounds.PointLiesInOrOn(segment.collinear[p]) && outerBounds.PointLiesInOrOn(segment.collinear[p + 1]))
                    {
                        graph.AddUndirectedEdge(segment.collinear[p], segment.collinear[p + 1],
                                                new Segment(segment.collinear[p], segment.collinear[p + 1]).Length,
                                                GeometryTutorLib.Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_SEGMENT);
                    }
                }
            }

            foreach (Arc arc in arcs)
            {
                List<Point> applicWithMidpoints = GetArcPoints(arc, circGranularity);

                // Add the points to the graph; preprocess to see if all points are inside the region.
                bool[] inOrOn = new bool[applicWithMidpoints.Count];
                for (int p = 0; p < applicWithMidpoints.Count; p++)
                {
                    if (outerBounds.PointLiesInOrOn(applicWithMidpoints[p]))
                    {
                        graph.AddNode(applicWithMidpoints[p]);
                        inOrOn[p] = true;
                    }
                }

                for (int p = 0; p < applicWithMidpoints.Count - 1; p++)
                {
                    if (inOrOn[p] && inOrOn[p + 1])
                    {
                        graph.AddUndirectedEdge(applicWithMidpoints[p], applicWithMidpoints[p + 1],
                                                new Segment(applicWithMidpoints[p], applicWithMidpoints[p + 1]).Length,
                                                GeometryTutorLib.Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_ARC);
                    }
                }
            }

            //
            // Collect the circles from the arcs.
            //
            List<Circle> circles = new List<Circle>();
            foreach (Arc arc in arcs)
            {
                GeometryTutorLib.Utilities.AddStructurallyUnique<Circle>(circles, arc.theCircle);
            }

            //
            // Convert the planar graph to atomic regions.
            //
            GeometryTutorLib.Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph copy = new GeometryTutorLib.Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph(graph);
            FacetCalculator atomFinder = new FacetCalculator(copy);
            List<Primitive> primitives = atomFinder.GetPrimitives();
            List<AtomicRegion> boundedAtoms = PrimitiveToRegionConverter.Convert(graph, primitives, circles);

            ////
            //// Realign this set of atoms with the current set of working atoms; this guarantees we are looking at the same atom objects.
            ////
            //List<AtomicRegion> finalBoundedAtoms = new List<AtomicRegion>();
            //foreach (AtomicRegion boundedAtom in boundedAtoms)
            //{
            //    int tempIndex = currentAtoms.IndexOf(boundedAtom);
            //    if (tempIndex == -1) finalBoundedAtoms.Add(boundedAtom);
            //    else finalBoundedAtoms.Add(currentAtoms[tempIndex]);
            //}

            //
            // Determine ownership of the atomic regions.
            //
            foreach (AtomicRegion boundedAtom in boundedAtoms)
            {
                boundedAtom.AddOwners(outerBounds.owners);

                // Indicate that the given boundary shape owns all of the new regions within.
                ShapeAtomicRegion shapeAtom = outerBounds as ShapeAtomicRegion;
                if (shapeAtom != null)
                {
                    shapeAtom.shape.AddAtomicRegion(boundedAtom);
                }
            }

            return boundedAtoms;
        }
Exemple #13
0
        //
        // Compose this atomic region with a segment
        // This operation will return a list of atomic regions iff the segment passes through the atomic region; this
        // creates two new atomic regions since the segment divides the atom.
        //
        //public static List<AtomicRegion> Compose(AtomicRegion thisAtom, Segment that, Figure owner)
        //{
        //    List<AtomicRegion> newAtoms = new List<AtomicRegion>();
        //    List<AtomicRegion.IntersectionAgg> intersections = thisAtom.GetIntersections(that);
        //    // If there is only 1 intersection then we may have a 'corner' inside of the atomic region.
        //    if (intersections.Count == 1) return newAtoms;
        //    if (intersections.Count > 2) throw new ArgumentException("More than 3 intersections due to a segment during atomic region composition");
        //    // If there are two intersection points, this atomic region is split into 2 regions.
        //    if (intersections.Count != 2)
        //    {
        //        throw new ArgumentException("Expected 2 intersections due to a segment during atomic region composition; have " + intersections.Count);
        //    }
        //    //
        //    // Split the region into 2 new atomic regions.
        //    //
        //    // (0) Order the connections of this atomic region.
        //    // (1) Make a copy of the list of connections
        //    // (2) Replace 2 intersected connections with (up to) 4 new connections.
        //    // (3) Add this segment connection
        //    //
        //    thisAtom.OrderConnections();
        //    AtomicRegion newAtom1 = new AtomicRegion();
        //    AtomicRegion newAtom2 = new AtomicRegion();
        //    bool[] marked = new bool[intersections.Count];
        //    bool atom1 = true;
        //    foreach (Connection conn in thisAtom.connections)
        //    {
        //        bool found = false;
        //        for (int i = 0; i < intersections.Count; i++)
        //        {
        //            if (!marked[i])
        //            {
        //                marked[i] = true;
        //                if (conn.Equals(intersections[i].Key))
        //                {
        //                    found = true;
        //                    //
        //                    // How does this new segment intersect this connection?
        //                    //
        //                    // Endpoint
        //                    if (conn.HasPoint(intersections[i].Value))
        //                    {
        //                        // No-op
        //                    }
        //                    // Split this connection in the middle
        //                    else
        //                    {
        //                        Connection newConn1 = new Connection(conn.endpoint1, intersections[i].Value, conn.type, conn.segmentOwner);
        //                        Connection newConn2 = new Connection(conn.endpoint2, intersections[i].Value, conn.type, conn.segmentOwner);
        //                        //
        //                        // Which atomic region owns which new connection.
        //                        //
        //                        if (newAtom1.HasPoint(conn.endpoint1))
        //                        {
        //                            newAtom1.AddConnection(newConn1);
        //                            newAtom2.AddConnection(newConn2);
        //                        }
        //                        else if (newAtom2.HasPoint(conn.endpoint1))
        //                        {
        //                            newAtom2.AddConnection(newConn1);
        //                            newAtom1.AddConnection(newConn2);
        //                        }
        //                        // Neither atomic region has the point (possibly the first connection encountered).
        //                        else
        //                        {
        //                            // Arbitrary assignment
        //                            newAtom1.AddConnection(newConn1);
        //                            newAtom2.AddConnection(newConn2);
        //                        }
        //                    }
        //                    // Shift to the second (new) atomic region.
        //                    atom1 = false;
        //                }
        //            }
        //        }
        //        // This is not a splittable connection so just add it to the list.
        //        if (!found)
        //        {
        //            if (atom1) newAtom1.AddConnection(conn);
        //            else newAtom2.AddConnection(conn);
        //        }
        //    }
        //    //
        //    // Add this new segment as a connection to both atomic regions.
        //    //
        //    newAtom1.AddConnection(intersections[0].Value, intersections[1].Value, ConnectionType.SEGMENT, owner);
        //    newAtom2.AddConnection(intersections[0].Value, intersections[1].Value, ConnectionType.SEGMENT, owner);
        //    // Order the connections in the new regions we created.
        //    newAtom1.OrderConnections();
        //    newAtom2.OrderConnections();
        //    newAtoms.Add(newAtom1);
        //    newAtoms.Add(newAtom2);
        //    return newAtoms;
        //}
        public static void Overlap(List<Point> figurePoints, AtomicRegion thisAtom, AtomicRegion thatAtom, out List<AtomicRegion> toAdd, out List<AtomicRegion> toRemove)
        {
            //
            // Acquire all arcs and segments.
            //
            List<Arc> graphArcs = new List<Arc>();
            List<Segment> graphSegments = new List<Segment>();
            foreach (Connection thisConn in thisAtom.connections)
            {
                if (thisConn.type == ConnectionType.SEGMENT) graphSegments.Add(thisConn.segmentOrArc as Segment);
                else graphArcs.Add(thisConn.segmentOrArc as Arc);
            }

            foreach (Connection thatConn in thatAtom.connections)
            {
                if (thatConn.type == ConnectionType.SEGMENT) graphSegments.Add(thatConn.segmentOrArc as Segment);
                else graphArcs.Add(thatConn.segmentOrArc as Arc);
            }

            //
            // Clear collinearities of all segments / arcs.
            //
            List<Circle> circles = new List<Circle>(); // get the list of applicable circles to these atoms.
            foreach (Segment seg in graphSegments) seg.ClearCollinear();
            foreach (Arc arc in graphArcs)
            {
                Utilities.AddStructurallyUnique<Circle>(circles, arc.theCircle);
                arc.ClearCollinear();
            }

            //
            // All points of interest for these atoms.
            //
            List<Point> allPoints = new List<Point>();
            allPoints.AddRange(thisAtom.GetVertices());
            allPoints.AddRange(thatAtom.GetVertices());

            //
            // Determine 'collinearities' for the intersections.
            //
            List<AtomicRegion.IntersectionAgg> intersections = thisAtom.GetIntersections(figurePoints, thatAtom);

            List<Point> intersectionPts = new List<Point>();
            foreach (AtomicRegion.IntersectionAgg agg in intersections)
            {
                if (agg.intersection1 != null)
                {
                    if (!Utilities.HasStructurally<Point>(allPoints, agg.intersection1)) intersectionPts.Add(agg.intersection1);
                    agg.thisConn.segmentOrArc.AddCollinearPoint(agg.intersection1);
                    agg.thatConn.segmentOrArc.AddCollinearPoint(agg.intersection1);
                }
                if (agg.intersection2 != null)
                {
                    if (!Utilities.HasStructurally<Point>(allPoints, agg.intersection2)) intersectionPts.Add(agg.intersection2);
                    intersectionPts.Add(agg.intersection2);
                    agg.thisConn.segmentOrArc.AddCollinearPoint(agg.intersection2);
                    agg.thatConn.segmentOrArc.AddCollinearPoint(agg.intersection2);
                }
            }

            // Add any unlabeled intersection points.
            allPoints.AddRange(intersectionPts);

            //
            // Construct the Planar graph for atomic region identification.
            //
            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph graph = new Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph();

            // Add the points as nodes in the graph.
            foreach (Point pt in allPoints)
            {
                graph.AddNode(pt);
            }

            //
            // Edges are based on all the collinear relationships.
            //
            foreach (Segment segment in graphSegments)
            {
                for (int p = 0; p < segment.collinear.Count - 1; p++)
                {
                    graph.AddUndirectedEdge(segment.collinear[p], segment.collinear[p+1],
                                            new Segment(segment.collinear[p], segment.collinear[p + 1]).Length,
                                            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_SEGMENT);
                }
            }

            foreach (Arc arc in graphArcs)
            {
                for (int p = 0; p < arc.collinear.Count - 1; p++)
                {
                    graph.AddUndirectedEdge(arc.collinear[p], arc.collinear[p + 1],
                                            new Segment(arc.collinear[p], arc.collinear[p + 1]).Length,
                                            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_ARC);
                }
            }

            //
            // Convert the planar graph to atomic regions.
            //
            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph copy = new Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph(graph);
            FacetCalculator atomFinder = new FacetCalculator(copy);
            List<Primitive> primitives = atomFinder.GetPrimitives();
            List<AtomicRegion> atoms = PrimitiveToRegionConverter.Convert(graph, primitives, circles);

            //
            // Determine ownership of the atomic regions.
            //
            foreach (AtomicRegion atom in atoms)
            {
                if (thisAtom.Contains(atom))
                {
                    atom.AddOwners(thisAtom.owners);
                }
                if (thatAtom.Contains(atom))
                {
                    atom.AddOwners(thatAtom.owners);
                }
            }

            toAdd = atoms;
            toRemove = new List<AtomicRegion>();
            toRemove.Add(thisAtom);
            toRemove.Add(thatAtom);
        }
Exemple #14
0
        //
        // Compose this atomic region with a segment
        // This operation will return a list of atomic regions iff the segment passes through the atomic region; this
        // creates two new atomic regions since the segment divides the atom.
        //
        //public static List<AtomicRegion> Compose(AtomicRegion thisAtom, Segment that, Figure owner)
        //{
        //    List<AtomicRegion> newAtoms = new List<AtomicRegion>();
        //    List<AtomicRegion.IntersectionAgg> intersections = thisAtom.GetIntersections(that);

        //    // If there is only 1 intersection then we may have a 'corner' inside of the atomic region.
        //    if (intersections.Count == 1) return newAtoms;

        //    if (intersections.Count > 2) throw new ArgumentException("More than 3 intersections due to a segment during atomic region composition");

        //    // If there are two intersection points, this atomic region is split into 2 regions.
        //    if (intersections.Count != 2)
        //    {
        //        throw new ArgumentException("Expected 2 intersections due to a segment during atomic region composition; have " + intersections.Count);
        //    }

        //    //
        //    // Split the region into 2 new atomic regions.
        //    //
        //    // (0) Order the connections of this atomic region.
        //    // (1) Make a copy of the list of connections
        //    // (2) Replace 2 intersected connections with (up to) 4 new connections.
        //    // (3) Add this segment connection
        //    //
        //    thisAtom.OrderConnections();

        //    AtomicRegion newAtom1 = new AtomicRegion();
        //    AtomicRegion newAtom2 = new AtomicRegion();

        //    bool[] marked = new bool[intersections.Count];
        //    bool atom1 = true;
        //    foreach (Connection conn in thisAtom.connections)
        //    {
        //        bool found = false;
        //        for (int i = 0; i < intersections.Count; i++)
        //        {
        //            if (!marked[i])
        //            {
        //                marked[i] = true;
        //                if (conn.Equals(intersections[i].Key))
        //                {
        //                    found = true;

        //                    //
        //                    // How does this new segment intersect this connection?
        //                    //
        //                    // Endpoint
        //                    if (conn.HasPoint(intersections[i].Value))
        //                    {
        //                        // No-op
        //                    }
        //                    // Split this connection in the middle
        //                    else
        //                    {
        //                        Connection newConn1 = new Connection(conn.endpoint1, intersections[i].Value, conn.type, conn.segmentOwner);
        //                        Connection newConn2 = new Connection(conn.endpoint2, intersections[i].Value, conn.type, conn.segmentOwner);

        //                        //
        //                        // Which atomic region owns which new connection.
        //                        //
        //                        if (newAtom1.HasPoint(conn.endpoint1))
        //                        {
        //                            newAtom1.AddConnection(newConn1);
        //                            newAtom2.AddConnection(newConn2);
        //                        }
        //                        else if (newAtom2.HasPoint(conn.endpoint1))
        //                        {
        //                            newAtom2.AddConnection(newConn1);
        //                            newAtom1.AddConnection(newConn2);
        //                        }
        //                        // Neither atomic region has the point (possibly the first connection encountered).
        //                        else
        //                        {
        //                            // Arbitrary assignment
        //                            newAtom1.AddConnection(newConn1);
        //                            newAtom2.AddConnection(newConn2);
        //                        }
        //                    }

        //                    // Shift to the second (new) atomic region.
        //                    atom1 = false;
        //                }
        //            }
        //        }

        //        // This is not a splittable connection so just add it to the list.
        //        if (!found)
        //        {
        //            if (atom1) newAtom1.AddConnection(conn);
        //            else newAtom2.AddConnection(conn);
        //        }
        //    }

        //    //
        //    // Add this new segment as a connection to both atomic regions.
        //    //
        //    newAtom1.AddConnection(intersections[0].Value, intersections[1].Value, ConnectionType.SEGMENT, owner);
        //    newAtom2.AddConnection(intersections[0].Value, intersections[1].Value, ConnectionType.SEGMENT, owner);

        //    // Order the connections in the new regions we created.
        //    newAtom1.OrderConnections();
        //    newAtom2.OrderConnections();
        //    newAtoms.Add(newAtom1);
        //    newAtoms.Add(newAtom2);

        //    return newAtoms;
        //}

        public static void Overlap(List <Point> figurePoints, AtomicRegion thisAtom, AtomicRegion thatAtom, out List <AtomicRegion> toAdd, out List <AtomicRegion> toRemove)
        {
            //
            // Acquire all arcs and segments.
            //
            List <Arc>     graphArcs     = new List <Arc>();
            List <Segment> graphSegments = new List <Segment>();

            foreach (Connection thisConn in thisAtom.connections)
            {
                if (thisConn.type == ConnectionType.SEGMENT)
                {
                    graphSegments.Add(thisConn.segmentOrArc as Segment);
                }
                else
                {
                    graphArcs.Add(thisConn.segmentOrArc as Arc);
                }
            }

            foreach (Connection thatConn in thatAtom.connections)
            {
                if (thatConn.type == ConnectionType.SEGMENT)
                {
                    graphSegments.Add(thatConn.segmentOrArc as Segment);
                }
                else
                {
                    graphArcs.Add(thatConn.segmentOrArc as Arc);
                }
            }

            //
            // Clear collinearities of all segments / arcs.
            //
            List <Circle> circles = new List <Circle>(); // get the list of applicable circles to these atoms.

            foreach (Segment seg in graphSegments)
            {
                seg.ClearCollinear();
            }
            foreach (Arc arc in graphArcs)
            {
                Utilities.AddStructurallyUnique <Circle>(circles, arc.theCircle);
                arc.ClearCollinear();
            }

            //
            // All points of interest for these atoms.
            //
            List <Point> allPoints = new List <Point>();

            allPoints.AddRange(thisAtom.GetVertices());
            allPoints.AddRange(thatAtom.GetVertices());

            //
            // Determine 'collinearities' for the intersections.
            //
            List <AtomicRegion.IntersectionAgg> intersections = thisAtom.GetIntersections(figurePoints, thatAtom);

            List <Point> intersectionPts = new List <Point>();

            foreach (AtomicRegion.IntersectionAgg agg in intersections)
            {
                if (agg.intersection1 != null)
                {
                    if (!Utilities.HasStructurally <Point>(allPoints, agg.intersection1))
                    {
                        intersectionPts.Add(agg.intersection1);
                    }
                    agg.thisConn.segmentOrArc.AddCollinearPoint(agg.intersection1);
                    agg.thatConn.segmentOrArc.AddCollinearPoint(agg.intersection1);
                }
                if (agg.intersection2 != null)
                {
                    if (!Utilities.HasStructurally <Point>(allPoints, agg.intersection2))
                    {
                        intersectionPts.Add(agg.intersection2);
                    }
                    intersectionPts.Add(agg.intersection2);
                    agg.thisConn.segmentOrArc.AddCollinearPoint(agg.intersection2);
                    agg.thatConn.segmentOrArc.AddCollinearPoint(agg.intersection2);
                }
            }

            // Add any unlabeled intersection points.
            allPoints.AddRange(intersectionPts);

            //
            // Construct the Planar graph for atomic region identification.
            //
            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph graph = new Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph();

            // Add the points as nodes in the graph.
            foreach (Point pt in allPoints)
            {
                graph.AddNode(pt);
            }

            //
            // Edges are based on all the collinear relationships.
            //
            foreach (Segment segment in graphSegments)
            {
                for (int p = 0; p < segment.collinear.Count - 1; p++)
                {
                    graph.AddUndirectedEdge(segment.collinear[p], segment.collinear[p + 1],
                                            new Segment(segment.collinear[p], segment.collinear[p + 1]).Length,
                                            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_SEGMENT);
                }
            }

            foreach (Arc arc in graphArcs)
            {
                for (int p = 0; p < arc.collinear.Count - 1; p++)
                {
                    graph.AddUndirectedEdge(arc.collinear[p], arc.collinear[p + 1],
                                            new Segment(arc.collinear[p], arc.collinear[p + 1]).Length,
                                            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_ARC);
                }
            }

            //
            // Convert the planar graph to atomic regions.
            //
            Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph copy = new Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph(graph);
            FacetCalculator     atomFinder = new FacetCalculator(copy);
            List <Primitive>    primitives = atomFinder.GetPrimitives();
            List <AtomicRegion> atoms      = PrimitiveToRegionConverter.Convert(graph, primitives, circles);

            //
            // Determine ownership of the atomic regions.
            //
            foreach (AtomicRegion atom in atoms)
            {
                if (thisAtom.Contains(atom))
                {
                    atom.AddOwners(thisAtom.owners);
                }
                if (thatAtom.Contains(atom))
                {
                    atom.AddOwners(thatAtom.owners);
                }
            }

            toAdd    = atoms;
            toRemove = new List <AtomicRegion>();
            toRemove.Add(thisAtom);
            toRemove.Add(thatAtom);
        }