private static List<EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            if (!Utilities.CompareValues(angle1.measure + angle2.measure, 90)) return newGrounded;

            // The perpendicular intersection must occur at the same vertex of both angles (we only need check one).
            if (!(angle1.GetVertex().Equals(perp.intersect) && angle2.GetVertex().Equals(perp.intersect))) return newGrounded;

            // Are the angles adjacent?
            Segment sharedRay = angle1.IsAdjacentTo(angle2);
            if (sharedRay == null) return newGrounded;

            // Do the non-shared rays for both angles align with the segments defined by the perpendicular intersection?
            if (!perp.DefinesBothRays(angle1.OtherRayEquates(sharedRay), angle2.OtherRayEquates(sharedRay))) return newGrounded;

            //
            // Now we have perpendicular -> complementary angles scenario
            //
            Complementary cas = new Complementary(angle1, angle2);

            // Construct hyperedge
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(perp);
            antecedent.Add(angle1);
            antecedent.Add(angle2);

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

            return newGrounded;
        }
Пример #2
0
        public override bool StructurallyEquals(Object obj)
        {
            Perpendicular perp = obj as Perpendicular;

            if (perp == null)
            {
                return(false);
            }
            return(intersect.Equals(perp.intersect) && ((lhs.StructurallyEquals(perp.lhs) && rhs.StructurallyEquals(perp.rhs)) ||
                                                        (lhs.StructurallyEquals(perp.rhs) && rhs.StructurallyEquals(perp.lhs))));
        }
Пример #3
0
        public override bool CanBeStrengthenedTo(GroundedClause gc)
        {
            Perpendicular perp = gc as Perpendicular;

            if (perp == null)
            {
                return(false);
            }
            return(intersect.Equals(perp.intersect) && ((lhs.StructurallyEquals(perp.lhs) && rhs.StructurallyEquals(perp.rhs)) ||
                                                        (lhs.StructurallyEquals(perp.rhs) && rhs.StructurallyEquals(perp.lhs))));
        }
Пример #4
0
        public override bool Equals(Object obj)
        {
            if (obj is PerpendicularBisector)
            {
                return((obj as PerpendicularBisector).Equals(this));
            }

            Perpendicular p = obj as Perpendicular;

            if (p == null)
            {
                return(false);
            }

            return(intersect.Equals(p.intersect) && lhs.Equals(p.lhs) && rhs.Equals(p.rhs));
        }
        private static List<EdgeAggregator> CheckAndGeneratePerpendicularImplyCongruentAdjacent(Perpendicular perp, Angle angle1, Angle angle2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            if (!Utilities.CompareValues(angle1.measure, angle2.measure)) return newGrounded;

            // The given angles must belong to the intersection. That is, the vertex must align and all rays must overlay the intersection.
            if (!(perp.InducesNonStraightAngle(angle1) && perp.InducesNonStraightAngle(angle1))) return newGrounded;

            //
            // Now we have perpendicular -> congruent angles scenario
            //
            GeometricCongruentAngles gcas = new GeometricCongruentAngles(angle1, angle2);

            // Construct hyperedge
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(perp);
            antecedent.Add(angle1);
            antecedent.Add(angle2);

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

            return newGrounded;
        }
Пример #6
0
        private static List<EdgeAggregator> InstantiateToAltitude(Triangle triangle, Perpendicular perp, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Acquire the side of the triangle containing the intersection point
            // This point may or may not be directly on the triangle side
            Segment baseSegment = triangle.GetSegmentWithPointOnOrExtends(perp.intersect);
            if (baseSegment == null) return newGrounded;

            // The altitude must pass through the intersection point as well as the opposing vertex
            Point oppositeVertex = triangle.OtherPoint(baseSegment);

            Segment altitude = new Segment(perp.intersect, oppositeVertex);

            // The alitude must alig with the intersection
            if (!perp.ImpliesRay(altitude)) return newGrounded;

            // The opposing side must align with the intersection
            if (!perp.OtherSegment(altitude).IsCollinearWith(baseSegment)) return newGrounded;

            //
            // Create the new Altitude object
            //
            Altitude newAltitude = new Altitude(triangle, altitude);

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

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

            //
            // Check if this induces a second altitude for a right triangle (although we don't know this is a strengthened triangle)
            // The intersection must be on the vertex of the triangle
            if (triangle.HasPoint(perp.intersect))
            {
                Angle possRightAngle = new Angle(triangle.OtherPoint(new Segment(perp.intersect, oppositeVertex)), perp.intersect, oppositeVertex);

                if (triangle.HasAngle(possRightAngle))
                {
                    Altitude secondAltitude = new Altitude(triangle, new Segment(perp.intersect, oppositeVertex));
                    newGrounded.Add(new EdgeAggregator(antecedent, secondAltitude, annotation));
                }
            }

            return newGrounded;
        }
        private static List<EdgeAggregator> CheckAndGeneratePerpendicular(Perpendicular perp, Parallel parallel, Intersection inter, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // The perpendicular intersection must refer to one of the parallel segments
            Segment shared = perp.CommonSegment(parallel);
            if (shared == null) return newGrounded;

            // The other intersection must refer to a segment in the parallel pair
            Segment otherShared = inter.CommonSegment(parallel);
            if (otherShared == null) return newGrounded;

            // The two shared segments must be distinct
            if (shared.Equals(otherShared)) return newGrounded;

            // Transversals must align
            if (!inter.OtherSegment(otherShared).Equals(perp.OtherSegment(shared))) return newGrounded;

            // Strengthen the old intersection to be perpendicular
            Strengthened strengthenedPerp = new Strengthened(inter, new Perpendicular(inter));

            // Construct hyperedge
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(original);
            antecedent.Add(parallel);
            antecedent.Add(inter);

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

            return newGrounded;
        }
        //        )  | B
        //         ) |
        // O        )| S
        //         ) |
        //        )  |
        //       )   | A
        // Tangent(Circle(O, R), Segment(A, B)), Intersection(OS, AB) -> Perpendicular(Segment(A,B), Segment(O, S))
        //
        private static List<EdgeAggregator> InstantiateTheorem(CircleSegmentIntersection inter, Perpendicular perp, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // The intersection points must be the same.
            if (!inter.intersect.StructurallyEquals(perp.intersect)) return newGrounded;

            // Get the radius - if it exists
            Segment radius = null;
            Segment garbage = null;
            inter.GetRadii(out radius, out garbage);

            if (radius == null) return newGrounded;

            // Two intersections, not a tangent situation.
            if (garbage != null) return newGrounded;

            // The radius can't be the same as the Circ-Inter segment.
            if (inter.segment.HasSubSegment(radius)) return newGrounded;

            // Does this perpendicular apply to this Arc intersection?
            if (!perp.HasSegment(radius) || !perp.HasSegment(inter.segment)) return newGrounded;

            Strengthened newTangent = new Strengthened(inter, new Tangent(inter));

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

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

            return newGrounded;
        }
        //               A
        //              |)
        //              | )
        //              |  )
        // Q------- O---X---) D
        //              |  )
        //              | )
        //              |)
        //               C
        //
        // Perpendicular(Segment(Q, D), Segment(A, C)) -> Congruent(Arc(A, D), Arc(D, C)) -> Congruent(Segment(AX), Segment(XC))
        //
        private static List<EdgeAggregator> InstantiateTheorem(Intersection inter, CircleSegmentIntersection arcInter, Perpendicular perp, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Does this intersection apply to this perpendicular?
            //
            if (!inter.intersect.StructurallyEquals(perp.intersect)) return newGrounded;

            // Is this too restrictive?
            if (!((inter.HasSegment(perp.lhs) && inter.HasSegment(perp.rhs)) && (perp.HasSegment(inter.lhs) && perp.HasSegment(inter.rhs)))) return newGrounded;

            //
            // Does this perpendicular intersection apply to a given circle?
            //
            // Acquire the circles for which the segments are secants.
            List<Circle> secantCircles1 = Circle.GetSecantCircles(perp.lhs);
            List<Circle> secantCircles2 = Circle.GetSecantCircles(perp.rhs);

            List<Circle> intersection = Utilities.Intersection<Circle>(secantCircles1, secantCircles2);

            if (!intersection.Any()) return newGrounded;

            //
            // Find the single, unique circle that has as chords the components of the perpendicular intersection
            //
            Circle theCircle = null;
            Segment chord1 = null;
            Segment chord2 = null;
            foreach (Circle circle in intersection)
            {
                chord1 = circle.GetChord(perp.lhs);
                chord2 = circle.GetChord(perp.rhs);
                if (chord1 != null && chord2 != null)
                {
                    theCircle = circle;
                    break;
                }
            }

            Segment diameter = chord1.Length > chord2.Length ? chord1 : chord2;
            Segment chord = chord1.Length < chord2.Length ? chord1 : chord2;

            //
            // Does the arc intersection apply?
            //
            if (!arcInter.HasSegment(diameter)) return newGrounded;
            if (!theCircle.StructurallyEquals(arcInter.theCircle)) return newGrounded;

            //
            // Create the bisector
            //
            Strengthened sb = new Strengthened(inter, new SegmentBisector(inter, diameter));
            Strengthened ab = new Strengthened(arcInter, new ArcSegmentBisector(arcInter));

            // For hypergraph
            List<GroundedClause> antecedentArc = new List<GroundedClause>();
            antecedentArc.Add(arcInter);
            antecedentArc.Add(original);
            antecedentArc.Add(theCircle);

            newGrounded.Add(new EdgeAggregator(antecedentArc, ab, annotation));

            List<GroundedClause> antecedentSegment = new List<GroundedClause>();
            antecedentSegment.Add(inter);
            antecedentSegment.Add(original);
            antecedentSegment.Add(theCircle);

            newGrounded.Add(new EdgeAggregator(antecedentSegment, sb, annotation));

            return newGrounded;
        }
Пример #10
0
        //
        // Perpendicular(B, Segment(A, B), Segment(B, C)) -> RightAngle(), RightAngle()
        //
        private static List<EdgeAggregator> InstantiateFromPerpendicular(GroundedClause original, Perpendicular perp)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(original);

            //          top
            //           |
            //           |_
            //           |_|____ right
            if (perp.StandsOnEndpoint())
            {
                Point top = perp.lhs.OtherPoint(perp.intersect);
                Point right = perp.rhs.OtherPoint(perp.intersect);

                Strengthened streng = new Strengthened(new Angle(top, perp.intersect, right), new RightAngle(top, perp.intersect, right));

                newGrounded.Add(new EdgeAggregator(antecedent, streng, annotation));
            }
            //          top
            //           |
            //           |_
            // left  ____|_|____ right
            else if (perp.StandsOn())
            {
                Point top = perp.lhs.Point1;
                Point center = perp.intersect;
                Point left = perp.rhs.Point1;
                Point right = perp.rhs.Point2;
                if (perp.lhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect))
                {
                    left = perp.lhs.Point1;
                    right = perp.lhs.Point2;
                    top = perp.rhs.OtherPoint(perp.intersect);
                }
                else if (perp.rhs.PointLiesOnAndExactlyBetweenEndpoints(perp.intersect))
                {
                    left = perp.rhs.Point1;
                    right = perp.rhs.Point2;
                    top = perp.lhs.OtherPoint(perp.intersect);
                }
                else return newGrounded;

                Strengthened topRight = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right));
                Strengthened topLeft = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left));

                newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation));
            }
            //          top
            //           |
            //           |_
            // left  ____|_|____ right
            //           |
            //           |
            //         bottom
            else if (perp.Crossing())
            {
                Point top = perp.lhs.Point1;
                Point bottom = perp.lhs.Point2;
                Point center = perp.intersect;
                Point left = perp.rhs.Point1;
                Point right = perp.rhs.Point2;

                Strengthened topRight = new Strengthened(new Angle(top, center, right), new RightAngle(top, center, right));
                Strengthened bottomRight = new Strengthened(new Angle(right, center, bottom), new RightAngle(right, center, bottom));
                Strengthened bottomLeft = new Strengthened(new Angle(left, center, bottom), new RightAngle(left, center, bottom));
                Strengthened topLeft = new Strengthened(new Angle(top, center, left), new RightAngle(top, center, left));

                newGrounded.Add(new EdgeAggregator(antecedent, topRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, bottomRight, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, bottomLeft, annotation));
                newGrounded.Add(new EdgeAggregator(antecedent, topLeft, annotation));
            }
            else return newGrounded;

            return newGrounded;
        }