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; }
public Polygon(Segment s1, Segment s2, Segment s3) { orderedSides = new List <Segment>(); orderedSides.Add(s1); orderedSides.Add(s2); orderedSides.Add(s3); KeyValuePair <List <Point>, List <Angle> > pair = MakePointsAngle(orderedSides); points = pair.Key; angles = pair.Value; thisAtomicRegion = new ShapeAtomicRegion(this); this.FigureSynthesizerConstructor(); }
public Semicircle(Circle circle, Point e1, Point e2, Point m, List <Point> minorPts, List <Point> majorPts, Segment d) : base(circle, e1, e2, minorPts, majorPts) { diameter = d; middlePoint = m; if (!circle.DefinesDiameter(diameter)) { System.Diagnostics.Debug.WriteLine("Semicircle constructed without a diameter"); } if (!circle.DefinesDiameter(new Segment(e1, e2))) { System.Diagnostics.Debug.WriteLine("Semicircle constructed without a diameter"); } thisAtomicRegion = new ShapeAtomicRegion(this); }
// // Apply the strengthening clause to the appropriate polygon. // private void StrengthenPolygon(Strengthened streng) { GeometryTutorLib.ConcreteAST.Polygon strengPoly = streng.strengthened as GeometryTutorLib.ConcreteAST.Polygon; int numVertices = (streng.strengthened as GeometryTutorLib.ConcreteAST.Polygon).points.Count; int polyIndex = GeometryTutorLib.ConcreteAST.Polygon.GetPolygonIndex(numVertices); for (int p = 0; p < polygons[polyIndex].Count; p++) { if (polygons[polyIndex][p].HasSamePoints(streng.original as GeometryTutorLib.ConcreteAST.Polygon)) { // Is this the strongest class for this particular shape? // For example, Quadrilateral -> Trapezoid -> Isosceles Trapezoid if (strengPoly.IsStrongerThan(polygons[polyIndex][p])) { polygons[polyIndex][p] = strengPoly; // // Update any shape atomic regions as well as owners // Find All instances of owners / update all figureAtoms as well (and their owners) // foreach (AtomicRegion atom in atomicRegions) { ShapeAtomicRegion shapeAtom = atom as ShapeAtomicRegion; if (shapeAtom != null) { if (shapeAtom.shape.StructurallyEquals(streng.original)) { shapeAtom.ReshapeForStrenghthening(streng.strengthened as Figure); } } } } return; } } }
// // Acquire the set of atomic regions and OMIT the region given by the inner shape. // public static List <AtomicRegion> AcquireOpenAtomicRegions(List <Connection> connections, List <Point> innerShapePoints, Figure innerShape) { List <AtomicRegion> atoms = ConstructAtomicRegions(connections, innerShapePoints, innerShape); int foundIndex = -1; for (int a = 0; a < atoms.Count; a++) { ShapeAtomicRegion shapeAtom = atoms[a] as ShapeAtomicRegion; if (shapeAtom != null) { Polygon shapeAtomPoly = shapeAtom.shape as Polygon; Polygon innerShapePoly = innerShape as Polygon; if (shapeAtomPoly != null && innerShapePoly != null) { if (shapeAtomPoly.HasSamePoints(innerShapePoly)) { foundIndex = a; } } else if (shapeAtom.shape.StructurallyEquals(innerShape)) { foundIndex = a; } } } if (foundIndex == -1) { throw new Exception("Expected to find the original shape " + innerShape.ToString() + " as atomic region; did not."); } atoms.RemoveAt(foundIndex); return(atoms); }
public static List <AtomicRegion> GetAtomicRegions(List <Point> figurePoints, List <Circle> circles, List <Polygon>[] polygons) { List <AtomicRegion> originalAtoms = new List <AtomicRegion>(); Dictionary <Circle, int> circGranularity = new Dictionary <Circle, int>(); // // Convert all circles to atomic regions identifying their chord / radii substructure. // if (circles.Any()) { // Construct the granularity for when we construct arcs. circles = new List <Circle>(circles.OrderBy(c => c.radius)); double currRadius = circles[0].radius; int gran = 1; foreach (Circle circle in circles) { List <AtomicRegion> circleAtoms = circle.Atomize(figurePoints); // Make this circle the owner of the atomic regions. foreach (AtomicRegion atom in circleAtoms) { atom.AddOwner(circle); circle.AddAtomicRegion(atom); } originalAtoms.AddRange(circleAtoms); // // Granularity // if (circle.radius > currRadius) { gran++; } circGranularity[circle] = gran; } } // // Make all of the polygons an atomic region. // Also, convert any concave polygon into atoms by extending sides inward. // for (int n = Polygon.MIN_POLY_INDEX; n < Polygon.MAX_EXC_POLY_INDEX; n++) { foreach (Polygon poly in polygons[n]) { // Handle any concave polygons. ConcavePolygon concave = poly as ConcavePolygon; if (concave != null) { List <AtomicRegion> concaveAtoms = concave.Atomize(figurePoints); originalAtoms.AddRange(concaveAtoms); poly.AddAtomicRegions(concaveAtoms); } // Basic polygon: make it a shape atomic region. else { ShapeAtomicRegion shapeAtom = new ShapeAtomicRegion(poly); shapeAtom.AddOwner(poly); originalAtoms.Add(shapeAtom); } } } // // Since circles and Concave Polygons were atomized, there may be duplicate atomic regions. // originalAtoms = RemoveDuplicates(originalAtoms); List <AtomicRegion> workingAtoms = new List <AtomicRegion>(originalAtoms); // // Combine all of the atomic regions together. // List <AtomicRegion> composed = ComposeAllRegions(figurePoints, workingAtoms, circGranularity); composed = RemoveContained(composed); // // Run the graph-based algorithm one last time to identify any pathological regions (exterior to all shapes). // // Identify those pathological regions as well as any lost (major arcs). // List <AtomicRegion> lost = new List <AtomicRegion>(); List <AtomicRegion> pathological = new List <AtomicRegion>(); List <AtomicRegion> pathologicalID = IdentifyPathological(figurePoints, composed, circles, circGranularity); pathologicalID = RemoveRedundantSemicircle(pathologicalID); foreach (AtomicRegion atom in composed) { if (!pathologicalID.Contains(atom)) { bool containment = false; foreach (AtomicRegion pathAtom in pathologicalID) { if (atom.Contains(pathAtom)) { containment = true; break; } } if (!containment) { lost.Add(atom); } } } foreach (AtomicRegion atom in pathologicalID) { if (!composed.Contains(atom)) { pathological.Add(atom); } } List <AtomicRegion> finalAtomSet = new List <AtomicRegion>(); finalAtomSet.AddRange(composed); finalAtomSet.AddRange(pathological); return(finalAtomSet); }
public ShapeAtomicRegion GetFigureAsAtomicRegion() { if (thisAtomicRegion == null) thisAtomicRegion = new ShapeAtomicRegion(this); return thisAtomicRegion; }