private static List<EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); if (!Utilities.CompareValues(angle1.measure + angle2.measure, 90)) return newGrounded; // The perpendicular intersection must occur at the same vertex of both angles (we only need check one). if (!(angle1.GetVertex().Equals(perp.intersect) && angle2.GetVertex().Equals(perp.intersect))) return newGrounded; // Are the angles adjacent? Segment sharedRay = angle1.IsAdjacentTo(angle2); if (sharedRay == null) return newGrounded; // Do the non-shared rays for both angles align with the segments defined by the perpendicular intersection? if (!perp.DefinesBothRays(angle1.OtherRayEquates(sharedRay), angle2.OtherRayEquates(sharedRay))) return newGrounded; // // Now we have perpendicular -> complementary angles scenario // Complementary cas = new Complementary(angle1, angle2); // Construct hyperedge List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(perp); antecedent.Add(angle1); antecedent.Add(angle2); newGrounded.Add(new EdgeAggregator(antecedent, cas, annotation)); return newGrounded; }
public override bool StructurallyEquals(Object obj) { Perpendicular perp = obj as Perpendicular; if (perp == null) { return(false); } return(intersect.Equals(perp.intersect) && ((lhs.StructurallyEquals(perp.lhs) && rhs.StructurallyEquals(perp.rhs)) || (lhs.StructurallyEquals(perp.rhs) && rhs.StructurallyEquals(perp.lhs)))); }
public override bool CanBeStrengthenedTo(GroundedClause gc) { Perpendicular perp = gc as Perpendicular; if (perp == null) { return(false); } return(intersect.Equals(perp.intersect) && ((lhs.StructurallyEquals(perp.lhs) && rhs.StructurallyEquals(perp.rhs)) || (lhs.StructurallyEquals(perp.rhs) && rhs.StructurallyEquals(perp.lhs)))); }
public override bool Equals(Object obj) { if (obj is PerpendicularBisector) { return((obj as PerpendicularBisector).Equals(this)); } Perpendicular p = obj as Perpendicular; if (p == null) { return(false); } return(intersect.Equals(p.intersect) && lhs.Equals(p.lhs) && rhs.Equals(p.rhs)); }
private static List<EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); if (!Utilities.CompareValues(angle1.measure, angle2.measure)) return newGrounded; // The given angles must belong to the intersection. That is, the vertex must align and all rays must overlay the intersection. if (!(perp.InducesNonStraightAngle(angle1) && perp.InducesNonStraightAngle(angle1))) return newGrounded; // // Now we have perpendicular -> congruent angles scenario // GeometricCongruentAngles gcas = new GeometricCongruentAngles(angle1, angle2); // Construct hyperedge List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(perp); antecedent.Add(angle1); antecedent.Add(angle2); newGrounded.Add(new EdgeAggregator(antecedent, gcas, annotation)); return newGrounded; }
private static List<EdgeAggregator> InstantiateToAltitude(Triangle triangle, Perpendicular perp, GroundedClause original) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Acquire the side of the triangle containing the intersection point // This point may or may not be directly on the triangle side Segment baseSegment = triangle.GetSegmentWithPointOnOrExtends(perp.intersect); if (baseSegment == null) return newGrounded; // The altitude must pass through the intersection point as well as the opposing vertex Point oppositeVertex = triangle.OtherPoint(baseSegment); Segment altitude = new Segment(perp.intersect, oppositeVertex); // The alitude must alig with the intersection if (!perp.ImpliesRay(altitude)) return newGrounded; // The opposing side must align with the intersection if (!perp.OtherSegment(altitude).IsCollinearWith(baseSegment)) return newGrounded; // // Create the new Altitude object // Altitude newAltitude = new Altitude(triangle, altitude); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(triangle); antecedent.Add(original); newGrounded.Add(new EdgeAggregator(antecedent, newAltitude, annotation)); // // Check if this induces a second altitude for a right triangle (although we don't know this is a strengthened triangle) // The intersection must be on the vertex of the triangle if (triangle.HasPoint(perp.intersect)) { Angle possRightAngle = new Angle(triangle.OtherPoint(new Segment(perp.intersect, oppositeVertex)), perp.intersect, oppositeVertex); if (triangle.HasAngle(possRightAngle)) { Altitude secondAltitude = new Altitude(triangle, new Segment(perp.intersect, oppositeVertex)); newGrounded.Add(new EdgeAggregator(antecedent, secondAltitude, annotation)); } } return newGrounded; }
private static List<EdgeAggregator> CheckAndGeneratePerpendicular(Perpendicular perp, Parallel parallel, Intersection inter, GroundedClause original) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // The perpendicular intersection must refer to one of the parallel segments Segment shared = perp.CommonSegment(parallel); if (shared == null) return newGrounded; // The other intersection must refer to a segment in the parallel pair Segment otherShared = inter.CommonSegment(parallel); if (otherShared == null) return newGrounded; // The two shared segments must be distinct if (shared.Equals(otherShared)) return newGrounded; // Transversals must align if (!inter.OtherSegment(otherShared).Equals(perp.OtherSegment(shared))) return newGrounded; // Strengthen the old intersection to be perpendicular Strengthened strengthenedPerp = new Strengthened(inter, new Perpendicular(inter)); // Construct hyperedge List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(original); antecedent.Add(parallel); antecedent.Add(inter); newGrounded.Add(new EdgeAggregator(antecedent, strengthenedPerp, annotation)); return newGrounded; }
// ) | B // ) | // O )| S // ) | // ) | // ) | A // Tangent(Circle(O, R), Segment(A, B)), Intersection(OS, AB) -> Perpendicular(Segment(A,B), Segment(O, S)) // private static List<EdgeAggregator> InstantiateTheorem(CircleSegmentIntersection inter, Perpendicular perp, GroundedClause original) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // The intersection points must be the same. if (!inter.intersect.StructurallyEquals(perp.intersect)) return newGrounded; // Get the radius - if it exists Segment radius = null; Segment garbage = null; inter.GetRadii(out radius, out garbage); if (radius == null) return newGrounded; // Two intersections, not a tangent situation. if (garbage != null) return newGrounded; // The radius can't be the same as the Circ-Inter segment. if (inter.segment.HasSubSegment(radius)) return newGrounded; // Does this perpendicular apply to this Arc intersection? if (!perp.HasSegment(radius) || !perp.HasSegment(inter.segment)) return newGrounded; Strengthened newTangent = new Strengthened(inter, new Tangent(inter)); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(original); antecedent.Add(inter); newGrounded.Add(new EdgeAggregator(antecedent, newTangent, annotation)); return newGrounded; }
// A // |) // | ) // | ) // Q------- O---X---) D // | ) // | ) // |) // C // // Perpendicular(Segment(Q, D), Segment(A, C)) -> Congruent(Arc(A, D), Arc(D, C)) -> Congruent(Segment(AX), Segment(XC)) // private static List<EdgeAggregator> InstantiateTheorem(Intersection inter, CircleSegmentIntersection arcInter, Perpendicular perp, GroundedClause original) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // Does this intersection apply to this perpendicular? // if (!inter.intersect.StructurallyEquals(perp.intersect)) return newGrounded; // Is this too restrictive? if (!((inter.HasSegment(perp.lhs) && inter.HasSegment(perp.rhs)) && (perp.HasSegment(inter.lhs) && perp.HasSegment(inter.rhs)))) return newGrounded; // // Does this perpendicular intersection apply to a given circle? // // Acquire the circles for which the segments are secants. List<Circle> secantCircles1 = Circle.GetSecantCircles(perp.lhs); List<Circle> secantCircles2 = Circle.GetSecantCircles(perp.rhs); List<Circle> intersection = Utilities.Intersection<Circle>(secantCircles1, secantCircles2); if (!intersection.Any()) return newGrounded; // // Find the single, unique circle that has as chords the components of the perpendicular intersection // Circle theCircle = null; Segment chord1 = null; Segment chord2 = null; foreach (Circle circle in intersection) { chord1 = circle.GetChord(perp.lhs); chord2 = circle.GetChord(perp.rhs); if (chord1 != null && chord2 != null) { theCircle = circle; break; } } Segment diameter = chord1.Length > chord2.Length ? chord1 : chord2; Segment chord = chord1.Length < chord2.Length ? chord1 : chord2; // // Does the arc intersection apply? // if (!arcInter.HasSegment(diameter)) return newGrounded; if (!theCircle.StructurallyEquals(arcInter.theCircle)) return newGrounded; // // Create the bisector // Strengthened sb = new Strengthened(inter, new SegmentBisector(inter, diameter)); Strengthened ab = new Strengthened(arcInter, new ArcSegmentBisector(arcInter)); // For hypergraph List<GroundedClause> antecedentArc = new List<GroundedClause>(); antecedentArc.Add(arcInter); antecedentArc.Add(original); antecedentArc.Add(theCircle); newGrounded.Add(new EdgeAggregator(antecedentArc, ab, annotation)); List<GroundedClause> antecedentSegment = new List<GroundedClause>(); antecedentSegment.Add(inter); antecedentSegment.Add(original); antecedentSegment.Add(theCircle); newGrounded.Add(new EdgeAggregator(antecedentSegment, sb, annotation)); return newGrounded; }
// // Perpendicular(B, Segment(A, B), Segment(B, C)) -> RightAngle(), RightAngle() // private static List<EdgeAggregator> InstantiateFromPerpendicular(GroundedClause original, Perpendicular perp) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(original); // top // | // |_ // |_|____ right if (perp.StandsOnEndpoint()) { Point top = perp.lhs.OtherPoint(perp.intersect); Point right = perp.rhs.OtherPoint(perp.intersect); Strengthened streng = new Strengthened(new Angle(top, perp.intersect, right), new RightAngle(top, perp.intersect, right)); newGrounded.Add(new EdgeAggregator(antecedent, streng, annotation)); } // top // | // |_ // left ____|_|____ right else if (perp.StandsOn()) { Point top = perp.lhs.Point1; Point center = perp.intersect; Point left = perp.rhs.Point1; Point right = perp.rhs.Point2; if (perp.lhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect)) { left = perp.lhs.Point1; right = perp.lhs.Point2; top = perp.rhs.OtherPoint(perp.intersect); } else if (perp.rhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect)) { left = perp.rhs.Point1; right = perp.rhs.Point2; top = perp.lhs.OtherPoint(perp.intersect); } else return newGrounded; Strengthened topRight = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right)); Strengthened topLeft = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left)); newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation)); } // top // | // |_ // left ____|_|____ right // | // | // bottom else if (perp.Crossing()) { Point top = perp.lhs.Point1; Point bottom = perp.lhs.Point2; Point center = perp.intersect; Point left = perp.rhs.Point1; Point right = perp.rhs.Point2; Strengthened topRight = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right)); Strengthened bottomRight = new Strengthened(new Angle(right, center, bottom), new RightAngle(right, center, bottom)); Strengthened bottomLeft = new Strengthened(new Angle(left, center, bottom), new RightAngle(left, center, bottom)); Strengthened topLeft = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left)); newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, bottomRight, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, bottomLeft, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation)); } else return newGrounded; return newGrounded; }