public KeyValuePair<Segment, Segment> GetSegments(Triangle tri)
        {
            // Collect the applicable segments.
            List<Segment> theseSegments = new List<Segment>();
            foreach (Segment segment in segments)
            {
                if (tri.HasSegment(segment)) theseSegments.Add(segment);
            }

            // Check for error condition
            if (theseSegments.Count != 2) return new KeyValuePair<Segment, Segment>(null, null);

            // Place the larger segment first
            KeyValuePair<Segment, Segment> pair;
            if (theseSegments[0].Length > theseSegments[1].Length)
            {
                pair = new KeyValuePair<Segment, Segment>(theseSegments[0], theseSegments[1]);
            }
            else
            {
                pair = new KeyValuePair<Segment, Segment>(theseSegments[1], theseSegments[0]);
            }

            return pair;
        }
        public EquilateralTriangle(Triangle t)
            : base(t.SegmentA, t.SegmentB, t.SegmentC)
        {
            if (!Utilities.CompareValues(t.SegmentA.Length, t.SegmentB.Length))
            {
                throw new ArgumentException("Equilateral Triangle constructed with non-congruent segments " + t.SegmentA.ToString() + " " + t.SegmentB.ToString());
            }

            if (!Utilities.CompareValues(t.SegmentA.Length, t.SegmentC.Length))
            {
                throw new ArgumentException("Equilateral Triangle constructed with non-congruent segments " + t.SegmentA.ToString() + " " + t.SegmentC.ToString());
            }

            if (!Utilities.CompareValues(t.SegmentB.Length, t.SegmentC.Length))
            {
                throw new ArgumentException("Equilateral Triangle constructed with non-congruent segments " + t.SegmentB.ToString() + " " + t.SegmentC.ToString());
            }

            provenIsosceles = true;
            provenEquilateral = true;

            // Need to capture all owners as well; if a triangle is strengthened.
            this.AddAtomicRegions(t.atoms);
            this.GetFigureAsAtomicRegion().AddOwners(t.GetFigureAsAtomicRegion().owners);
        }
Exemple #3
0
        public RightTriangle(Triangle t)
            : base(t.SegmentA, t.SegmentB, t.SegmentC)
        {
            provenRight = true;

            rightAngle = Utilities.CompareValues(AngleA.measure, 90) ? AngleA : rightAngle;
            rightAngle = Utilities.CompareValues(AngleB.measure, 90) ? AngleB : rightAngle;
            rightAngle = Utilities.CompareValues(AngleC.measure, 90) ? AngleC : rightAngle;
        }
        //
        // We know at this point that we have a right triangle
        //
        private static List<EdgeAggregator> InstantiateRightTriangle(Triangle tri, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            KeyValuePair<Angle, Angle> acuteAngles = tri.GetAcuteAngles();

            Complementary newComp = new Complementary(acuteAngles.Key, acuteAngles.Value);

            // Hypergraph
            List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(original);

            newGrounded.Add(new EdgeAggregator(antecedent, newComp, annotation));

            return newGrounded;
        }
Exemple #5
0
        //
        // Split the quadrilateral into two triangles and compute the area.
        //
        public override double CoordinatizedArea()
        {
            Point shared1 = orderedSides[0].SharedVertex(orderedSides[1]);
            Segment diagonal1 = new Segment(orderedSides[0].OtherPoint(shared1), orderedSides[1].OtherPoint(shared1));
            Triangle tri1 = new Triangle(orderedSides[0], orderedSides[1], diagonal1);

            Point shared2 = orderedSides[2].SharedVertex(orderedSides[3]);
            Segment diagonal2 = new Segment(orderedSides[2].OtherPoint(shared2), orderedSides[3].OtherPoint(shared2));
            Triangle tri2 = new Triangle(orderedSides[2], orderedSides[3], diagonal2);

            double area1 = tri1.CoordinatizedArea();
            double area2 = tri2.CoordinatizedArea();

            return area1 + area2;
        }
        //
        // Just generate the new angle congruence
        //
        private static List<EdgeAggregator> InstantiateToCongruence(Triangle tri, CongruentSegments css)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            if (!tri.HasSegment(css.cs1) || !tri.HasSegment(css.cs2)) return newGrounded;

            GeometricCongruentAngles newConAngs = new GeometricCongruentAngles(tri.GetOppositeAngle(css.cs1), tri.GetOppositeAngle(css.cs2));

            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(css);
            antecedent.Add(tri);

            newGrounded.Add(new EdgeAggregator(antecedent, newConAngs, annotation));

            return newGrounded;
        }
        public Page146Problem12(bool onoff, bool complete)
            : base(onoff, complete)
        {
            problemName = "Page 146 Problem 12";

            Point l = new Point("L", 0, 5); points.Add(l);
            Point m = new Point("M", 2, 0); points.Add(m);
            Point n = new Point("N", 6, 0); points.Add(n);
            Point x = new Point("X", 0, 0); points.Add(x);

            Point r = new Point("R", 10, 5); points.Add(r);
            Point s = new Point("S", 12, 0); points.Add(s);
            Point t = new Point("T", 16, 0); points.Add(t);
            Point y = new Point("Y", 10, 0); points.Add(y);

            Segment lm = new Segment(l, m); segments.Add(lm);
            Segment ln = new Segment(l, n); segments.Add(ln);
            Segment lx = new Segment(l, x); segments.Add(lx);
            Segment rs = new Segment(r, s); segments.Add(rs);
            Segment rt = new Segment(r, t); segments.Add(rt);
            Segment ry = new Segment(r, y); segments.Add(ry);

            List<Point> pts = new List<Point>();
            pts.Add(x);
            pts.Add(m);
            pts.Add(n);
            collinear.Add(new Collinear(pts));

            pts = new List<Point>();
            pts.Add(y);
            pts.Add(s);
            pts.Add(t);
            collinear.Add(new Collinear(pts));

            Triangle tOne = new Triangle(l, m, n);
            Triangle tTwo = new Triangle(r, s, t);

                        parser = new LiveGeometry.TutorParser.HardCodedParserMain(points, collinear, segments, circles, onoff);

            given.Add(new GeometricCongruentTriangles((Triangle)parser.Get(tOne), (Triangle)parser.Get(tTwo)));
            given.Add(new Altitude((Triangle)parser.Get(tOne), lx));
            given.Add(new Altitude((Triangle)parser.Get(tTwo), ry));

            goals.Add(new GeometricCongruentSegments(lx, ry));
        }
        private static EdgeAggregator ConstructExteriorRelationship(Triangle tri, Angle extAngle)
        {
            //
            // Acquire the remote angles
            //
            Angle remote1 = null;
            Angle remote2 = null;

            tri.AcquireRemoteAngles(extAngle.GetVertex(), out remote1, out remote2);

            //
            // Construct the new equation
            //
            Addition sum = new Addition(remote1, remote2);
            GeometricAngleEquation eq = new GeometricAngleEquation(extAngle, sum);

            //
            // For the hypergraph
            //
            List<GroundedClause> antecedent = Utilities.MakeList<GroundedClause>(tri);
            antecedent.Add(extAngle);

            return new EdgeAggregator(antecedent, eq, annotation);
        }
Exemple #9
0
 public bool WasDeducedCongruent(Triangle that)
 {
     return congruencePairs.Contains(that);
 }
Exemple #10
0
        public Segment SharesSide(Triangle cs)
        {
            if (SegmentA.Equals(cs.SegmentA) || SegmentA.Equals(cs.SegmentB) || SegmentA.Equals(cs.SegmentC))
            {
                return SegmentA;
            }
            if (SegmentB.Equals(cs.SegmentA) || SegmentB.Equals(cs.SegmentB) || SegmentB.Equals(cs.SegmentC))
            {
                return SegmentB;
            }
            if (SegmentC.Equals(cs.SegmentA) || SegmentC.Equals(cs.SegmentB) || SegmentC.Equals(cs.SegmentC))
            {
                return SegmentC;
            }

            return null;
        }
Exemple #11
0
        // Returns the exact correspondence between the triangles; <this, that>
        public Dictionary<Point, Point> PointsCorrespond(Triangle thatTriangle)
        {
            if (!this.StructurallyEquals(thatTriangle)) return null;

            List<Point> thatTrianglePts = thatTriangle.points;
            List<Point> thisTrianglePts = this.points;

            // Find the index of the first point (in this Triangle)
            int i = 0;
            for (; i < 3; i++)
            {
                if (thisTrianglePts[0].StructurallyEquals(thatTrianglePts[i])) break;
            }

            // Sanity check; something bad happened
            if (i == 3) return null;

            Dictionary<Point, Point> correspondence = new Dictionary<Point, Point>();
            for (int j = 0; j < 3; j++)
            {
                if (!thisTrianglePts[j].StructurallyEquals(thatTrianglePts[(j + i) % 3])) return null;
                correspondence.Add(thisTrianglePts[j], thatTrianglePts[(j + i) % 3]);
            }

            return correspondence;
        }
        //
        // Take the angle congruence and bisector and create the AngleBisector relation
        //
        private static List<EdgeAggregator> InstantiateToMedian(Triangle tri, SegmentBisector sb, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // The Bisector cannot be a side of the triangle.
            if (tri.CoincidesWithASide(sb.bisector) != null) return newGrounded;

            // Acquire the intersection segment that coincides with the base of the triangle
            Segment triangleBaseCandidate = sb.bisected.OtherSegment(sb.bisector);
            Segment triangleBase = tri.CoincidesWithASide(triangleBaseCandidate);
            if (triangleBase == null) return newGrounded;

            // The candidate base and the actual triangle side must equate exactly
            if (!triangleBase.HasSubSegment(triangleBaseCandidate) || !triangleBaseCandidate.HasSubSegment(triangleBase)) return newGrounded;

            // The point opposite the base of the triangle must be within the endpoints of the bisector
            Point oppPoint = tri.OtherPoint(triangleBase);
            if (!sb.bisector.PointLiesOnAndBetweenEndpoints(oppPoint)) return newGrounded;

            // -> Median(Segment(V, C), Triangle(A, B, C))
            Median newMedian = new Median(sb.bisector, tri);

            // For hypergraph
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(tri);
            antecedent.Add(original);

            newGrounded.Add(new EdgeAggregator(antecedent, newMedian, annotation));

            return newGrounded;
        }
Exemple #13
0
        //
        // Is this triangle similar to the given triangle in terms of the coordinatization from the UI?
        //
        public bool CoordinateSimilar(Triangle thatTriangle)
        {
            bool[] congruentAngle = new bool[3];
            List<Angle> thisAngles = this.angles;
            List<Angle> thatAngles = thatTriangle.angles;

            for (int thisS = 0; thisS < thisAngles.Count; thisS++)
            {
                int thatS = 0;
                for (; thatS < thatAngles.Count; thatS++)
                {
                    if (thisAngles[thisS].CoordinateCongruent(thatAngles[thatS]))
                    {
                        congruentAngle[thisS] = true;
                        break;
                    }
                }

                if (thatS == thatAngles.Count) return false;
            }

            KeyValuePair<Triangle, Triangle> corresponding = CoordinateCongruent(thatTriangle);
            return !congruentAngle.Contains(false) && (corresponding.Key == null && corresponding.Value == null); // CTA: Congruence is stronger than Similarity
        }
Exemple #14
0
 // Add to the list of similar triangles
 public void AddSimilarTriangle(Triangle t)
 {
     similarPairs.Add(t);
 }
Exemple #15
0
        public static Triangle GetFigureTriangle(Point pt1, Point pt2, Point pt3)
        {
            Triangle candTriangle = new Triangle(pt1, pt2, pt3);

            // Search for exact segment first
            foreach (Triangle tri in figureTriangles)
            {
                if (tri.StructurallyEquals(candTriangle)) return tri;
            }

            return null;
        }
        //
        // DO NOT generate a new clause, instead, report the result and generate all applicable
        //
        private static List<EdgeAggregator> StrengthenToRightTriangle(Triangle tri, RightAngle ra, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // This angle must belong to this triangle.
            if (!tri.HasAngle(ra)) return newGrounded;

            // Strengthen the old triangle to a right triangle
            Strengthened newStrengthened = new Strengthened(tri, new RightTriangle(tri));
            tri.SetProvenToBeRight();

            // Hypergraph
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(tri);
            antecedent.Add(original);

            newGrounded.Add(new EdgeAggregator(antecedent, newStrengthened, annotation));

            return newGrounded;
        }
Exemple #17
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;
        }
 /// <summary>
 /// Tests to see if a triangle is isosceles
 /// </summary>
 /// <param name="t">The triangle to test</param>
 /// <returns>true if at least two sides have equal length</returns>
 private bool isIsosceles(Triangle t)
 {
     return (t.SegmentA.Length == t.SegmentB.Length) || (t.SegmentA.Length == t.SegmentC.Length) || (t.SegmentB.Length == t.SegmentC.Length);
 }
Exemple #19
0
 public Median(Segment segment, Triangle thatTriangle)
 {
     medianSegment = segment;
     theTriangle = thatTriangle;
 }
        //
        //
        //
        private static List<EdgeAggregator> IfCongruencesApplyToTrianglesGenerate(Triangle ct1, Triangle ct2, CongruentSegments css1, CongruentSegments css2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // The congruent relationships need to link the given triangles
            //
            if (!css1.LinksTriangles(ct1, ct2)) return newGrounded;
            if (!css2.LinksTriangles(ct1, ct2)) return newGrounded;

            Segment seg1Tri1 = ct1.GetSegment(css1);
            Segment seg2Tri1 = ct1.GetSegment(css2);

            Segment seg1Tri2 = ct2.GetSegment(css1);
            Segment seg2Tri2 = ct2.GetSegment(css2);

            // Avoid redundant segments, if it arises
            if (seg1Tri1.StructurallyEquals(seg2Tri1)) return newGrounded;
            if (seg1Tri2.StructurallyEquals(seg2Tri2)) return newGrounded;

            //
            // Proportional Segments (we generate only as needed to avoid bloat in the hypergraph (assuming they are used by both triangles)
            // We avoid generating proportions if they are truly congruences.
            //
            List<GroundedClause> propAntecedent = new List<GroundedClause>();
            propAntecedent.Add(css1);
            propAntecedent.Add(css2);

            SegmentRatio ratio1 = new SegmentRatio(seg1Tri1, seg1Tri2);
            SegmentRatio ratio2 = new SegmentRatio(seg2Tri1, seg2Tri2);

            GeometricSegmentRatioEquation newEq = new GeometricSegmentRatioEquation(ratio1, ratio2);

            newGrounded.Add(new EdgeAggregator(propAntecedent, newEq, annotation));

            ////
            //// Only generate if ratios are not 1.
            ////

            //GeometricSegmentRatio newProp = null;
            //if (!Utilities.CompareValues(seg1Tri1.Length, seg1Tri2.Length))
            //{
            //    newProp = new GeometricSegmentRatio(seg1Tri1, seg1Tri2);
            //    newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation));
            //}
            //if (!Utilities.CompareValues(seg1Tri1.Length, seg2Tri2.Length))
            //{
            //    newProp = new GeometricSegmentRatio(seg1Tri1, seg2Tri2);
            //    newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation));
            //}
            //if (!Utilities.CompareValues(seg2Tri1.Length, seg1Tri2.Length))
            //{
            //    newProp = new GeometricSegmentRatio(seg2Tri1, seg1Tri2);
            //    newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation));
            //}
            //if (!Utilities.CompareValues(seg2Tri1.Length, seg2Tri2.Length))
            //{
            //    newProp = new GeometricSegmentRatio(seg2Tri1, seg2Tri2);
            //    newGrounded.Add(new EdgeAggregator(propAntecedent, newProp, annotation));
            //}

            return newGrounded;
        }
Exemple #21
0
 public bool WasDeducedSimilar(Triangle that)
 {
     return similarPairs.Contains(that);
 }
Exemple #22
0
 //
 // Have we deduced a similarity between this triangle and t already?
 //
 public bool HasEstablishedSimilarity(Triangle t)
 {
     return similarPairs.Contains(t);
 }
Exemple #23
0
        //
        // Can this triangle be strengthened to Isosceles, Equilateral, Right, or Right Isosceles?
        //
        public static List<Strengthened> CanBeStrengthened(Triangle thatTriangle)
        {
            List<Strengthened> strengthened = new List<Strengthened>();

            //
            // Equilateral cannot be strengthened
            //
            if (thatTriangle is EquilateralTriangle) return strengthened;

            if (thatTriangle is IsoscelesTriangle)
            {
                //
                // Isosceles -> Equilateral
                //
                if (thatTriangle.isEquilateral)
                {
                    strengthened.Add(new Strengthened(thatTriangle, new EquilateralTriangle(thatTriangle)));
                }

                //
                // Isosceles -> Right Isosceles
                //
                if (thatTriangle.isRight)
                {
                    strengthened.Add(new Strengthened(thatTriangle, new RightTriangle(thatTriangle)));
                }

                return strengthened;
            }

            //
            // Scalene -> Isosceles
            //
            if (thatTriangle.isIsosceles)
            {
                strengthened.Add(new Strengthened(thatTriangle, new IsoscelesTriangle(thatTriangle)));
            }

            //
            // Scalene -> Equilateral
            //
            if (thatTriangle.isEquilateral)
            {
                strengthened.Add(new Strengthened(thatTriangle, new EquilateralTriangle(thatTriangle)));
            }

            //
            // Scalene -> Right
            //
            if (!(thatTriangle is RightTriangle))
            {
                if (thatTriangle.isRight)
                {
                    strengthened.Add(new Strengthened(thatTriangle, new RightTriangle(thatTriangle)));
                }
            }

            return strengthened;
        }
 public IsoscelesTriangle(Triangle tri) : base(tri.SegmentA, tri.SegmentB, tri.SegmentC)
 {
     DetermineIsoscelesValues();
     provenIsosceles = true;
 }
Exemple #25
0
 // Add to the list of congruent triangles
 public void AddCongruentTriangle(Triangle t)
 {
     congruencePairs.Add(t);
 }
 public GeometricCongruentTriangles(Triangle t1, Triangle t2)
     : base(t1, t2)
 {
 }
Exemple #27
0
        //
        // Is this triangle congruent to the given triangle in terms of the coordinatization from the UI?
        //
        public KeyValuePair<Triangle, Triangle> CoordinateCongruent(Triangle thatTriangle)
        {
            bool[] marked = new bool[3];
            List<Segment> thisSegments = this.orderedSides;
            List<Segment> thatSegments = thatTriangle.orderedSides;

            List<Segment> corrSegmentsThis = new List<Segment>();
            List<Segment> corrSegmentsThat = new List<Segment>();

            for (int thisS = 0; thisS < thisSegments.Count; thisS++)
            {
                bool found = false;
                for (int thatS = 0; thatS < thatSegments.Count; thatS++)
                {
                    if (!marked[thatS])
                    {
                        if (thisSegments[thisS].CoordinateCongruent(thatSegments[thatS]))
                        {
                            corrSegmentsThat.Add(thatSegments[thatS]);
                            corrSegmentsThis.Add(thisSegments[thisS]);
                            marked[thatS] = true;
                            found = true;
                            break;
                        }
                    }
                }
                if (!found) return new KeyValuePair<Triangle,Triangle>(null, null);
            }

            //
            // Find the exact corresponding points
            //
            List<Point> triThis = new List<Point>();
            List<Point> triThat = new List<Point>();

            for (int i = 0; i < 3; i++)
            {
                triThis.Add(corrSegmentsThis[i].SharedVertex(corrSegmentsThis[i + 1 < 3 ? i + 1 : 0]));
                triThat.Add(corrSegmentsThat[i].SharedVertex(corrSegmentsThat[i + 1 < 3 ? i + 1 : 0]));
            }

            return new KeyValuePair<Triangle, Triangle>(new Triangle(triThis), new Triangle(triThat));
        }
        //
        // A right triangle means we can apply the pythagorean theorem to acquire an unknown.
        //
        public static bool HandleTriangle(KnownMeasurementsAggregator known, Triangle tri)
        {
            if (tri == null) return false;

            KeyValuePair<Segment, double> pair = tri.PythagoreanTheoremApplies(known);

            if (pair.Value > 0)
            {
                // Do we know this already?
                if (known.GetSegmentLength(pair.Key) > 0) return false;

                // We don't know it, we add it.
                known.AddSegmentLength(pair.Key, pair.Value);
                return true;
            }
            else
            {
                if (AddKnowns(known, tri.IsoscelesRightApplies(known))) return true;
                if (AddKnowns(known, tri.CalculateBaseOfIsosceles(known))) return true;
                if (AddKnowns(known, tri.RightTriangleTrigApplies(known))) return true;
            }

            return false;
        }
Exemple #29
0
 //
 // Have we deduced a congrunence between this triangle and t already?
 //
 public bool HasEstablishedCongruence(Triangle t)
 {
     return congruencePairs.Contains(t);
 }
        private static List<EdgeAggregator> CheckAndGenerateProportionality(Triangle tri, Intersection inter1,
                                                                            Intersection inter2, Parallel parallel)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // The two intersections should not be at the same vertex
            if (inter1.intersect.Equals(inter2.intersect)) return newGrounded;

            //
            // Do these intersections share a segment? That is, do they share the transversal?
            //
            Segment transversal = inter1.AcquireTransversal(inter2);
            if (transversal == null) return newGrounded;

            //
            // Is the transversal a side of the triangle? It should not be.
            //
            if (tri.LiesOn(transversal)) return newGrounded;

            //
            // Determine if one parallel segment is a side of the triangle (which must occur)
            //
            Segment coinciding = tri.DoesParallelCoincideWith(parallel);
            if (coinciding == null) return newGrounded;

            // The transversal and common segment must be distinct
            if (coinciding.IsCollinearWith(transversal)) return newGrounded;

            //
            // Determine if the simplified transversal is within the parallel relationship.
            //
            Segment parallelTransversal = parallel.OtherSegment(coinciding);
            Segment simpleParallelTransversal = new Segment(inter1.intersect, inter2.intersect);

            if (!parallelTransversal.IsCollinearWith(simpleParallelTransversal)) return newGrounded;

            //            A
            //           /\
            //          /  \
            //         /    \
            //  off1  /------\ off2
            //       /        \
            //    B /__________\ C

            //
            // Both intersections should create a T-shape.
            //
            Point off1 = inter1.CreatesTShape();
            Point off2 = inter2.CreatesTShape();
            if (off1 == null || off2 == null) return newGrounded;

            // Get the intersection segments which should coincide with the triangle sides
            KeyValuePair<Segment, Segment> otherSides = tri.OtherSides(coinciding);

            // The intersections may be outside this triangle
            if (otherSides.Key == null || otherSides.Value == null) return newGrounded;

            Segment side1 = inter1.OtherSegment(transversal);
            Segment side2 = inter2.OtherSegment(transversal);

            // Get the actual sides of the triangle
            Segment triangleSide1 = null;
            Segment triangleSide2 = null;
            if (side1.IsCollinearWith(otherSides.Key) && side2.IsCollinearWith(otherSides.Value))
            {
                triangleSide1 = otherSides.Key;
                triangleSide2 = otherSides.Value;
            }
            else if (side1.IsCollinearWith(otherSides.Value) && side2.IsCollinearWith(otherSides.Key))
            {
                triangleSide1 = otherSides.Value;
                triangleSide2 = otherSides.Key;
            }
            else return newGrounded;

            // Verify the opposing parts of the T are on the opposite sides of the triangle
            if (!triangleSide1.PointLiesOnAndExactlyBetweenEndpoints(off2)) return newGrounded;
            if (!triangleSide2.PointLiesOnAndExactlyBetweenEndpoints(off1)) return newGrounded;

            //
            // Construct the new proprtional relationship and resultant equation
            //
            Point sharedVertex = triangleSide1.SharedVertex(triangleSide2);
            SegmentRatio newProp1 = new SegmentRatio(new Segment(sharedVertex, off2), triangleSide1);
            SegmentRatio newProp2 = new SegmentRatio(new Segment(sharedVertex, off1), triangleSide2);

            GeometricSegmentRatioEquation newEq = new GeometricSegmentRatioEquation(newProp1, newProp2);

            // Construct hyperedge
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(tri);
            antecedent.Add(inter1);
            antecedent.Add(inter2);
            antecedent.Add(parallel);

            newGrounded.Add(new EdgeAggregator(antecedent, newEq, annotation));

            return newGrounded;
        }
        /// <summary>
        /// Checks to see if two triangles are congruent. (All sides are equal length)
        /// </summary>
        /// <param name="t1">A triangle</param>
        /// <param name="t2">A triangle</param>
        /// <returns>true if the triangles are congruent, false otherwise.</returns>
        private bool isCongruent(Triangle t1, Triangle t2)
        {
            //Convert each triangle into an array of sides, such that sides i % n and i+1 % n are adjancent.
            GeometryTutorLib.ConcreteAST.Segment[] sides1 = { t1.SegmentA, t1.SegmentB, t1.SegmentC };
            GeometryTutorLib.ConcreteAST.Segment[] sides2 = { t2.SegmentA, t2.SegmentB, t2.SegmentC };

            //Pick a side of triangle 1 and compare it to each side of triangle 2
            for (int i = 0; i < 3; i++)
            {
                if (sides1[0].Length == sides2[i].Length) //See if they have the same length
                {
                    //We need to compare sides in each direction. Start in the forward direction.
                    bool pass = true;
                    for (int j = 1; j < 3; j++)
                    {
                        pass = (sides1[j].Length == sides2[(i + j) % 3].Length) && pass;
                    }

                    if (pass)
                    {
                        return true;
                    }

                    //If the previous direction failed, check the backwards direction.
                    pass = true;
                    for (int j = 1; j < 3; j++)
                    {
                        pass = (sides1[j].Length == sides2[((i - j) + 2) % 3].Length) && pass;
                    }

                    if (pass)
                    {
                        return true;
                    }

                    //Both directions failed. Containue checking sides of triangle 2.
                }
            }

            //Both directions failed for all sides of triangle 2.
            return false;
        }
Exemple #32
0
 public bool LinksTriangles(Triangle ct1, Triangle ct2)
 {
     return(ct1.HasSegment(cs1) && ct2.HasSegment(cs2) || ct1.HasSegment(cs2) && ct2.HasSegment(cs1));
 }