public List <Area_Based_Analyses.Atomizer.AtomicRegion> Atomize(List <Point> figurePoints) { // // Clear collinearities in preparation for determining intersection points. // List <Segment> extendedSegments = new List <Segment>(); foreach (Segment side in orderedSides) { side.ClearCollinear(); } // // Determine if any side intersects a non-adjacent side. // If so, track all the intersection points. // List <Point> imagPts = new List <Point>(); for (int s1 = 0; s1 < orderedSides.Count - 1; s1++) { // +2 excludes this side and the adjacent side for (int s2 = s1 + 2; s2 < orderedSides.Count; s2++) { // Avoid intersecting the first with the last. if (s1 != 0 || s2 != orderedSides.Count - 1) { Point intersection = orderedSides[s1].FindIntersection(orderedSides[s2]); intersection = Utilities.AcquirePoint(figurePoints, intersection); if (intersection != null) { // The point of interest must be on the perimeter of the polygon. if (this.PointLiesOn(intersection) || this.PointLiesInside(intersection)) { orderedSides[s1].AddCollinearPoint(intersection); orderedSides[s2].AddCollinearPoint(intersection); // The intersection point may be a vertex; avoid redundant additions. if (!Utilities.HasStructurally <Point>(imagPts, intersection)) { imagPts.Add(intersection); } } } } } } // // Add the imaginary points to the list of figure points; // this is needed for consistency among all regions / polygons. // Utilities.AddUniqueList <Point>(figurePoints, imagPts); // // Construct the Planar graph for atomic region identification. // Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph graph = new Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.PlanarGraph(); // Add all imaginary points and intersection points foreach (Point pt in this.points) { graph.AddNode(pt); } foreach (Point pt in imagPts) { graph.AddNode(pt); } // // Cycle through collinearities adding to the graph. // Ensure that a connection is interior to this polygon. // foreach (Segment side in orderedSides) { for (int p = 0; p < side.collinear.Count - 1; p++) { // // Find the midpoint of this segment and determine if it is interior to the polygon. // If it is, then this is a legitimate connection. // Segment thisSegment = new Segment(side.collinear[p], side.collinear[p + 1]); Point midpoint = thisSegment.Midpoint(); if (this.PointLiesInOrOn(midpoint)) { graph.AddUndirectedEdge(side.collinear[p], side.collinear[p + 1], thisSegment.Length, Area_Based_Analyses.Atomizer.UndirectedPlanarGraph.EdgeType.REAL_SEGMENT); } } } // // 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, new List <Circle>()); // No circles here. // State ownership foreach (AtomicRegion atom in atoms) { atom.AddOwner(this); this.AddAtomicRegion(atom); } return(atoms); }