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; }