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;
        }
Beispiel #2
0
        // 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;
        }
Beispiel #4
0
        // 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);
        }
Beispiel #5
0
        // 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);
        }
Beispiel #7
0
        //
        // 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);
        }
Beispiel #8
0
        // 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);
        }
Beispiel #9
0
        // 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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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;
        }
Beispiel #14
0
 //
 // 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;
        }
Beispiel #18
0
        //
        // 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);
        }
Beispiel #20
0
 //
 // 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));
 }
Beispiel #21
0
        //
        // 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;
        }
Beispiel #23
0
        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);
        }
Beispiel #24
0
 //
 // Does this congruent pair of angles apply to this quadrilateral?
 //
 public bool HasOppositeCongruentAngles(CongruentAngles cas)
 {
     return AreOppositeAngles(cas.ca1, cas.ca2);
 }
Beispiel #25
0
        //
        //
        //
        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;
        }
Beispiel #26
0
 //
 // 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);
 }
Beispiel #27
0
        //
        // 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;
        }
Beispiel #34
0
 //
 // 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;
        }