Пример #1
0
        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;
        }