public override bool IsStrongerThan(Polygon that) { if (that is Kite) return false; if (that is Parallelogram) return false; if (that is Trapezoid) return true; if (that is Quadrilateral) return true; return false; }
public override bool IsStrongerThan(Polygon that) { if (that is EquilateralTriangle) return false; if (that is IsoscelesTriangle) return false; if (that is RightTriangle) return false; if (that is Triangle) return true; return false; }
// // For each given set, add 1 new side (at a time) to the list of sides in order to construct polygons. // private void InductivelyConstructPolygon(List <List <int> > openPolygonSets, bool[,] eligible, List <List <int> > constructedPolygonSets) { // Stop if no sets to consider and grow from. if (!openPolygonSets.Any()) { return; } // Stop at a maximum number of sides; we say n is the number of sides if (openPolygonSets[0].Count == GeometryTutorLib.ConcreteAST.Polygon.MAX_POLYGON_SIDES) { return; } int matrixLength = eligible.GetLength(0); // The set of sets that contains n+1 elements that do not make a polygon (sent to the next round) List <List <int> > failedPolygonSets = new List <List <int> >(); // Breadth first consruction / traversal foreach (List <int> currentOpenSet in openPolygonSets) { // Since indices will be ordered least to greatest, we start looking at the largest index (last place in the list). for (int s = currentOpenSet[currentOpenSet.Count - 1]; s < matrixLength; s++) { if (IsEligible(currentOpenSet, eligible, s)) { List <int> newIndices = new List <int>(currentOpenSet); newIndices.Add(s); // Did we already create a polygon with a subset of these indices? if (!GeometryTutorLib.Utilities.ListHasSubsetOfSet <int>(constructedPolygonSets, newIndices)) { List <GeometryTutorLib.ConcreteAST.Segment> segs = MakeSegmentsList(newIndices); GeometryTutorLib.ConcreteAST.Polygon poly = GeometryTutorLib.ConcreteAST.Polygon.MakePolygon(segs); if (poly == null) { failedPolygonSets.Add(newIndices); } else { polygons[GeometryTutorLib.ConcreteAST.Polygon.GetPolygonIndex(segs.Count)].Add(poly); // Keep track of all existent sets of segments which created polygons. constructedPolygonSets.Add(newIndices); } } } } } InductivelyConstructPolygon(failedPolygonSets, eligible, constructedPolygonSets); }
// // Not all shapes are explicitly stated by the user; find all the implied shapes. // This populates the polygon array with any such shapes (concave or convex) // // Using a restricted powerset construction (from the bottom-up), construct all polygons. // Specifically: // (1) begin with all nC3 sets of segments. // (2) If the set of 3 segments makes a triangle, create polygon, stop. // (3) If the set of 3 segments does NOT make a triangle, construct all possible sets of size 4. // (4) Inductively repeat for sets of size up MAX_POLY // No set of segments are collinear. // // This construction must be done in a breadth first manner (triangles then quads then pentagons...) // private void CalculateImpliedPolygons() { bool[,] eligible = DetermineEligibleCombinations(); List <List <int> > constructedPolygonSets = new List <List <int> >(); List <List <int> > failedPolygonSets = new List <List <int> >(); // // Base case: construct all triangles. // For all non-triangle set of 3 segments, inductively look for polygons with more sides. // for (int s1 = 0; s1 < segments.Count - 2; s1++) { for (int s2 = s1 + 1; s2 < segments.Count - 1; s2++) { if (eligible[s1, s2]) { for (int s3 = s2 + 1; s3 < segments.Count - 0; s3++) { // Does this set create a triangle? if (eligible[s1, s3] && eligible[s2, s3]) { List <int> indices = new List <int>(); indices.Add(s1); indices.Add(s2); indices.Add(s3); List <GeometryTutorLib.ConcreteAST.Segment> segs = MakeSegmentsList(indices); GeometryTutorLib.ConcreteAST.Polygon poly = GeometryTutorLib.ConcreteAST.Polygon.MakePolygon(segs); if (poly == null) { failedPolygonSets.Add(indices); } else { polygons[GeometryTutorLib.ConcreteAST.Polygon.GetPolygonIndex(indices.Count)].Add(poly); // Keep track of all existent sets of segments which created polygons. constructedPolygonSets.Add(indices); } } } } } } // // Inductively look for polygons with more than 3 sides. // InductivelyConstructPolygon(failedPolygonSets, eligible, constructedPolygonSets); }
public override bool IsStrongerThan(Polygon that) { if (that is EquilateralTriangle) return false; if (that is IsoscelesTriangle) return true; if (that is RightTriangle) return false; if (that is Triangle) { Triangle tri = that as Triangle; if (tri.provenIsosceles) return true; if (tri.provenEquilateral) return false; if (tri.provenRight) return false; return true; } return false; }
// // 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; } } }
// // For each polygon, it is inscribed in the circle? Is it circumscribed? // public void AnalyzePolygonInscription(Polygon poly) { int index = Polygon.GetPolygonIndex(poly.orderedSides.Count); if (PolygonCircumscribesCircle(poly.orderedSides)) circumPolys[index].Add(poly); if (CircleCircumscribesPolygon(poly.orderedSides)) inscribedPolys[index].Add(poly); }
// // that Polygon lies within this circle. // private bool ContainsPolygon(Polygon that) { // // All points are interior to the polygon. // foreach (Point thatPt in that.points) { if (!this.PointLiesInOrOn(thatPt)) return false; } return true; }
// // Takes a non-shape atomic region and turns it into an approximate polygon, // by converting all arcs into approximated arcs using many line segments. // public virtual Polygon GetPolygonalized() { if (polygonalized != null) return polygonalized; List<Segment> sides = new List<Segment>(); foreach (Connection conn in connections) { sides.AddRange(conn.Segmentize()); } polygonalized = Polygon.MakePolygon(sides); return polygonalized; }
private bool ContainsPolygon(Polygon that) { // // All points are interior to the polygon. // foreach (Point thatPt in that.points) { if (!this.PointLiesInOrOn(thatPt)) return false; } // // Check that all intersections so that there are no crossings. // foreach (Segment thisSide in this.orderedSides) { foreach (Segment thatSide in that.orderedSides) { if (thisSide.LooseCrosses(thatSide)) return false; } } return true; }
public bool HasSamePoints(Polygon that) { if (that == null) return false; if (this.points.Count != that.points.Count) return false; return Utilities.EqualSets<Point>(this.points, that.points); }
// // Find the points of intersection of two polygons. // public List<Point> FindIntersections(Polygon that) { List<Point> intersections = new List<Point>(); foreach (Segment thatSide in that.orderedSides) { Point pt1 = null; Point pt2 = null; this.FindIntersection(thatSide, out pt1, out pt2); if (pt1 != null) Utilities.AddStructurallyUnique<Point>(intersections, pt1); if (pt2 != null) Utilities.AddStructurallyUnique<Point>(intersections, pt2); } return intersections; }
/// <summary> /// Parse a regular polygon. (Currently only equilateral triangles) /// </summary> /// <param name="rgon">The regular polygon to parse.</param> private void ParseRegularPolygon(RegularPolygon rgon) { // Acquire the implicit center of the regular polygon IPoint center = rgon.Dependencies.FindPoint(rgon.Center, 0); IPoint vertex = rgon.Dependencies.FindPoint(rgon.Vertex, 0); int numSides = rgon.NumberOfSides; // // Genereate vertex points knowing that the polygon is regular // IPoint[] pts = new IPoint[numSides]; double radius = Math.Distance(vertex.Coordinates.X, center.Coordinates.X, vertex.Coordinates.Y, center.Coordinates.Y); double initAngle = Math.GetAngle(new System.Windows.Point(center.Coordinates.X, center.Coordinates.Y), new System.Windows.Point(vertex.Coordinates.X, vertex.Coordinates.Y)); double increment = Math.DOUBLEPI / numSides; // Vertex point generation and parsing. for (int i = 0; i < numSides - 1; i++) { double angle = initAngle + (i + 1) * increment; double X = center.Coordinates.X + radius * System.Math.Cos(angle); double Y = center.Coordinates.Y + radius * System.Math.Sin(angle); System.Windows.Point newPt = new System.Windows.Point(X, Y); pts[i] = rgon.Dependencies.FindPoint(newPt, 0); if (pts[i] == null) { pts[i] = Factory.CreateFreePoint(drawing, newPt); } Parse(pts[i] as IFigure); } pts[numSides - 1] = vertex; Parse(pts[numSides - 1] as IFigure); // // Generate sides from vertices // List <GeometryTutorLib.ConcreteAST.Segment> tutorSegments = new List <GeometryTutorLib.ConcreteAST.Segment>(); for (int i = 0; i < numSides; i++) { int j = (i + 1) % 3; tutorSegments.Add(new GeometryTutorLib.ConcreteAST.Segment(uiToEngineMap[pts[i]] as Point, uiToEngineMap[pts[j]] as Point)); } definedSegments.AddRange(tutorSegments); GeometryTutorLib.ConcreteAST.Polygon newPoly = null; switch (numSides) { case 3: newPoly = new EquilateralTriangle(tutorSegments); polygons[GeometryTutorLib.ConcreteAST.Polygon.TRIANGLE_INDEX].Add(newPoly); break; case 4: Quadrilateral newQuad = Quadrilateral.GenerateQuadrilateral(tutorSegments); if (newQuad != null) { newPoly = new Rhombus(newQuad); polygons[GeometryTutorLib.ConcreteAST.Polygon.QUADRILATERAL_INDEX].Add(newPoly); } break; case 5: case 6: case 7: case 8: case 9: case 10: break; default: break; } if (newPoly != null) { uiToEngineMap.Add(rgon, newPoly); } }
/// <summary> /// Parse a polygon. (Currently only triangles) /// </summary> /// <param name="pgon">The polygon to parse.</param> private void ParsePolygon(PolygonBase pgon) { // // Handle an n-sided polygon // int numSides = pgon.VertexCoordinates.Length; // // Find verticies // System.Windows.Point[] pts = pgon.VertexCoordinates; IPoint[] iPts = new IPoint[numSides]; // // Parse all points // for (int i = 0; i < numSides; i++) { iPts[i] = pgon.Dependencies.FindPoint(pts[i], 0); Parse(iPts[i] as IFigure); } // // Generate sides // List <GeometryTutorLib.ConcreteAST.Segment> tutorSegments = new List <GeometryTutorLib.ConcreteAST.Segment>(); for (int i = 0; i < numSides; i++) { int j = (i + 1) % numSides; tutorSegments.Add(new GeometryTutorLib.ConcreteAST.Segment(uiToEngineMap[iPts[i]] as GeometryTutorLib.ConcreteAST.Point, uiToEngineMap[iPts[j]] as GeometryTutorLib.ConcreteAST.Point)); } definedSegments.AddRange(tutorSegments); GeometryTutorLib.ConcreteAST.Polygon newPoly = null; switch (numSides) { case 3: newPoly = new Triangle(tutorSegments); polygons[GeometryTutorLib.ConcreteAST.Polygon.TRIANGLE_INDEX].Add(newPoly); break; case 4: newPoly = Quadrilateral.GenerateQuadrilateral(tutorSegments); if (newPoly != null) { polygons[GeometryTutorLib.ConcreteAST.Polygon.QUADRILATERAL_INDEX].Add(newPoly); } break; case 5: case 6: case 7: case 8: case 9: case 10: break; default: break; } if (newPoly != null) { uiToEngineMap.Add(pgon, newPoly); } }
// // All points of the polygon are on or in the sector. // No need to check that any sides of the polygon pass // through the sector since that implies a vertex exterior to the sector. // private bool ContainsPolygon(Polygon that) { foreach (Point thatPt in that.points) { if (!this.PointLiesInOrOn(thatPt)) return false; } foreach (Segment side in that.orderedSides) { if (!this.PointLiesInOrOn(side.Midpoint())) return false; } return true; }
// // Is this polygon stronger than that? // That is, triangle -> isosceles -> equilateral. // public virtual bool IsStrongerThan(Polygon that) { return false; }
private Circle CheckCircleCutInsidePolygon(Polygon poly, Circle circle, Point pt1, Point pt2) { Segment diameter = new Segment(pt1, pt2); // A semicircle always cuts into the polygon. if (circle.DefinesDiameter(diameter)) return circle; else { // Is the midpoint on the interior of the polygon? Point midpt = circle.Midpoint(pt1, pt2); // Is this point in the interior of this polygon? if (poly.IsInPolygon(midpt)) return circle; } return null; }