public static Circle ConstructCircle(Point p1, Point p2, Point p3) { // // Find the center of the circle. // Segment chord1 = new Segment(p1, p2); Segment chord2 = new Segment(p2, p3); Segment perpBis1 = chord1.GetPerpendicular(chord1.Midpoint()); Segment perpBis2 = chord2.GetPerpendicular(chord2.Midpoint()); Point center = perpBis1.FindIntersection(perpBis2); // // Radius is the distance between the circle and any of the original points. // return new Circle(center, Point.calcDistance(center, p1)); }
public static Circle ConstructCircle(Point p1, Point p2, Point p3) { // // Find the center of the circle. // Segment chord1 = new Segment(p1, p2); Segment chord2 = new Segment(p2, p3); Segment perpBis1 = chord1.GetPerpendicular(chord1.Midpoint()); Segment perpBis2 = chord2.GetPerpendicular(chord2.Midpoint()); Point center = perpBis1.FindIntersection(perpBis2); // // Radius is the distance between the circle and any of the original points. // return(new Circle(center, Point.calcDistance(center, p1))); }
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); }
// return the midpoint between these two on the circle. public Point Midpoint(Point a, Point b) { if (!this.PointLiesOn(a)) return null; if (!this.PointLiesOn(b)) return null; // Make the chord. Segment chord = new Segment(a, b); Point pt1 = null; Point pt2 = null; // Is this a diameter? If so, quickly return a point perpendicular to the diameter if (DefinesDiameter(chord)) { Segment perp = chord.GetPerpendicular(center); this.FindIntersection(perp, out pt1, out pt2); // Arbitrarily choose one of the points. return pt1 != null ? pt1 : pt2; } // Make radius through the midpoint of the chord. Segment radius = new Segment(center, chord.Midpoint()); this.FindIntersection(radius, out pt1, out pt2); if (pt2 == null) return pt1; Point theMidpoint = Arc.StrictlyBetweenMinor(pt1, new MinorArc(this, a, b)) ? pt1 : pt2; double angle1 = new Angle(a, center, theMidpoint).measure; double angle2 = new Angle(b, center, theMidpoint).measure; if (!Utilities.CompareValues(angle1, angle2)) { throw new ArgumentException("Midpoint is incorrect; angles do not equate: " + angle1 + " " + angle2); } return theMidpoint; }
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; }