//
        // Chair Corresponding
        //
        // |     |                  |
        // |_____|____   leftInter  |_________ tipOfT
        // |                        |     |
        // |                        |     |
        //                         off   tipOfT
        //
        //                                bottomInter
        private static List<EdgeAggregator> InstantiateChairIntersection(Parallel parallel, Intersection inter1, Point off, Intersection inter2, Point bottomTip)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Segment transversal = inter1.AcquireTransversal(inter2);
            Point tipOfT1 = inter1.CreatesTShape();
            Point tipOfT2 = inter2.CreatesTShape();

            Point leftTip = null;
            Intersection leftInter = null;
            Intersection bottomInter = null;

            if (transversal.PointLiesOn(tipOfT1))
            {
                leftInter = inter1;
                bottomInter = inter2;
                leftTip = tipOfT1;
            }
            // thatInter is leftInter
            else if (transversal.PointLiesOn(tipOfT2))
            {
                leftInter = inter2;
                bottomInter = inter1;
                leftTip = tipOfT2;
            }

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            // CTA: Hack fix to alleviate exception thrown from improper congruent constructions.
            GeometricCongruentAngles gca = null;
            try
            {
                gca = new GeometricCongruentAngles(new Angle(leftTip, bottomInter.intersect, bottomTip),
                                                   new Angle(bottomInter.intersect, leftInter.intersect, off));
            }
            catch (Exception e)
            {
                if (Utilities.DEBUG) System.Diagnostics.Debug.WriteLine(e.ToString());

                return newGrounded;
            }

            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
Beispiel #2
0
        public static List<GenericInstantiator.EdgeAggregator> CreateTransitiveParallel(Parallel parallel1, Parallel parallel2)
        {
            annotation.active = EngineUIBridge.JustificationSwitch.TRANSITIVE_PARALLEL;

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

            //
            // Create the antecedent clauses
            //
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(parallel1);
            antecedent.Add(parallel2);

            //
            // Create the consequent clause
            //
            Segment shared = parallel1.SharedSegment(parallel2);

            AlgebraicParallel newAP = new AlgebraicParallel(parallel1.OtherSegment(shared), parallel2.OtherSegment(shared));

            newGrounded.Add(new GenericInstantiator.EdgeAggregator(antecedent, newAP, annotation));

            return newGrounded;
        }
        //     offCross
        //        |
        //  ______|______ rightCrossing
        //        |
        //        |_____  offStands
        //        |
        //        |
        //     bottomStands
        private static List<EdgeAggregator> InstantiateExtendedChairIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Point offCross)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the crossing intersection and which stands on the endpoints
            //
            Intersection crossingInter = null;
            Intersection standsInter = null;
            if (inter1.Crossing())
            {
                crossingInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.Crossing())
            {
                crossingInter = inter2;
                standsInter = inter1;
            }

            //
            // Determination of Points
            //
            Point offStands = standsInter.CreatesTShape();

            Segment transversal = inter1.AcquireTransversal(inter2);
            Segment transversalStands = standsInter.GetCollinearSegment(transversal);

            Point bottomStands = Segment.Between(standsInter.intersect, transversalStands.Point1, crossingInter.intersect) ? transversalStands.Point1 : transversalStands.Point2;

            // Which side for rightCrossing
            Segment parallelCrossing = crossingInter.OtherSegment(transversal);
            Segment crossingTester = new Segment(offStands, parallelCrossing.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);

            Point rightCrossing = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelCrossing.Point2 : parallelCrossing.Point1;

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(bottomStands, standsInter.intersect, offStands),
                                                                        new Angle(standsInter.intersect, crossingInter.intersect, rightCrossing));
            newAngleRelations.Add(gca);

            gca = new GeometricCongruentAngles(new Angle(offStands, standsInter.intersect, crossingInter.intersect),
                                               new Angle(rightCrossing, crossingInter.intersect, offCross));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //
        // Generate all new relationships from a Geoemetric, Congruent Pair of Parallel Segments
        //
        private static List<EdgeAggregator> HandleNewParallelRelation(Parallel parallel)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // New transitivity? G + G -> A
            foreach (GeometricParallel gp in geoParallel)
            {
                newGrounded.AddRange(CreateTransitiveParallelSegments(gp, parallel));
            }

            if (parallel is GeometricParallel)
            {
                // New transitivity? G + A -> A
                foreach (AlgebraicParallel ap in algParallel)
                {
                    newGrounded.AddRange(CreateTransitiveParallelSegments(ap, parallel));
                }
            }

            return newGrounded;
        }
Beispiel #5
0
 //
 // Does this parallel set apply to this quadrilateral?
 //
 public bool HasOppositeParallelSubsegmentSides(Parallel parallel)
 {
     return AreOppositeSubsegmentSides(parallel.segment1, parallel.segment2);
 }
        private static List<EdgeAggregator> CheckAndGenerateParallelImplyAlternateInterior(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;

            // Determine the transversal
            Segment transversal = inter1.AcquireTransversal(inter2);
            if (transversal == null) return newGrounded;

            //
            // Ensure the non-traversal segments align with the parallel segments
            //
            Segment parallel1 = inter1.OtherSegment(transversal);
            Segment parallel2 = inter2.OtherSegment(transversal);

            // The non-transversals should not be the same (coinciding)
            if (parallel1.IsCollinearWith(parallel2)) return newGrounded;

            Segment coincidingParallel1 = parallel.CoincidesWith(parallel1);
            Segment coincidingParallel2 = parallel.CoincidesWith(parallel2);

            // The pair of non-transversals needs to align exactly with the parallel pair of segments
            if (coincidingParallel1 == null || coincidingParallel2 == null) return newGrounded;

            // Both intersections should not be referring to an intersection point on the same parallel segment
            if (parallel.segment1.PointLiesOn(inter1.intersect) && parallel.segment1.PointLiesOn(inter2.intersect)) return newGrounded;
            if (parallel.segment2.PointLiesOn(inter1.intersect) && parallel.segment2.PointLiesOn(inter2.intersect)) return newGrounded;

            // The resultant candidate parallel segments shouldn't share any vertices
            if (coincidingParallel1.SharedVertex(coincidingParallel2) != null) return newGrounded;

            if (inter1.StandsOnEndpoint() && inter2.StandsOnEndpoint())
            {
                //
                // Creates a basic S-Shape with standsOnEndpoints
                //
                //   offThis   ______
                //                   |
                //   offThat   ______|
                //
                // Return <offThis, offThat>
                KeyValuePair<Point, Point> cShapePoints = inter1.CreatesBasicCShape(inter2);
                if (cShapePoints.Key != null && cShapePoints.Value != null) return newGrounded;

                //
                // Creates a basic S-Shape with standsOnEndpoints
                //
                //                  ______ offThat       _______
                //                 |                     \
                //   offThis ______|                 _____\
                //
                // Return <offThis, offThat>
                KeyValuePair<Point, Point> sShapePoints = inter1.CreatesBasicSShape(inter2);
                if (sShapePoints.Key != null && sShapePoints.Value != null)
                {
                    return GenerateSimpleS(parallel, inter1, sShapePoints.Key, inter2, sShapePoints.Value);
                }

                return newGrounded;
            }

            //     _______/________
            //           /
            //          /
            //   ______/_______
            //        /
            if (inter1.Crossing() && inter2.Crossing()) return GenerateDualCrossings(parallel, inter1, inter2);

            // No alt int in this case:
            // Creates an F-Shape
            //   top
            //    _____ offEnd     <--- Stands on Endpt
            //   |
            //   |_____ offStands  <--- Stands on
            //   |
            //   |
            //  bottom
            KeyValuePair<Point, Point> fShapePoints = inter1.CreatesFShape(inter2);
            if (fShapePoints.Key != null && fShapePoints.Value != null) return newGrounded;

            // Alt. Int if an H-Shape
            //
            // |     |
            // |_____|
            // |     |
            // |     |
            //
            if (inter1.CreatesHShape(inter2)) return GenerateH(parallel, inter1, inter2);

            // Creates an S-Shape
            //
            //         |______
            //         |
            //   ______|
            //         |
            //
            //   Order of non-collinear points is order of intersections: <this, that>
            KeyValuePair<Point, Point> standardSShapePoints = inter1.CreatesStandardSShape(inter2);
            if (standardSShapePoints.Key != null && standardSShapePoints.Value != null)
            {
                return GenerateSimpleS(parallel, inter1, standardSShapePoints.Key, inter2, standardSShapePoints.Value);
            }

            // Corresponding if a flying-Shape
            //
            // |     |
            // |_____|___ offCross
            // |     |
            // |     |
            //
            Point offCross = inter1.CreatesFlyingShapeWithCrossing(inter2);
            if (offCross != null)
            {
                return GenerateFlying(parallel, inter1, inter2, offCross);
            }

            //
            // Creates a shape like an extended t
            //     offCross                          offCross
            //      |                                   |
            // _____|____                         ______|______
            //      |                                   |
            //      |_____ offStands     offStands _____|
            //
            // Returns <offStands, offCross>
            KeyValuePair<Point, Point> tShapePoints = inter1.CreatesCrossedTShape(inter2);
            if (tShapePoints.Key != null && tShapePoints.Value != null)
            {
                return GenerateCrossedT(parallel, inter1, inter2, tShapePoints.Key, tShapePoints.Value);
            }

            //
            // Creates a Topped F-Shape
            //            top
            // offLeft __________ offEnd    <--- Stands on
            //             |
            //             |_____ off       <--- Stands on
            //             |
            //             |
            //           bottom
            //
            //   Returns: <bottom, off>
            KeyValuePair<Intersection, Point> toppedFShapePoints = inter1.CreatesToppedFShape(inter2);
            if (toppedFShapePoints.Key != null && toppedFShapePoints.Value != null)
            {
                return GenerateToppedFShape(parallel, inter1, inter2, toppedFShapePoints.Key, toppedFShapePoints.Value);
            }

            return newGrounded;
        }
        //
        // Creates a Topped F-Shape
        //            top
        // oppSide __________       <--- Stands on
        //             |
        //             |_____ off   <--- Stands on
        //             |
        //             |
        //           bottom
        //
        //   Returns: <bottom, off>
        private static List<EdgeAggregator> GenerateToppedFShape(Parallel parallel, Intersection inter1, Intersection inter2, Intersection bottom, Point off)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Intersection top = inter1.Equals(bottom) ? inter2 : inter1;

            // Determine the side of the top intersection needed for the angle
            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment parallelTop = top.OtherSegment(transversal);
            Segment parallelBottom = bottom.OtherSegment(transversal);

            Segment crossingTester = new Segment(off, parallelTop.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);

            Point oppSide = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelTop.Point1 : parallelTop.Point2;

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(off, bottom.intersect, top.intersect),
                                                                        new Angle(oppSide, top.intersect, bottom.intersect));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //     leftTop    rightTop
        //         |         |
        //         |_________|
        //         |         |
        //         |         |
        //   leftBottom rightBottom
        //
        private static List<EdgeAggregator> GenerateH(Parallel parallel, Intersection crossingInterLeft, Intersection crossingInterRight)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Segment transversal = crossingInterLeft.AcquireTransversal(crossingInterRight);

            //
            // Find tops and bottoms
            //
            Segment crossingLeftParallel = crossingInterLeft.OtherSegment(transversal);
            Segment crossingRightParallel = crossingInterRight.OtherSegment(transversal);

            //
            // Determine which points are on the same side of the transversal.
            //
            Segment testingCrossSegment = new Segment(crossingLeftParallel.Point1, crossingRightParallel.Point1);
            Point intersection = transversal.FindIntersection(testingCrossSegment);

            Point leftTop = crossingLeftParallel.Point1;
            Point leftBottom = crossingLeftParallel.Point2;

            Point rightTop = null;
            Point rightBottom = null;
            if (transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                rightTop = crossingRightParallel.Point2;
                rightBottom = crossingRightParallel.Point1;
            }
            else
            {
                rightTop = crossingRightParallel.Point1;
                rightBottom = crossingRightParallel.Point2;
            }

            //
            // Generate the new congruences
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(leftTop, crossingInterLeft.intersect, crossingInterRight.intersect),
                                                                        new Angle(rightBottom, crossingInterRight.intersect, crossingInterLeft.intersect));
            newAngleRelations.Add(gca);
            gca = new GeometricCongruentAngles(new Angle(rightTop, crossingInterRight.intersect, crossingInterLeft.intersect),
                                               new Angle(leftBottom, crossingInterLeft.intersect, crossingInterRight.intersect));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, crossingInterLeft, crossingInterRight);
        }
        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;
        }
        // Corresponding angles if:
        //            sameSide offRightEnd
        // standsOn (o)   o       e
        //                o       e    standsOnEndpoint (e)
        // offLeftEnd  eeeoeeeeeeee
        //                o
        //                o
        //
        // Returns <offLeftEnd, offRightEnd>
        //
        private static List<EdgeAggregator> InstantiateSimpleTIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Point offLeftEnd, Point offRightEnd)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the endpoint and stands intersections
            //
            Intersection endpointInter = null;
            Intersection standsInter = null;
            if (inter1.StandsOnEndpoint() && inter2.StandsOn())
            {
                endpointInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.StandsOnEndpoint() && inter1.StandsOn())
            {
                endpointInter = inter2;
                standsInter = inter1;
            }
            else return newGrounded;

            // Determine the sameSide point
            Segment transversal = inter1.AcquireTransversal(inter2);
            Segment parallelStands = standsInter.OtherSegment(transversal);
            Segment crossingTester = new Segment(offRightEnd, parallelStands.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);

            Point sameSide = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelStands.Point2 : parallelStands.Point1;

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(offLeftEnd, standsInter.intersect, sameSide),
                                                                        new Angle(standsInter.intersect, endpointInter.intersect, offRightEnd));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        //                   top
        //                    o
        //  offStands  oooooooe
        //                    e
        //offEndpoint   eeeeeee
        //                    o
        //                 bottom
        //                       Returns: <offEndpoint, offStands>
        private static List<EdgeAggregator> InstantiateSimplePiIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Point offEndpoint, Point offStands)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the endpoint and stands intersections
            //
            Intersection endpointInter = null;
            Intersection standsInter = null;
            if (inter1.StandsOnEndpoint() && inter2.StandsOn())
            {
                endpointInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.StandsOnEndpoint() && inter1.StandsOn())
            {
                endpointInter = inter2;
                standsInter = inter1;
            }
            else return newGrounded;

            //
            // Determine the top and bottom points
            //
            Segment transversal = inter1.AcquireTransversal(inter2);
            Segment transversalStands = standsInter.GetCollinearSegment(transversal);

            Point top = null;
            Point bottom = null;
            if (Segment.Between(standsInter.intersect, transversalStands.Point1, endpointInter.intersect))
            {
                top = transversalStands.Point1;
                bottom = transversalStands.Point2;
            }
            else
            {
                top = transversalStands.Point2;
                bottom = transversalStands.Point1;
            }

            //
            // Generate the new congruences
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(top, standsInter.intersect, offStands),
                                                                        new Angle(standsInter.intersect, endpointInter.intersect, offEndpoint));
            newAngleRelations.Add(gca);
            gca = new GeometricCongruentAngles(new Angle(bottom, endpointInter.intersect, offEndpoint),
                                               new Angle(endpointInter.intersect, standsInter.intersect, offStands));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        // Corresponding angles if:
        //
        //   left _____________ right
        //           |     |
        //           |     |
        //          off1  off2
        //
        //     Inter 1       Inter 2
        //
        private static List<EdgeAggregator> InstantiatePiIntersection(Parallel parallel, Intersection inter1, Point off1, Intersection inter2, Point off2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment nonParallel1 = inter1.GetCollinearSegment(transversal);
            Segment nonParallel2 = inter2.GetCollinearSegment(transversal);

            Point left = Segment.Between(inter1.intersect, nonParallel1.Point1, inter2.intersect) ? nonParallel1.Point1 : nonParallel1.Point2;
            Point right = Segment.Between(inter2.intersect, inter1.intersect, nonParallel2.Point1) ? nonParallel2.Point1 : nonParallel2.Point2;

            //
            // Generate the new congruences
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            // CTA: Hack to avoid an exception being thrown during testing.
            try
            {
                GeometricCongruentAngles gca1 = new GeometricCongruentAngles(new Angle(left, inter1.intersect, off1),
                                                                             new Angle(inter1.intersect, inter2.intersect, off2));
                newAngleRelations.Add(gca1);

                GeometricCongruentAngles gca2 = new GeometricCongruentAngles(new Angle(right, inter2.intersect, off2),
                                                                             new Angle(inter2.intersect, inter1.intersect, off1));
                newAngleRelations.Add(gca2);
            }
            catch (Exception)
            {
                return newGrounded;
            }

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        private static List<EdgeAggregator> InstantiateIntersection(Parallel parallel, Intersection inter1, Intersection inter2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Avoid:
            //      |            |
            //    __|    ________|
            //      |            |
            //      |            |
            // Both intersections (transversal segments) must contain the actual transversal; that is, a direct, segment relationship must exist
            if (!inter1.CreatesAValidTransversalWith(inter2)) return newGrounded;

            // No corresponding angles if we have:
            //
            //    |          |         |
            //    |__________|         |_________
            //                                   |
            //                                   |
            //
            if (inter1.StandsOnEndpoint() && inter2.StandsOnEndpoint()) return newGrounded;

            // if (Utilities.DEBUG) System.Diagnostics.Debug.WriteLine("Working on: \n\t" + inter1.ToString() + "\n\t" + inter2.ToString());

            //
            // Verify we have a parallel / intersection situation using the given information
            //
            Segment transversal = inter1.AcquireTransversal(inter2);

            // Ensure the non-traversal segments align with the parallel segments
            Segment coincidingParallel1 = parallel.CoincidesWith(inter1.OtherSegment(transversal));
            Segment coincidingParallel2 = parallel.CoincidesWith(inter2.OtherSegment(transversal));

            // The pair of non-transversals needs to align exactly with the parallel pair of segments
            if (coincidingParallel1 == null || coincidingParallel2 == null) return newGrounded;

            // STANDARD Dual Crossings
            // Corresponding angles:
            //
            //      |          |
            //   ___|__________|__
            //      |          |
            //      |          |
            //
            if (inter1.Crossing() && inter2.Crossing()) return InstantiateCompleteIntersection(parallel, inter1, inter2);

            // NOT Corresponding if an H-Shape
            //
            // |     |
            // |_____|
            // |     |
            // |     |
            //
            if (inter1.CreatesHShape(inter2)) return newGrounded;

            // NOT Corresponding angles if:
            //
            //         |______
            //         |
            //   ______|
            //         |
            //
            KeyValuePair<Point, Point> sShapePoints = inter1.CreatesStandardSShape(inter2);
            if (sShapePoints.Key != null && sShapePoints.Value != null) return newGrounded;

            // NOT Corresponding angles if:
            //
            //       |______
            //       |
            // ______|
            KeyValuePair<Point, Point> leanerShapePoints = inter1.CreatesLeanerShape(inter2);
            if (leanerShapePoints.Key != null && leanerShapePoints.Value != null) return newGrounded;

            // Corresponding angles if:
            //    _____
            //   |
            //   |_____
            //   |
            //   |
            //
            KeyValuePair<Point, Point> fShapePoints = inter1.CreatesFShape(inter2);
            if (fShapePoints.Key != null && fShapePoints.Value != null)
            {
                return InstantiateFIntersection(parallel, inter1, fShapePoints.Key, inter2, fShapePoints.Value);
            }

            sShapePoints = inter1.CreatesSimpleSShape(inter2);
            if (sShapePoints.Key != null && sShapePoints.Value != null) return newGrounded;

            // Corresponding angles if:
            //                o       e
            // standsOn (o)   o       e    standsOnEndpoint (e)
            //             eeeoeeeeeeee
            //                o
            //                o
            //
            KeyValuePair<Point, Point> simpleTShapePoints = inter1.CreatesSimpleTShape(inter2);
            if (simpleTShapePoints.Key != null && simpleTShapePoints.Value != null)
            {
                return InstantiateSimpleTIntersection(parallel, inter1, inter2, simpleTShapePoints.Key, simpleTShapePoints.Value);
            }

            // Corresponding angles if:
            //    ____________
            //       |    |
            //       |    |
            //
            KeyValuePair<Point, Point> piShapePoints = inter1.CreatesSimplePIShape(inter2);
            if (piShapePoints.Key != null && piShapePoints.Value != null)
            {
                return InstantiateSimplePiIntersection(parallel, inter1, inter2, piShapePoints.Key, piShapePoints.Value);
            }

            // Corresponding if:
            //
            // |     |        |
            // |_____|____    |_________
            // |              |     |
            // |              |     |
            //
            KeyValuePair<Point, Point> chairShapePoints = inter1.CreatesChairShape(inter2);
            if (chairShapePoints.Key != null && chairShapePoints.Value != null)
            {
                return InstantiateChairIntersection(parallel, inter1, chairShapePoints.Key, inter2, chairShapePoints.Value);
            }

            // Corresponding angles if:
            //    ____________
            //       |    |
            //       |    |
            //
            piShapePoints = inter1.CreatesPIShape(inter2);
            if (piShapePoints.Key != null && piShapePoints.Value != null)
            {
                return InstantiatePiIntersection(parallel, inter1, piShapePoints.Key, inter2, piShapePoints.Value);
            }

            //
            //      |                |
            // _____|____      ______|______
            //      |                |
            //      |_____      _____|
            //
            KeyValuePair<Point, Point> crossedTShapePoints = inter1.CreatesCrossedTShape(inter2);
            if (crossedTShapePoints.Key != null && crossedTShapePoints.Value != null)
            {
                return InstantiateCrossedTIntersection(parallel, inter1, inter2, crossedTShapePoints.Key, crossedTShapePoints.Value);
            }

            // Corresponding if a flying-Shape
            //
            // |     |
            // |_____|___
            // |     |
            // |     |
            //
            KeyValuePair<Intersection, Point> flyingShapeValues = inter1.CreatesFlyingShape(inter2);
            if (flyingShapeValues.Key != null && flyingShapeValues.Value != null)
            {
                return InstantiateFlyingIntersection(parallel, inter1, inter2, flyingShapeValues.Key, flyingShapeValues.Value);
            }

            //        |
            //  ______|______
            //        |
            //   _____|_____
            Point offCross = inter1.CreatesFlyingShapeWithCrossing(inter2);
            if (offCross != null) return InstantiateFlyingCrossedIntersection(parallel, inter1, inter2, offCross);

            //        |
            //  ______|______
            //        |
            //        |_____
            //        |
            offCross = inter1.CreatesExtendedChairShape(inter2);
            if (offCross != null) return InstantiateExtendedChairIntersection(parallel, inter1, inter2, offCross);

            return newGrounded;
        }
        //
        // Creates a shape like a crazy person flying
        //
        //            top   top
        //             |     |
        // larger      |_____|___ off
        //             |     |
        //             |     |
        //
        // Similar to H-shape with an extended point
        // Returns the 'larger' intersection that contains the point: off
        private static List<EdgeAggregator> InstantiateFlyingIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Intersection larger, Point off)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Intersection smallerInter = inter1.Equals(larger) ? inter2 : inter1;

            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment parallel1 = inter1.OtherSegment(transversal);
            Segment parallel2 = inter2.OtherSegment(transversal);

            Point largerTop = parallel1.Point1;
            Point largerBottom = parallel1.Point2;

            Point otherTop = null;
            Point otherBottom = null;

            Segment crossingTester = new Segment(parallel1.Point1, parallel2.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);
            // opposite sides
            if (transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                otherTop = parallel2.Point2;
                otherBottom = parallel2.Point1;
            }
            // same sides
            else
            {
                otherTop = parallel2.Point1;
                otherBottom = parallel2.Point2;
            }

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca1 = new GeometricCongruentAngles(new Angle(off, smallerInter.intersect, otherTop),
                                                                         new Angle(smallerInter.intersect, larger.intersect, largerTop));
            newAngleRelations.Add(gca1);
            GeometricCongruentAngles gca2 = new GeometricCongruentAngles(new Angle(off, smallerInter.intersect, otherBottom),
                                                                         new Angle(smallerInter.intersect, larger.intersect, largerBottom));
            newAngleRelations.Add(gca2);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        // Corresponding angles if:
        //
        //   up  <- may not occur
        //   |_____  offEnd
        //   |
        //   |_____  offStands
        //   |
        //   |
        //  down
        //
        private static List<EdgeAggregator> InstantiateFIntersection(Parallel parallel, Intersection inter1, Point off1, Intersection inter2, Point off2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            Point offEnd = null;
            Point offStands = null;
            Intersection endpt = null;
            Intersection stands = null;
            if (inter1.StandsOnEndpoint())
            {
                endpt = inter1;
                offEnd = off1;
                stands = inter2;
                offStands = off2;
            }
            else if (inter2.StandsOnEndpoint())
            {
                endpt = inter2;
                offEnd = off2;
                stands = inter1;
                offStands = off1;
            }

            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment nonParallelEndpt = endpt.GetCollinearSegment(transversal);
            Segment nonParallelStands = stands.GetCollinearSegment(transversal);

            Point down = null;
            Point up = null;
            if (Segment.Between(stands.intersect, nonParallelStands.Point1, endpt.intersect))
            {
                down = nonParallelStands.Point1;
                up = nonParallelStands.Point2;
            }
            else
            {
                down = nonParallelStands.Point2;
                up = nonParallelStands.Point1;
            }

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            if (!down.Equals(stands.intersect))
            {
                GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(offEnd, endpt.intersect, stands.intersect),
                                                                            new Angle(offStands, stands.intersect, down));
                newAngleRelations.Add(gca);
            }

            if (!up.Equals(endpt.intersect))
            {
                GeometricCongruentAngles gcaOptional = new GeometricCongruentAngles(new Angle(up, endpt.intersect, offEnd),
                                                                                    new Angle(endpt.intersect, stands.intersect, offStands));
                newAngleRelations.Add(gcaOptional);
            }

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
Beispiel #16
0
        //
        // If a common segment exists (a transversal that cuts across both intersections), return that common segment
        //
        public Segment CommonSegment(Parallel thatParallel)
        {
            if (lhs.StructurallyEquals(thatParallel.segment1) || lhs.IsCollinearWith(thatParallel.segment1)) return lhs;
            if (lhs.StructurallyEquals(thatParallel.segment2) || lhs.IsCollinearWith(thatParallel.segment2)) return lhs;
            if (rhs.StructurallyEquals(thatParallel.segment1) || rhs.IsCollinearWith(thatParallel.segment1)) return rhs;
            if (rhs.StructurallyEquals(thatParallel.segment2) || rhs.IsCollinearWith(thatParallel.segment2)) return rhs;

            return null;
        }
        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;
        }
        //
        // Are the parallel sides subsegments of sides of the quadrilateral?
        // If so, instantiate.
        //
        private static List<EdgeAggregator> InstantiateToTrapezoidSubsegments(Quadrilateral quad, Parallel parallel)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Does this parallel set apply to this quadrilateral?
            if (!quad.HasOppositeParallelSubsegmentSides(parallel)) return newGrounded;

            //
            // The other set of sides should NOT be parallel (that's a parallelogram)
            //
            List<Segment> otherSides = quad.GetOtherSubsegmentSides(parallel);

            if (otherSides.Count != 2)
            {
                throw new ArgumentException("Expected TWO sides returned from a quadrilateral / parallel relationship: "
                                            + quad + " " + parallel + " returned " + otherSides.Count);
            }

            if (otherSides[0].IsParallelWith(otherSides[1])) return newGrounded;

            return MakeTrapezoid(quad, parallel);
        }
        //                 offCross
        //                     |
        // leftCross     ______|______   rightCross
        //                     |
        // leftStands     _____|_____    rightStands
        //
        private static List<EdgeAggregator> GenerateFlying(Parallel parallel, Intersection inter1, Intersection inter2, Point offCross)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the crossing intersection and which stands on the endpoints
            //
            Intersection crossingInter = null;
            Intersection standsInter = null;
            if (inter1.Crossing())
            {
                crossingInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.Crossing())
            {
                crossingInter = inter2;
                standsInter = inter1;
            }

            // Determine the side of the crossing needed for the angle
            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment parallelStands = standsInter.OtherSegment(transversal);
            Segment parallelCrossing = crossingInter.OtherSegment(transversal);

            // Determine point orientation in the plane
            Point leftStands = parallelStands.Point1;
            Point rightStands = parallelStands.Point2;
            Point leftCross = null;
            Point rightCross = null;

            Segment crossingTester = new Segment(leftStands, parallelCrossing.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);
            if (transversal.PointLiesOnAndBetweenEndpoints(intersection))
            {
                leftCross = parallelCrossing.Point2;
                rightCross = parallelCrossing.Point1;
            }
            else
            {
                leftCross = parallelCrossing.Point1;
                rightCross = parallelCrossing.Point2;
            }

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(rightCross, crossingInter.intersect, standsInter.intersect),
                                                                        new Angle(leftStands, standsInter.intersect, crossingInter.intersect));
            newAngleRelations.Add(gca);

            gca = new GeometricCongruentAngles(new Angle(leftCross, crossingInter.intersect, standsInter.intersect),
                                               new Angle(rightStands, standsInter.intersect, crossingInter.intersect));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
        private static List<EdgeAggregator> MakeTrapezoid(Quadrilateral quad, Parallel parallel)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Create the new Trapezoid object
            //
            Strengthened newTrapezoid = new Strengthened(quad, new Trapezoid(quad));

            // For hypergraph
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(quad);
            antecedent.Add(parallel);

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

            return newGrounded;
        }
        //
        // Creates a basic S-Shape with standsOnEndpoints
        //
        //                  ______ offThat
        //                 |
        //   offThis ______|
        //
        // Return <offThis, offThat>
        private static List<EdgeAggregator> GenerateSimpleS(Parallel parallel, Intersection inter1, Point offThis, Intersection inter2, Point offThat)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(offThat, inter2.intersect, inter1.intersect),
                                                                        new Angle(offThis, inter1.intersect, inter2.intersect));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }
Beispiel #22
0
        public Segment SharedSegment(Parallel thatParallel)
        {
            if (segment1.IsCollinearWith(thatParallel.segment1) && segment1.IsCollinearWith(thatParallel.segment2)) return segment1;
            if (segment2.IsCollinearWith(thatParallel.segment1) && segment2.IsCollinearWith(thatParallel.segment2)) return segment2;

            return null;
        }
        private static List<EdgeAggregator> MakeRelations(List<CongruentAngles> newAngleRelations, Parallel parallel, Intersection inter1, Intersection inter2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // For hypergraph
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(parallel);
            antecedent.Add(inter1);
            antecedent.Add(inter2);

            foreach (CongruentAngles newAngles in newAngleRelations)
            {
                newGrounded.Add(new EdgeAggregator(antecedent, newAngles, annotation));
            }

            return newGrounded;
        }
Beispiel #24
0
        public int SharesNumClauses(Parallel thatParallel)
        {
            int shared = segment1.IsCollinearWith(thatParallel.segment1) && segment1.IsCollinearWith(thatParallel.segment2) ? 1 : 0;
            shared += segment2.IsCollinearWith(thatParallel.segment1) && segment2.IsCollinearWith(thatParallel.segment2) ? 1 : 0;

            return shared;
        }
Beispiel #25
0
        //
        // Acquire the other 2 sides not in this parallel relationship.
        //
        public List<Segment> GetOtherSubsegmentSides(Parallel parallel)
        {
            List<Segment> segs = new List<Segment>();
            segs.Add(parallel.segment1);
            segs.Add(parallel.segment2);

            return GetOtherSubsegmentSides(segs);
        }
        private static List<EdgeAggregator> InstantiateToParallelogram(Quadrilateral quad, Parallel parallel1, Parallel parallel2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // Does this paralle set apply to this triangle?
            if (!quad.HasOppositeParallelSides(parallel1)) return newGrounded;
            if (!quad.HasOppositeParallelSides(parallel2)) return newGrounded;

            //
            // Create the new Parallelogram object
            //
            Strengthened newParallelogram = new Strengthened(quad, new Parallelogram(quad));

            // For hypergraph
            List<GroundedClause> antecedent = new List<GroundedClause>();
            antecedent.Add(quad);
            antecedent.Add(parallel1);
            antecedent.Add(parallel2);

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

            return newGrounded;
        }
        //
        // For generation of transitive Parallel Lines
        //
        private static List<EdgeAggregator> CreateTransitiveParallelSegments(Parallel parallel1, Parallel parallel2)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            // If there is a deduction relationship between the given congruences, do not perform another substitution
            // CTA: remove?
            if (parallel1.HasGeneralPredecessor(parallel2))
            {
                return newGrounded;
            }

            int numSharedExps = parallel1.SharesNumClauses(parallel2);
            switch (numSharedExps)
            {
                case 0:
                    // Nothing is shared: do nothing
                    break;

                case 1:
                    // Expected case to create a new congruence relationship
                    return Parallel.CreateTransitiveParallel(parallel1, parallel2);

                case 2:
                    // This is either reflexive or the exact same congruence relationship (which shouldn't happen)
                    break;

                default:

                    throw new Exception("Parallel Statements may only have 0, 1, or 2 common expressions; not, " + numSharedExps);
            }

            return newGrounded;
        }
        private static List<EdgeAggregator> InstantiateFromParallelogram(Parallelogram Parallelogram, GroundedClause original)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine the parallel opposing sides and output that.
            //
            Parallel newParallel1 = new Parallel(Parallelogram.top, Parallelogram.bottom);
            Parallel newParallel2 = new Parallel(Parallelogram.left, Parallelogram.right);

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

            newGrounded.Add(new EdgeAggregator(antecedent, newParallel1, annotation));
            newGrounded.Add(new EdgeAggregator(antecedent, newParallel2, annotation));

            return newGrounded;
        }
Beispiel #29
0
        // Determine if the given segment is coinciding with one of the triangle sides; return that
        public Segment DoesParallelCoincideWith(Parallel p)
        {
            if (CoincidesWithASide(p.segment1) != null) return p.segment1;
            if (CoincidesWithASide(p.segment2) != null) return p.segment2;

            return null;
        }
        //
        // Creates a shape like an extended t
        //     offCross                          offCross
        //      |                                   |
        // _____|____ sameSide       sameSide ______|______
        //      |                                   |
        //      |_____ offStands     offStands _____|
        //
        // Returns <offStands, offCross>
        private static List<EdgeAggregator> InstantiateCrossedTIntersection(Parallel parallel, Intersection inter1, Intersection inter2, Point offStands, Point offCross)
        {
            List<EdgeAggregator> newGrounded = new List<EdgeAggregator>();

            //
            // Determine which is the crossing intersection and which stands on the endpoints
            //
            Intersection crossingInter = null;
            Intersection standsInter = null;
            if (inter1.Crossing() && inter2.StandsOnEndpoint())
            {
                crossingInter = inter1;
                standsInter = inter2;
            }
            else if (inter2.Crossing() && inter1.StandsOnEndpoint())
            {
                crossingInter = inter2;
                standsInter = inter1;
            }

            // Determine the side of the crossing needed for the angle
            Segment transversal = inter1.AcquireTransversal(inter2);

            Segment parallelStands = standsInter.OtherSegment(transversal);
            Segment parallelCrossing = crossingInter.OtherSegment(transversal);

            Segment crossingTester = new Segment(offStands, parallelCrossing.Point1);
            Point intersection = transversal.FindIntersection(crossingTester);

            Point sameSide = transversal.PointLiesOnAndBetweenEndpoints(intersection) ? parallelCrossing.Point2 : parallelCrossing.Point1;

            //
            // Generate the new congruence
            //
            List<CongruentAngles> newAngleRelations = new List<CongruentAngles>();

            GeometricCongruentAngles gca = new GeometricCongruentAngles(new Angle(offStands, standsInter.intersect, crossingInter.intersect),
                                                                        new Angle(sameSide, crossingInter.intersect, offCross));
            newAngleRelations.Add(gca);

            return MakeRelations(newAngleRelations, parallel, inter1, inter2);
        }