private static List<EdgeAggregator> CheckAndGenerateSupplementaryCongruentImplyRightAngles(Supplementary supplementary, CongruentAngles conAngles) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); //The given pairs must contain the same angles (i.e., the angles must be both supplementary AND congruent) if (!((supplementary.angle1.Equals(conAngles.ca1) && supplementary.angle2.Equals(conAngles.ca2)) || (supplementary.angle2.Equals(conAngles.ca1) && supplementary.angle1.Equals(conAngles.ca2)))) return newGrounded; //if (!(supplementary.StructurallyEquals(conAngles))) return newGrounded; // // Now we have two supplementary and congruent angles, which must be right angles // Strengthened streng = new Strengthened(supplementary.angle1, new RightAngle(supplementary.angle1)); Strengthened streng2 = new Strengthened(supplementary.angle2, new RightAngle(supplementary.angle2)); // Construct hyperedges List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(supplementary); antecedent.Add(conAngles); newGrounded.Add(new EdgeAggregator(antecedent, streng, annotation)); newGrounded.Add(new EdgeAggregator(antecedent, streng2, annotation)); return newGrounded; }
// Return the shared angle in both congruences public Angle AngleShared(CongruentAngles cas) { if (ca1.Equates(cas.ca1) || ca1.Equates(cas.ca2)) return ca1; if (ca2.Equates(cas.ca1) || ca2.Equates(cas.ca2)) return ca2; return null; }
// Return the shared angle in both congruences public Angle AngleShared(CongruentAngles cas) { if (angle1.Equates(cas.ca1) || angle1.Equates(cas.ca2)) return angle1; if (angle2.Equates(cas.ca1) || angle2.Equates(cas.ca2)) return angle2; return null; }
// Return the number of shared angles in both congruences public int SharesNumClauses(CongruentAngles thatCas) { int numShared = smallerAngle.Equals(thatCas.ca1) || smallerAngle.Equals(thatCas.ca2) ? 1 : 0; numShared += largerAngle.Equals(thatCas.ca1) || largerAngle.Equals(thatCas.ca2) ? 1 : 0; return(numShared); }
// Return the shared angle in both congruences public Angle AngleShared(CongruentAngles thatCas) { if (SharesNumClauses(thatCas) != 1) { return(null); } return(smallerAngle.Equals(thatCas.ca1) || smallerAngle.Equals(thatCas.ca2) ? smallerAngle : largerAngle); }
public static bool AcquireCongruences(KnownMeasurementsAggregator known, List <GroundedClause> clauses) { bool addedKnown = false; foreach (GeometryTutorLib.ConcreteAST.GroundedClause clause in clauses) { GeometryTutorLib.ConcreteAST.CongruentSegments cs = clause as GeometryTutorLib.ConcreteAST.CongruentSegments; if (cs != null && !cs.IsReflexive()) { double length1 = known.GetSegmentLength(cs.cs1); double length2 = known.GetSegmentLength(cs.cs2); if (length1 >= 0 && length2 < 0) { if (known.AddSegmentLength(cs.cs2, length1)) { addedKnown = true; } } if (length1 <= 0 && length2 > 0) { if (known.AddSegmentLength(cs.cs1, length2)) { addedKnown = true; } } // else: both known } GeometryTutorLib.ConcreteAST.CongruentAngles cas = clause as GeometryTutorLib.ConcreteAST.CongruentAngles; if (cas != null && !cas.IsReflexive()) { double measure1 = known.GetAngleMeasure(cas.ca1); double measure2 = known.GetAngleMeasure(cas.ca2); if (measure1 >= 0 && measure2 < 0) { if (known.AddAngleMeasureDegree(cas.ca2, measure1)) { addedKnown = true; } } if (measure1 <= 0 && measure2 > 0) { if (known.AddAngleMeasureDegree(cas.ca1, measure2)) { addedKnown = true; } } // else: both known } } return(addedKnown); }
// // If a common segment exists (a transversal that cuts across both intersections), return that common segment // public Angle GetInducedNonStraightAngle(CongruentAngles congAngles) { if (this.InducesNonStraightAngle(congAngles.ca1)) { return(congAngles.ca1); } if (this.InducesNonStraightAngle(congAngles.ca2)) { return(congAngles.ca2); } return(null); }
// Return the shared angle in both congruences public Angle AngleShared(CongruentAngles cas) { if (ca1.Equates(cas.ca1) || ca1.Equates(cas.ca2)) { return(ca1); } if (ca2.Equates(cas.ca1) || ca2.Equates(cas.ca2)) { return(ca2); } return(null); }
// Return the number of shared angles in both congruences public override int SharesNumClauses(Congruent thatCC) { CongruentAngles ccas = thatCC as CongruentAngles; if (ccas == null) { return(0); } int numShared = ca1.Equates(ccas.ca1) || ca1.Equates(ccas.ca2) ? 1 : 0; numShared += ca2.Equates(ccas.ca1) || ca2.Equates(ccas.ca2) ? 1 : 0; return(numShared); }
public static List <GenericInstantiator.EdgeAggregator> CreateTransitiveCongruence(Congruent congruent1, Congruent congruent2) { List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>(); // // Create the antecedent clauses // List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(congruent1); antecedent.Add(congruent2); // // Create the consequent clause // Congruent newCC = null; if (congruent1 is CongruentSegments) { CongruentSegments css1 = congruent1 as CongruentSegments; CongruentSegments css2 = congruent2 as CongruentSegments; Segment shared = css1.SegmentShared(css2); newCC = new AlgebraicCongruentSegments(css1.OtherSegment(shared), css2.OtherSegment(shared)); } else if (congruent1 is CongruentAngles) { CongruentAngles cas1 = congruent1 as CongruentAngles; CongruentAngles cas2 = congruent2 as CongruentAngles; Angle shared = cas1.AngleShared(cas2); newCC = new AlgebraicCongruentAngles(cas1.OtherAngle(shared), cas2.OtherAngle(shared)); } if (newCC == null) { System.Diagnostics.Debug.WriteLine(""); throw new NullReferenceException("Unexpected Problem in Atomic substitution..."); } newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newCC, annotation)); return(newGrounded); }
public override bool StructurallyEquals(Object obj) { CongruentAngles cas = obj as CongruentAngles; if (cas == null) { return(false); } if (!Utilities.CompareValues(this.ca1.measure, cas.ca1.measure)) { return(false); } return((ca1.StructurallyEquals(cas.ca1) && ca2.StructurallyEquals(cas.ca2)) || (ca1.StructurallyEquals(cas.ca2) && ca2.StructurallyEquals(cas.ca1))); }
// // All right angles are supplementary. // public static List<EdgeAggregator> InstantiateToSupplementary(CongruentAngles cas) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); if (cas.IsReflexive()) return newGrounded; if (!(cas.ca1 is RightAngle) || !(cas.ca2 is RightAngle)) return newGrounded; Supplementary supp = new Supplementary(cas.ca1, cas.ca2); supp.SetNotASourceNode(); supp.SetNotAGoalNode(); supp.SetClearDefinition(); newGrounded.Add(new EdgeAggregator(Utilities.MakeList<GroundedClause>(cas), supp, annotation)); return newGrounded; }
private static List<EdgeAggregator> CheckAndGenerateCongruentAdjacentImplyPerpendicular(Intersection intersection, CongruentAngles conAngles) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // The given angles must belong to the intersection. That is, the vertex must align and all rays must overlay the intersection. if (!intersection.InducesBothAngles(conAngles)) return newGrounded; // // Now we have perpendicular scenario // Strengthened streng = new Strengthened(intersection, new Perpendicular(intersection)); // Construct hyperedge List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(intersection); antecedent.Add(conAngles); newGrounded.Add(new EdgeAggregator(antecedent, streng, annotation)); return newGrounded; }
// // Does this congruent pair of angles apply to this quadrilateral? // public bool HasOppositeCongruentAngles(CongruentAngles cas) { return(AreOppositeAngles(cas.ca1, cas.ca2)); }
private static List<EdgeAggregator> IndirectRelations(CongruentAngles cas, AnglePairRelation relation1, AnglePairRelation relation2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Do we have the same type of relation? if (relation1.GetType() != relation2.GetType()) return newGrounded; // // Determine the shared values amongst the relations // Angle shared1 = relation1.AngleShared(cas); if (shared1 == null) return newGrounded; Angle shared2 = cas.OtherAngle(shared1); if (!relation2.HasAngle(shared2)) return newGrounded; Angle otherAngle1 = relation1.OtherAngle(shared1); Angle otherAngle2 = relation2.OtherAngle(shared2); // Avoid generating a reflexive relationship if (otherAngle1.Equates(otherAngle2)) return newGrounded; // // Congruent(Angle(1), Angle(3)) // // The other two angles from the relation pairs are then congruent GeometricCongruentAngles gcas = new GeometricCongruentAngles(otherAngle1, otherAngle2); // Avoid direct cyclic congruent angle generation if (cas.StructurallyEquals(gcas)) return newGrounded; // Construct hyperedge List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(cas); antecedent.Add(relation1); antecedent.Add(relation2); // // AnglePairRelation(Angle(1), Angle(4)), // AnglePairRelation(Angle(2), Angle(3)), // if (relation1 is Complementary && relation2 is Complementary) { Complementary comp1 = new Complementary(shared1, otherAngle2); Complementary comp2 = new Complementary(shared2, otherAngle1); newGrounded.Add(new EdgeAggregator(antecedent, comp1, compAnnotation)); newGrounded.Add(new EdgeAggregator(antecedent, comp2, compAnnotation)); } else if (relation1 is Supplementary && relation2 is Supplementary) { Supplementary supp1 = new Supplementary(shared1, otherAngle2); Supplementary supp2 = new Supplementary(shared2, otherAngle1); newGrounded.Add(new EdgeAggregator(antecedent, supp1, suppAnnotation)); newGrounded.Add(new EdgeAggregator(antecedent, supp2, suppAnnotation)); } else { throw new ArgumentException("RelationsOfCongruent:: Expected a supplementary or complementary angle, not " + relation1.GetType()); } newGrounded.Add(new EdgeAggregator(antecedent, gcas, relation1 is Complementary ? compAnnotation : suppAnnotation)); return newGrounded; }
/// <summary> /// Figure out what possible angle combinations are before showing the window. /// </summary> protected override void OnShow() { options = new Dictionary<Angle, List<Angle>>(); //Get a list of all congruent angle givens List<GroundedClause> cangs = new List<GroundedClause>(); foreach (GroundedClause gc in currentGivens) { CongruentAngles cang = gc as CongruentAngles; if (cang != null) { cangs.Add(cang); } } //Pick a first angle... foreach (Angle a1 in parser.backendParser.implied.angles) { List<Angle> possible = new List<Angle>(); //... and see what other angles are viable second options. foreach (Angle a2 in parser.backendParser.implied.angles) { if (a1.measure == a2.measure) { CongruentAngles cang = new CongruentAngles(a1, a2); if (!a1.StructurallyEquals(a2) && !StructurallyContains(cangs, cang)) { possible.Add(a2); } } } //If we found a possible list of combinations, add it to the dictionary if (possible.Count > 0) { options.Add(a1, possible); } } //Set the options of the angle1 combo box angle1.ItemsSource = null; //Graphical refresh angle1.ItemsSource = options.Keys; }
private static List<EdgeAggregator> InstantiateToTheorem(Quadrilateral quad, CongruentAngles cas1, CongruentAngles cas2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Are the pairs on the opposite side of this quadrilateral? if (!quad.HasOppositeCongruentAngles(cas1)) return newGrounded; if (!quad.HasOppositeCongruentAngles(cas2)) return newGrounded; // // Create the new Rhombus object // Strengthened newParallelogram = new Strengthened(quad, new Parallelogram(quad)); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(quad); antecedent.Add(cas1); antecedent.Add(cas2); newGrounded.Add(new EdgeAggregator(antecedent, newParallelogram, annotation)); return newGrounded; }
// // Checks for AA given the 4 values // private static List<EdgeAggregator> InstantiateAASimilarity(Triangle tri1, Triangle tri2, CongruentAngles cas1, CongruentAngles cas2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // All congruence pairs must minimally relate the triangles // if (!cas1.LinksTriangles(tri1, tri2)) return newGrounded; if (!cas2.LinksTriangles(tri1, tri2)) return newGrounded; // Is this angle an 'extension' of the actual triangle angle? If so, acquire the normalized version of // the angle, using only the triangle vertices to represent the angle Angle angle1Tri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas1)); Angle angle1Tri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas1)); Angle angle2Tri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas2)); Angle angle2Tri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas2)); // The angles for each triangle must be distinct if (angle1Tri1.Equals(angle2Tri1) || angle1Tri2.Equals(angle2Tri2)) return newGrounded; // // Construct the corrsesponding points between the triangles // List<Point> triangleOne = new List<Point>(); List<Point> triangleTwo = new List<Point>(); triangleOne.Add(angle1Tri1.GetVertex()); triangleTwo.Add(angle1Tri2.GetVertex()); triangleOne.Add(angle2Tri1.GetVertex()); triangleTwo.Add(angle2Tri2.GetVertex()); // We know the segment endpoint mappings above, now acquire the opposite point triangleOne.Add(tri1.OtherPoint(new Segment(angle1Tri1.GetVertex(), angle2Tri1.GetVertex()))); triangleTwo.Add(tri2.OtherPoint(new Segment(angle1Tri2.GetVertex(), angle2Tri2.GetVertex()))); // // Construct the new clauses: similar triangles and resultant components // GeometricSimilarTriangles simTris = new GeometricSimilarTriangles(new Triangle(triangleOne), new Triangle(triangleTwo)); // Hypergraph edge List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(tri1); antecedent.Add(tri2); antecedent.Add(cas1); antecedent.Add(cas2); newGrounded.Add(new EdgeAggregator(antecedent, simTris, annotation)); // Add all the corresponding parts as new Similar clauses newGrounded.AddRange(SimilarTriangles.GenerateComponents(simTris, triangleOne, triangleTwo)); return newGrounded; }
// // Just generate the new triangle // private static EdgeAggregator GenerateCongruentSides(Triangle tri, CongruentAngles cas) { GeometricCongruentSegments newConSegs = new GeometricCongruentSegments(tri.OtherSide(cas.ca1), tri.OtherSide(cas.ca2)); List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(cas); antecedent.Add(tri); return new EdgeAggregator(antecedent, newConSegs, annotation); }
// // Are both angles induced by this intersection either as vertical angles or adjacent angles // public bool InducesBothAngles(CongruentAngles conAngles) { return(this.InducesNonStraightAngle(conAngles.ca1) && this.InducesNonStraightAngle(conAngles.ca2)); }
// // Checks for ASA given the 5 values // private static List<EdgeAggregator> InstantiateAAS(Triangle tri1, Triangle tri2, CongruentAngles cas1, CongruentAngles cas2, CongruentSegments css) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // All congruence pairs must minimally relate the triangles // if (!cas1.LinksTriangles(tri1, tri2)) return newGrounded; if (!cas2.LinksTriangles(tri1, tri2)) return newGrounded; if (!css.LinksTriangles(tri1, tri2)) return newGrounded; // Is this angle an 'extension' of the actual triangle angle? If so, acquire the normalized version of // the angle, using only the triangle vertices to represent the angle Angle angle1Tri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas1)); Angle angle1Tri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas1)); Angle angle2Tri1 = tri1.NormalizeAngle(tri1.AngleBelongs(cas2)); Angle angle2Tri2 = tri2.NormalizeAngle(tri2.AngleBelongs(cas2)); // The angles for each triangle must be distinct if (angle1Tri1.Equals(angle2Tri1) || angle1Tri2.Equals(angle2Tri2)) return newGrounded; Segment segTri1 = tri1.GetSegment(css); Segment segTri2 = tri2.GetSegment(css); // ASA situations if (segTri1.IsIncludedSegment(angle1Tri1, angle2Tri1)) return newGrounded; if (segTri2.IsIncludedSegment(angle1Tri2, angle2Tri2)) return newGrounded; // The segments for each triangle must be corresponding if (segTri1.Equals(tri1.OtherSide(angle1Tri1)) && segTri2.Equals(tri2.OtherSide(angle2Tri2))) return newGrounded; if (segTri1.Equals(tri1.OtherSide(angle2Tri1)) && segTri2.Equals(tri2.OtherSide(angle1Tri2))) return newGrounded; // // Construct the corrsesponding points between the triangles // List<Point> triangleOne = new List<Point>(); List<Point> triangleTwo = new List<Point>(); triangleOne.Add(angle1Tri1.GetVertex()); triangleTwo.Add(angle1Tri2.GetVertex()); triangleOne.Add(angle2Tri1.GetVertex()); triangleTwo.Add(angle2Tri2.GetVertex()); // We know the segment endpoint mappings above, now acquire the opposite point triangleOne.Add(tri1.OtherPoint(angle1Tri1.GetVertex(), angle2Tri1.GetVertex())); triangleTwo.Add(tri2.OtherPoint(angle1Tri2.GetVertex(), angle2Tri2.GetVertex())); // // Construct the new clauses: congruent triangles and CPCTC // GeometricCongruentTriangles gcts = new GeometricCongruentTriangles(new Triangle(triangleOne), new Triangle(triangleTwo)); // Hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(tri1); antecedent.Add(tri2); antecedent.Add(cas1); antecedent.Add(cas2); antecedent.Add(css); newGrounded.Add(new EdgeAggregator(antecedent, gcts, annotation)); // Add all the corresponding parts as new congruent clauses newGrounded.AddRange(CongruentTriangles.GenerateCPCTC(gcts, triangleOne, triangleTwo)); return newGrounded; }
public static List<GenericInstantiator.EdgeAggregator> CreateTransitiveProportion(ProportionalAngles pss, CongruentAngles conAngs) { List<GenericInstantiator.EdgeAggregator> newGrounded = new List<GenericInstantiator.EdgeAggregator>(); //// Did either of these proportions come from the other? //if (pss.HasRelationPredecessor(conAngs) || conAngs.HasRelationPredecessor(pss)) return newGrounded; // // Create the antecedent clauses // List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(pss); antecedent.Add(conAngs); // // Create the consequent clause // Angle shared = pss.AngleShared(conAngs); AlgebraicProportionalAngles newPS = new AlgebraicProportionalAngles(pss.OtherAngle(shared), conAngs.OtherAngle(shared)); // Update relationship among the congruence pairs to limit cyclic information generation //newPS.AddPredecessor(pss); //newPS.AddPredecessor(conAngs); newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newPS, propAnnotation)); return newGrounded; }
public static List <GenericInstantiator.EdgeAggregator> CreateTransitiveProportion(ProportionalAngles pss, CongruentAngles conAngs) { List <GenericInstantiator.EdgeAggregator> newGrounded = new List <GenericInstantiator.EdgeAggregator>(); //// Did either of these proportions come from the other? //if (pss.HasRelationPredecessor(conAngs) || conAngs.HasRelationPredecessor(pss)) return newGrounded; // // Create the antecedent clauses // List <GroundedClause> antecedent = new List <GroundedClause>(); antecedent.Add(pss); antecedent.Add(conAngs); // // Create the consequent clause // Angle shared = pss.AngleShared(conAngs); AlgebraicProportionalAngles newPS = new AlgebraicProportionalAngles(pss.OtherAngle(shared), conAngs.OtherAngle(shared)); // Update relationship among the congruence pairs to limit cyclic information generation //newPS.AddPredecessor(pss); //newPS.AddPredecessor(conAngs); newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newPS, propAnnotation)); return(newGrounded); }
// // Does this congruent pair of angles apply to this quadrilateral? // public bool HasOppositeCongruentAngles(CongruentAngles cas) { return AreOppositeAngles(cas.ca1, cas.ca2); }
// // // private static List<EdgeAggregator> CollectAndCheckSAS(Triangle ct1, Triangle ct2, CongruentAngles cas, SegmentRatioEquation sre) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Proportions must actually equate //if (!pss1.ProportionallyEquals(pss2)) return newGrounded; //// The smaller and larger segments of the proportionality must be distinct, respectively. //if (!pss1.IsDistinctFrom(pss2)) return newGrounded; // The proportional relationships need to link the given triangles if (!cas.LinksTriangles(ct1, ct2)) return newGrounded; if (!sre.LinksTriangles(ct1, ct2)) return newGrounded; //if (!pss1.LinksTriangles(ct1, ct2)) return newGrounded; //if (!pss2.LinksTriangles(ct1, ct2)) return newGrounded; // The smaller segments must belong to one triangle, same for larger segments. //if (!(ct1.HasSegment(pss1.smallerSegment) && ct1.HasSegment(pss2.smallerSegment) && // ct2.HasSegment(pss1.largerSegment) && ct2.HasSegment(pss2.largerSegment)) && // !(ct2.HasSegment(pss1.smallerSegment) && ct2.HasSegment(pss2.smallerSegment) && // ct1.HasSegment(pss1.largerSegment) && ct1.HasSegment(pss2.largerSegment))) // return newGrounded; KeyValuePair<Segment, Segment> segsTri1 = sre.GetSegments(ct1); KeyValuePair<Segment, Segment> segsTri2 = sre.GetSegments(ct2); //Segment seg1Tri1 = ct1.GetSegment(pss1); //Segment seg2Tri1 = ct1.GetSegment(pss2); //Segment seg1Tri2 = ct2.GetSegment(pss1); //Segment seg2Tri2 = ct2.GetSegment(pss2); // Avoid redundant segments, if they arise if (segsTri1.Key.StructurallyEquals(segsTri1.Value)) return newGrounded; if (segsTri2.Key.StructurallyEquals(segsTri2.Value)) return newGrounded; //if (seg1Tri1.StructurallyEquals(seg2Tri1)) return newGrounded; //if (seg1Tri2.StructurallyEquals(seg2Tri2)) return newGrounded; Angle angleTri1 = ct1.AngleBelongs(cas); Angle angleTri2 = ct2.AngleBelongs(cas); // Check both triangles if this is the included angle; if it is, we have SAS if (!angleTri1.IsIncludedAngle(segsTri1.Key, segsTri1.Value)) return newGrounded; if (!angleTri2.IsIncludedAngle(segsTri2.Key, segsTri2.Value)) return newGrounded; // // Generate Similar Triangles // Point vertex1 = angleTri1.GetVertex(); Point vertex2 = angleTri2.GetVertex(); // Construct a list of pairs to return; this is the correspondence from triangle 1 to triangle 2 List<KeyValuePair<Point, Point>> pairs = new List<KeyValuePair<Point, Point>>(); // The vertices of the angles correspond pairs.Add(new KeyValuePair<Point, Point>(vertex1, vertex2)); // For the segments, look at the congruences and select accordingly pairs.Add(new KeyValuePair<Point, Point>(segsTri1.Key.OtherPoint(vertex1), segsTri2.Key.OtherPoint(vertex2))); pairs.Add(new KeyValuePair<Point, Point>(segsTri1.Value.OtherPoint(vertex1), segsTri2.Value.OtherPoint(vertex2))); List<GroundedClause> simTriAntecedent = new List<GroundedClause>(); simTriAntecedent.Add(ct1); simTriAntecedent.Add(ct2); simTriAntecedent.Add(cas); simTriAntecedent.Add(sre); newGrounded.AddRange(GenerateCorrespondingParts(pairs, simTriAntecedent, annotation)); return newGrounded; }
// // Are both angles induced by this intersection either as vertical angles or adjacent angles // public bool InducesBothAngles(CongruentAngles conAngles) { return this.InducesNonStraightAngle(conAngles.ca1) && this.InducesNonStraightAngle(conAngles.ca2); }
// // If a common segment exists (a transversal that cuts across both intersections), return that common segment // public Angle GetInducedNonStraightAngle(CongruentAngles congAngles) { if (this.InducesNonStraightAngle(congAngles.ca1)) return congAngles.ca1; if (this.InducesNonStraightAngle(congAngles.ca2)) return congAngles.ca2; return null; }
// // Construct the AngleBisector if we have // // V---------------A // / \ // / \ // / \ // B C // // Congruent(Angle, A, V, C), Angle(C, V, B)), Segment(V, C)) -> AngleBisector(Angle(A, V, B) // // private static List<EdgeAggregator> InstantiateToDef(CongruentAngles cas, Segment segment) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // Find the shared segment between the two angles; we know it is valid if we reach this point Segment shared = cas.AreAdjacent(); // The bisector must align with the given segment if (!segment.IsCollinearWith(shared)) return newGrounded; // We need a true bisector in which the shared vertex of the angles in between the endpoints of this segment if (!segment.PointLiesOnAndBetweenEndpoints(cas.ca1.GetVertex())) return newGrounded; // // Create the overall angle which is being bisected // Point vertex = cas.ca1.GetVertex(); Segment newRay1 = cas.ca1.OtherRayEquates(shared); Segment newRay2 = cas.ca2.OtherRayEquates(shared); Angle combinedAngle = new Angle(newRay1.OtherPoint(vertex), vertex, newRay2.OtherPoint(vertex)); // Determine if the segment is a straight angle (we don't want an angle bisector here, we would want a segment bisector) if (newRay1.IsCollinearWith(newRay2)) return newGrounded; // The bisector cannot be of the form: // \ // \ // V---------------A // / // / // B if (!combinedAngle.IsOnInteriorExplicitly(segment.Point1) && !combinedAngle.IsOnInteriorExplicitly(segment.Point2)) return newGrounded; AngleBisector newAB = new AngleBisector(combinedAngle, segment); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(segment); antecedent.Add(cas); newGrounded.Add(new EdgeAggregator(antecedent, newAB, annotation)); return newGrounded; }
// A // /) // / ) // / ) // center: O ) // \ ) // \ ) // \) // C // // D // /) // / ) // / ) // center: Q ) // \ ) // \ ) // \) // F // // Congruent(Angle(AOC), Angle(DQF)) -> Congruent(Arc(A, C), Arc(D, F)) // private static List<EdgeAggregator> InstantiateForwardPartOfTheorem(CongruentAngles cas) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // // Determine if the angles are central angles. // List<Circle> circles1 = Circle.IsCentralAngle(cas.ca1); //Circle circle1 = null; Circle.IsCentralAngle(cas.ca1); if (!circles1.Any()) return newGrounded; List<Circle> circles2 = Circle.IsCentralAngle(cas.ca2); //Circle circle2 = null; Circle.IsCentralAngle(cas.ca2); if (!circles2.Any()) return newGrounded; //Construct arc congruences between congruent circles foreach (Circle c1 in circles1) { foreach (Circle c2 in circles2) { if (c1.radius == c2.radius) { Arc a1 = Arc.GetInterceptedArc(c1, cas.ca1); Arc a2 = Arc.GetInterceptedArc(c2, cas.ca2); if (a1 != null & a2 != null) { GeometricCongruentArcs gcas = new GeometricCongruentArcs(a1, a2); // For hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(a1); antecedent.Add(a2); antecedent.Add(cas); newGrounded.Add(new EdgeAggregator(antecedent, gcas, forwardAnnotation)); } } } } // // Construct the arc congruence by acquiring the arc endpoints. // //Point endpt11, endpt12, garbage; //circle1.FindIntersection(cas.ca1.ray1, out endpt11, out garbage); //if (endpt11 == null) return newGrounded; //circle1.FindIntersection(cas.ca1.ray2, out endpt12, out garbage); //if (endpt12 == null) return newGrounded; //Point endpt21, endpt22; //circle1.FindIntersection(cas.ca2.ray1, out endpt21, out garbage); //if (endpt21 == null) return newGrounded; //circle1.FindIntersection(cas.ca2.ray2, out endpt22, out garbage); //if (endpt22 == null) return newGrounded; //Arc arc1 = Arc.GetFigureMinorArc(circle1, endpt11, endpt12); //Arc arc2 = Arc.GetFigureMinorArc(circle2, endpt21, endpt22); //if (arc1 == null || arc2 == null) return newGrounded; return newGrounded; }
// Return the shared angle in both congruences public Angle AngleShared(CongruentAngles thatCas) { if (SharesNumClauses(thatCas) != 1) return null; return smallerAngle.Equals(thatCas.ca1) || smallerAngle.Equals(thatCas.ca2) ? smallerAngle : largerAngle; }
// // Implements 'transitivity' with right angles; that is, we may know two angles are congruent and if one is a right angle, the other is well // // Congruent(Angle(A, B, C), Angle(D, E, F), RightAngle(A, B, C) -> RightAngle(D, E, F) // public static List<EdgeAggregator> InstantiateToRightAngle(RightAngle ra, CongruentAngles cas, GroundedClause original) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // The congruent must have the given angle in order to generate if (!cas.HasAngle(ra)) return newGrounded; Angle toBeRight = cas.OtherAngle(ra); Strengthened newRightAngle = new Strengthened(toBeRight, new RightAngle(toBeRight)); List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(original); antecedent.Add(cas); newGrounded.Add(new EdgeAggregator(antecedent, newRightAngle, transAnnotation)); return newGrounded; }
private static List<EdgeAggregator> CheckAndGenerateCorrespondingAnglesImplyParallel(Intersection inter1, Intersection inter2, CongruentAngles conAngles) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // The two intersections should not be at the same vertex if (inter1.intersect.Equals(inter2.intersect)) return newGrounded; Segment transversal = inter1.CommonSegment(inter2); if (transversal == null) return newGrounded; Angle angleI = inter1.GetInducedNonStraightAngle(conAngles); Angle angleJ = inter2.GetInducedNonStraightAngle(conAngles); // // Do we have valid intersections and congruent angle pairs // if (angleI == null || angleJ == null) return newGrounded; // // Check to see if they are, in fact, Corresponding Angles // Segment parallelCand1 = inter1.OtherSegment(transversal); Segment parallelCand2 = inter2.OtherSegment(transversal); // The resultant candidate parallel segments shouldn't share any vertices if (parallelCand1.SharedVertex(parallelCand2) != null) return newGrounded; // Numeric hack to discount any non-parallel segments if (!parallelCand1.IsParallelWith(parallelCand2)) return newGrounded; // A sanity check that the '4th' point does not lie on the other intersection (thus creating an obvious triangle and thus not parallel lines) Point fourthPoint1 = parallelCand1.OtherPoint(inter1.intersect); Point fourthPoint2 = parallelCand2.OtherPoint(inter2.intersect); if (fourthPoint1 != null && fourthPoint2 != null) { if (parallelCand1.PointLiesOn(fourthPoint2) || parallelCand2.PointLiesOn(fourthPoint1)) return newGrounded; } // Both angles should NOT be in the interioir OR the exterioir; a combination is needed. bool ang1Interior = angleI.OnInteriorOf(inter1, inter2); bool ang2Interior = angleJ.OnInteriorOf(inter1, inter2); if (ang1Interior && ang2Interior) return newGrounded; if (!ang1Interior && !ang2Interior) return newGrounded; // // Are these angles on the same side of the transversal? // // // Make a simple transversal from the two intersection points Segment simpleTransversal = new Segment(inter1.intersect, inter2.intersect); // Find the rays the lie on the transversal Segment rayNotOnTransversalI = angleI.OtherRayEquates(simpleTransversal); Segment rayNotOnTransversalJ = angleJ.OtherRayEquates(simpleTransversal); Point pointNotOnTransversalNorVertexI = rayNotOnTransversalI.OtherPoint(angleI.GetVertex()); Point pointNotOnTransversalNorVertexJ = rayNotOnTransversalJ.OtherPoint(angleJ.GetVertex()); // Create a segment from these two points so we can compare distances Segment crossing = new Segment(pointNotOnTransversalNorVertexI, pointNotOnTransversalNorVertexJ); // // Will this crossing segment actually intersect the real transversal in the middle of the two segments It should NOT. // Point intersection = transversal.FindIntersection(crossing); if (Segment.Between(intersection, inter1.intersect, inter2.intersect)) return newGrounded; // // Now we have an alternate interior scenario // GeometricParallel newParallel = new GeometricParallel(parallelCand1, parallelCand2); // Construct hyperedge List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(inter1); antecedent.Add(inter2); antecedent.Add(conAngles); newGrounded.Add(new EdgeAggregator(antecedent, newParallel, annotation)); return newGrounded; }
// Return the number of shared angles in both congruences public int SharesNumClauses(CongruentAngles thatCas) { int numShared = smallerAngle.Equals(thatCas.ca1) || smallerAngle.Equals(thatCas.ca2) ? 1 : 0; numShared += largerAngle.Equals(thatCas.ca1) || largerAngle.Equals(thatCas.ca2) ? 1 : 0; return numShared; }
// // Acquire the particular angle which belongs to this triangle (of a congruence) // public Angle AngleBelongs(CongruentAngles ccas) { if (HasAngle(ccas.ca1)) return ccas.ca1; if (HasAngle(ccas.ca2)) return ccas.ca2; return null; }
// // Acquires all of the applicable congruent segments as well as congruent angles. Then checks for SAS // private static List<EdgeAggregator> CheckAndGenerateThirdCongruentPair(Triangle tri1, Triangle tri2, CongruentAngles cas1, CongruentAngles cas2) { List<EdgeAggregator> newGrounded = new List<EdgeAggregator>(); // We have eliminated all reflexive relationships at this point // The congruent relations should not share any angles if (cas1.AngleShared(cas2) != null) return newGrounded; // Both congruent pairs of angles must relate both triangles if (!cas1.LinksTriangles(tri1, tri2)) return newGrounded; if (!cas2.LinksTriangles(tri1, tri2)) return newGrounded; Angle firstAngleTri1 = tri1.AngleBelongs(cas1); Angle secondAngleTri1 = tri1.AngleBelongs(cas2); Angle firstAngleTri2 = tri2.AngleBelongs(cas1); Angle secondAngleTri2 = tri2.AngleBelongs(cas2); Angle thirdAngle1 = tri1.OtherAngle(firstAngleTri1, secondAngleTri1); Angle thirdAngle2 = tri2.OtherAngle(firstAngleTri2, secondAngleTri2); CongruentAngles newCas = new CongruentAngles(thirdAngle1, thirdAngle2); // Hypergraph List<GroundedClause> antecedent = new List<GroundedClause>(); antecedent.Add(tri1); antecedent.Add(tri2); antecedent.Add(cas1); antecedent.Add(cas2); newGrounded.Add(new EdgeAggregator(antecedent, newCas, annotation)); return newGrounded; }