private static List <EdgeAggregator> InstantiateToTheorem(Rhombus rhombus, GroundedClause original)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

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

            // Instantiate this rhombus diagonals ONLY if the original figure has the diagonals drawn.
            if (rhombus.TopLeftDiagonalIsValid())
            {
                AngleBisector ab1 = new AngleBisector(rhombus.topLeftAngle, rhombus.topLeftBottomRightDiagonal);
                AngleBisector ab2 = new AngleBisector(rhombus.bottomRightAngle, rhombus.topLeftBottomRightDiagonal);
                newGrounded.Add(new EdgeAggregator(antecedent, ab1, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, ab2, annotation));
            }

            if (rhombus.BottomRightDiagonalIsValid())
            {
                AngleBisector ab1 = new AngleBisector(rhombus.topRightAngle, rhombus.bottomLeftTopRightDiagonal);
                AngleBisector ab2 = new AngleBisector(rhombus.bottomLeftAngle, rhombus.bottomLeftTopRightDiagonal);
                newGrounded.Add(new EdgeAggregator(antecedent, ab1, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, ab2, annotation));
            }

            return(newGrounded);
        }
        //
        // AngleBisector(SegmentA, D), Angle(C, A, B)) -> 2 m\angle CAD = m \angle CAB,
        //                                                2 m\angle BAD = m \angle CAB
        //
        //   A ________________________B
        //    |\
        //    | \ 
        //    |  \
        //    |   \
        //    |    \
        //    C     D
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ANGLE_BISECTOR_THEOREM;

            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (!(c is AngleBisector))
            {
                return(newGrounded);
            }

            AngleBisector angleBisector = c as AngleBisector;
            KeyValuePair <Angle, Angle> adjacentAngles = angleBisector.GetBisectedAngles();

            // Construct 2 m\angle CAD
            Multiplication product1 = new Multiplication(new NumericValue(2), adjacentAngles.Key);
            // Construct 2 m\angle BAD
            Multiplication product2 = new Multiplication(new NumericValue(2), adjacentAngles.Value);

            // 2X = AB
            GeometricAngleEquation newEq1 = new GeometricAngleEquation(product1, angleBisector.angle);
            GeometricAngleEquation newEq2 = new GeometricAngleEquation(product2, angleBisector.angle);

            // For hypergraph
            List <GroundedClause> antecedent = Utilities.MakeList <GroundedClause>(angleBisector);

            newGrounded.Add(new EdgeAggregator(antecedent, newEq1, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, newEq2, annotation));

            return(newGrounded);
        }
        //
        // 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);
        }
        //      V---------------A
        //     / \
        //    /   \
        //   /     \
        //  B       C
        //
        // AngleBisector(Angle(A, V, B), Segment(V, C)) -> Congruent(Angle, A, V, C), Angle(C, V, B))
        //
        private static List <EdgeAggregator> InstantiateBisector(AngleBisector ab)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            // Create the two adjacent angles
            Point vertex                 = ab.angle.GetVertex();
            Point interiorPt             = ab.angle.IsOnInteriorExplicitly(ab.bisector.Point1) ? ab.bisector.Point1 : ab.bisector.Point2;
            Angle adj1                   = new Angle(ab.angle.ray1.OtherPoint(vertex), vertex, interiorPt);
            Angle adj2                   = new Angle(ab.angle.ray2.OtherPoint(vertex), vertex, interiorPt);
            GeometricCongruentAngles cas = new GeometricCongruentAngles(adj1, adj2);

            // For hypergraph
            newGrounded.Add(new EdgeAggregator(Utilities.MakeList <GroundedClause>(ab), cas, annotation));

            return(newGrounded);
        }
示例#5
0
 public override string ToString()
 {
     return((IsValid ? "[OK]" : "[NOK]") +
            //" " + LeftEdge.ToString() + " -> " + RightEdge.ToString() +
            ", angle G: " + AngleBisector.ToString("0.00"));
 }
        //
        // IsoscelesTriangle(A, B, C),
        // AngleBisector(Segment(M, C), Angle(A, C, B)),
        // Intersection(M, Segment(M, C), Segment(A, B) -> PerpendicularBisector(M, Segment(M, C), Segment(A, B)),
        //
        //   A _____M_____B
        //     \    |    /
        //      \   |   /
        //       \  |  /
        //        \ | /
        //         \|/
        //          C
        //
        public static List <EdgeAggregator> Instantiate(GroundedClause c)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.ANGLE_BISECTOR_IS_PERPENDICULAR_BISECTOR_IN_ISOSCELES;

            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            if (!(c is Strengthened) && !(c is IsoscelesTriangle) && !(c is AngleBisector) && !(c is Intersection))
            {
                return(newGrounded);
            }

            if (c is IsoscelesTriangle)
            {
                IsoscelesTriangle isoTri = c as IsoscelesTriangle;

                foreach (AngleBisector ab in candidateBisectors)
                {
                    foreach (Intersection inter in candidateIntersections)
                    {
                        newGrounded.AddRange(GeneratePerpendicularBisector(isoTri, ab, inter));
                    }
                }

                candidateIsosceles.Add(isoTri);
            }
            else if (c is Strengthened)
            {
                Strengthened streng = c as Strengthened;

                // We are not interested if the strengthened clause is not Isosceles (note, this includes equilateral)
                if (!(streng.strengthened is IsoscelesTriangle))
                {
                    return(newGrounded);
                }

                foreach (AngleBisector ab in candidateBisectors)
                {
                    foreach (Intersection inter in candidateIntersections)
                    {
                        newGrounded.AddRange(GeneratePerpendicularBisector(streng, ab, inter));
                    }
                }

                candidateStrengthened.Add(streng);
            }
            else if (c is Intersection)
            {
                Intersection newIntersection = c as Intersection;

                foreach (IsoscelesTriangle isoTri in candidateIsosceles)
                {
                    foreach (AngleBisector ab in candidateBisectors)
                    {
                        newGrounded.AddRange(GeneratePerpendicularBisector(isoTri, ab, newIntersection));
                    }
                }

                candidateIntersections.Add(newIntersection);
            }
            else if (c is AngleBisector)
            {
                AngleBisector newAB = c as AngleBisector;

                foreach (IsoscelesTriangle isoTri in candidateIsosceles)
                {
                    foreach (Intersection inter in candidateIntersections)
                    {
                        newGrounded.AddRange(GeneratePerpendicularBisector(isoTri, newAB, inter));
                    }
                }

                candidateBisectors.Add(newAB);
            }

            return(newGrounded);
        }
        public static List <GenericInstantiator.EdgeAggregator> GeneratePerpendicularBisector(GroundedClause tri, AngleBisector ab, Intersection inter)
        {
            List <EdgeAggregator> newGrounded = new List <EdgeAggregator>();

            IsoscelesTriangle isoTri = (tri is Strengthened ? (tri as Strengthened).strengthened : tri) as IsoscelesTriangle;

            if (tri is EquilateralTriangle)
            {
            }

            // Does the Angle Bisector occur at the vertex angle (non-base angles) of the Isosceles triangle?
            try
            {
                if (!ab.angle.GetVertex().Equals(isoTri.GetVertexAngle().GetVertex()))
                {
                    return(newGrounded);
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.ToString());
            }

            // Is the intersection point between the endpoints of the base of the triangle?
            if (!Segment.Between(inter.intersect, isoTri.baseSegment.Point1, isoTri.baseSegment.Point2))
            {
                return(newGrounded);
            }

            // Does this intersection define this angle bisector situation? That is, the bisector and base must align with the intersection
            if (!inter.ImpliesRay(ab.bisector))
            {
                return(newGrounded);
            }
            if (!inter.HasSegment(isoTri.baseSegment))
            {
                return(newGrounded);
            }

            List <GroundedClause> antecedent = new List <GroundedClause>();

            antecedent.Add(tri);
            antecedent.Add(ab);
            antecedent.Add(inter);

            // PerpendicularBisector(M, Segment(M, C), Segment(A, B))
            Strengthened newPerpB = new Strengthened(inter, new PerpendicularBisector(inter, ab.bisector));

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

            return(newGrounded);
        }