public void Test_Line_That_Wasnt_There_Before() { // Create the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var bc = new ConstructedConfigurationObject(LineFromPoints, B, C); var l = new ConstructedConfigurationObject(PerpendicularLine, A, bc); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, bc, l); // Run var(newTheorems, allTheorems) = FindTheorems(configuration); // Assert new theorems newTheorems.OrderlessEquals(new[] { new Theorem(Incidence, l, A) }) .Should().BeTrue(); // Assert all theorems allTheorems.OrderlessEquals(new[] { new Theorem(Incidence, l, A), new Theorem(Incidence, bc, B), new Theorem(Incidence, bc, C) }) .Should().BeTrue(); }
public void Test_That_Old_Theorem_Invalidation_Happens_With_Line_Tangent_To_Circle() { // Create the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var c = new ConstructedConfigurationObject(Incircle, A, B, C); var I = new ConstructedConfigurationObject(Incenter, A, B, C); var D = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, I, B, C); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, c, I, D); // Run var(oldTheorems, newTheorems, invalidOldTheorems, allTheorems) = FindTheorems(configuration); // Assert that old + new - invalidated = all oldTheorems.AllObjects.Concat(newTheorems.AllObjects).Except(invalidOldTheorems).OrderlessEquals(allTheorems.AllObjects).Should().BeTrue(); // Create the invalidated theorem var invalidatedTheorem = new Theorem(LineTangentToCircle, new TheoremObject[] { new LineTheoremObject(B, C), new CircleTheoremObject(c) }); // Assert it is the only one invalidOldTheorems.OrderlessEquals(new[] { invalidatedTheorem }); // Assert it is indeed old oldTheorems.AllObjects.Should().Contain(invalidatedTheorem); }
public void Test_Quadrilateral_With_Very_Strong_Partial_Symmetry() { // Prepare the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new LooseConfigurationObject(Point); var P = new ConstructedConfigurationObject(Midpoint, A, B); var Q = new ConstructedConfigurationObject(Midpoint, B, C); var R = new ConstructedConfigurationObject(Midpoint, C, D); var S = new ConstructedConfigurationObject(Midpoint, D, A); // Prepare the configuration var configuration = Configuration.DeriveFromObjects(Quadrilateral, P, Q, R, S); // Prepare the theorem // NOTE: I did not really try to make it be true in general var theorem = new Theorem(PerpendicularLines, new[] { new LineTheoremObject(P, R), new LineTheoremObject(Q, S) }); // Rank var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null); // Assert rank.Rounded().Should().Be((5d / 9).Rounded()); }
public void Test_GetUnnecessaryObjects_Midline_Is_Half_Of_Side() { // Draw configuration with medians var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var mBC = new ConstructedConfigurationObject(Midpoint, B, C); var mAC = new ConstructedConfigurationObject(Midpoint, C, A); var mAB = new ConstructedConfigurationObject(Midpoint, A, B); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, mBC, mAC, mAB); // This can't be stated in a smaller configuration either new Theorem(EqualLineSegments, new[] { new LineSegmentTheoremObject(mAB, mAC), new LineSegmentTheoremObject(B, mBC) }) .GetUnnecessaryObjects(configuration).Should().BeEmpty(); // Analogously this couldn't be stated in a smaller configuration either new Theorem(EqualLineSegments, new[] { new LineSegmentTheoremObject(mAB, mAC), new LineSegmentTheoremObject(C, mBC) }) .GetUnnecessaryObjects(configuration).Should().BeEmpty(); }
public void Test_Circle_That_Is_Already_There_Implicitly_With_Its_Point_As_Last_Object() { // Create the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var thalesBC = new ConstructedConfigurationObject(CircleWithDiameter, B, C); var D = new ConstructedConfigurationObject(ReflectionInLineFromPoints, A, B, C); // Create the configuration var configuration = Configuration.DeriveFromObjects(RightTriangle, A, thalesBC, D); // Run var(newTheorems, allTheorems) = FindTheorems(configuration); // Assert new theorems newTheorems.OrderlessEquals(new[] { new Theorem(Incidence, thalesBC, D) }) .Should().BeTrue(); // Assert all theorems allTheorems.OrderlessEquals(new[] { new Theorem(Incidence, thalesBC, A), new Theorem(Incidence, thalesBC, B), new Theorem(Incidence, thalesBC, C), new Theorem(Incidence, thalesBC, D) }) .Should().BeTrue(); }
public void Test_Triangle_With_Partial_Symmetry() { // Prepare the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var M = new ConstructedConfigurationObject(Midpoint, A, B); var N = new ConstructedConfigurationObject(Midpoint, A, C); // Prepare the configuration var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, M, N); // Prepare the theorem var theorem = new Theorem(ParallelLines, new[] { new LineTheoremObject(B, C), new LineTheoremObject(M, N) }); // Rank var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null); // Assert rank.Rounded().Should().Be((1d / 3).Rounded()); }
public void Test_Quadrilateral_With_Medium_Partial_Symmetry() { // Prepare the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new LooseConfigurationObject(Point); var P = new ConstructedConfigurationObject(Incenter, A, B, D); var Q = new ConstructedConfigurationObject(Incenter, C, B, D); // Prepare the configuration var configuration = Configuration.DeriveFromObjects(Quadrilateral, P, Q); // Prepare the theorem // NOTE: I did not really try to make it be true in general var theorem = new Theorem(PerpendicularLines, new[] { new LineTheoremObject(P, Q), new LineTheoremObject(B, D) }); // Rank var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null); // Assert rank.Rounded().Should().Be((3d / 9).Rounded()); }
public void Test_InferTheoremsFromSymmetry_PartialSymmetry() { // Draw configuration with medians var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var mAC = new ConstructedConfigurationObject(Midpoint, A, C); var mAB = new ConstructedConfigurationObject(Midpoint, A, B); var D = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, A, B, C); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, mAC, mAB, D); // Create the theorem var theorem = new Theorem(ParallelLines, new[] { new LineTheoremObject(B, D), new LineTheoremObject(mAB, mAC) }); // We can infer one other isomorphic theorem theorem.InferTheoremsFromSymmetry(configuration).Should().BeEquivalentTo(new[] { new Theorem(ParallelLines, new[] { new LineTheoremObject(C, D), new LineTheoremObject(mAB, mAC) }) }); }
public void Test_Triangle_With_Full_Symmetry() { // Prepare the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var P = new ConstructedConfigurationObject(Midpoint, B, C); var Q = new ConstructedConfigurationObject(Midpoint, C, A); var R = new ConstructedConfigurationObject(Midpoint, A, B); // Prepare the configuration var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, P, Q, R); // Prepare the theorem var theorem = new Theorem(ConcurrentLines, new[] { new LineTheoremObject(A, P), new LineTheoremObject(B, Q), new LineTheoremObject(C, R) }); // Rank var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null); // Assert rank.Should().Be(1); }
public void Test_Quadrilateral_With_Full_Symmetry() { // Prepare the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new LooseConfigurationObject(Point); var P = new ConstructedConfigurationObject(Incenter, A, B, C); var Q = new ConstructedConfigurationObject(Incenter, B, C, D); var R = new ConstructedConfigurationObject(Incenter, C, D, A); var S = new ConstructedConfigurationObject(Incenter, D, A, B); // Prepare the configuration var configuration = Configuration.DeriveFromObjects(Quadrilateral, P, Q, R, S); // Prepare the theorem // NOTE: I did not really try to make it be true in general var theorem = new Theorem(ConcyclicPoints, P, Q, R, S); // Rank var rank = new SymmetryRanker().Rank(theorem, configuration, allTheorems: null); // Assert rank.Should().Be(1); }
public void Test_Circle_That_Wasnt_There_Before() { // Create the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var abc = new ConstructedConfigurationObject(Circumcircle, A, B, C); var thalesBC = new ConstructedConfigurationObject(CircleWithDiameter, B, C); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, abc, thalesBC); // Run var(newTheorems, allTheorems) = FindTheorems(configuration); // Assert new theorems newTheorems.OrderlessEquals(new[] { new Theorem(Incidence, thalesBC, B), new Theorem(Incidence, thalesBC, C) }) .Should().BeTrue(); // Assert all theorems allTheorems.OrderlessEquals(new[] { new Theorem(Incidence, thalesBC, B), new Theorem(Incidence, thalesBC, C), new Theorem(Incidence, abc, A), new Theorem(Incidence, abc, B), new Theorem(Incidence, abc, C) }) .Should().BeTrue(); }
public void Test_That_Old_Theorem_Invalidation_Happens_With_Concurrent_Lines() { // Create the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(Midpoint, B, C); var E = new ConstructedConfigurationObject(Midpoint, C, A); var F = new ConstructedConfigurationObject(Midpoint, A, B); var G = new ConstructedConfigurationObject(Centroid, A, B, C); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, D, E, F, G); // Run var(oldTheorems, newTheorems, invalidOldTheorems, allTheorems) = FindTheorems(configuration); // Assert that old + new - invalidated = all oldTheorems.AllObjects.Concat(newTheorems.AllObjects).Except(invalidOldTheorems).OrderlessEquals(allTheorems.AllObjects).Should().BeTrue(); // Create the invalidated theorem var invalidatedTheorem = new Theorem(ConcurrentLines, new[] { new LineTheoremObject(A, D), new LineTheoremObject(B, E), new LineTheoremObject(C, F) }); // Assert it is the only one invalidOldTheorems.OrderlessEquals(new[] { invalidatedTheorem }); // Assert it is indeed old oldTheorems.AllObjects.Should().Contain(invalidatedTheorem); }
public void Test_With_Midpoint_Of_Opposite_Arc() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var M = new ConstructedConfigurationObject(MidpointOfOppositeArc, A, B, C); // Find the trivial theorems Producer.InferTrivialTheoremsFromObject(M) // There should be these theorems .OrderlessEquals(new[] { // Equal line segments new Theorem(EqualLineSegments, new[] { new LineSegmentTheoremObject(B, M), new LineSegmentTheoremObject(C, M) }), // Concyclic points new Theorem(ConcyclicPoints, A, B, C, M), }) .Should().BeTrue(); }
public void Test_Triangle_And_Midpoint_With_Initial_Objects(int iterations, int expectedCount) { // Prepare the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var P = new ConstructedConfigurationObject(Midpoint, A, B); var Q = new ConstructedConfigurationObject(Midpoint, B, C); var R = new ConstructedConfigurationObject(Midpoint, C, A); // Prepare the configuration var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, P, Q, R); // Prepare the input with just the midpoint construction var input = new ConfigurationGeneratorInput ( initialConfiguration: configuration, constructions: new HashSet <Construction> { Midpoint }.ToReadOnlyHashSet(), numberOfIterations: iterations, maximalNumbersOfObjectsToAdd: new Dictionary <ConfigurationObjectType, int> { { Point, int.MaxValue } }, configurationFilter: _ => true ); // Assert counts (can be verified by hand) GetGenerator(ConfigurationFilterType.Fast).Generate(input).ToArray().Length.Should().Be(expectedCount); GetGenerator(ConfigurationFilterType.MemoryEfficient).Generate(input).ToArray().Length.Should().Be(expectedCount); }
public void Test_That_Simplification_Does_Not_Happen_When_It_Would_Add_More_Objects() { // Create the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(Incenter, A, B, C); var E = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, D, B, C); var F = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, D, A, C); var G = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, D, A, B); var l = new ConstructedConfigurationObject(ParallelLineToLineFromPoints, A, E, F); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, l); // Create the theorem var theorem = new Theorem(ConcurrentLines, new[] { new LineTheoremObject(C, D), new LineTheoremObject(E, G), new LineTheoremObject(l) }); // Let it be simplified. Theoretically speaking, CD is the angle bisector and it could be applied, // but neither C nor D could be removed from the configuration, i.e. we would have all the objects // + angle bisector after applying the rule. We don't want that var result = Simplify(theorem, configuration); // Assert it couldn't be done result.Should().BeNull(); }
public void Test_GetObjectsThatWouldMakeThisConfigurationFullySymmetric_Mix() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(PointReflection, B, C); var E = new ConstructedConfigurationObject(Midpoint, B, C); var H = new ConstructedConfigurationObject(Orthocenter, A, B, C); var I = new ConstructedConfigurationObject(Incenter, A, B, C); var G = new ConstructedConfigurationObject(Centroid, E, I, H); var K = new ConstructedConfigurationObject(PointReflection, H, I); // Create the configuration and call the method Configuration.DeriveFromObjects(Triangle, D, E, H, I, G, K).GetObjectsThatWouldMakeThisConfigurationFullySymmetric() // We need lots of objects .Should().BeEquivalentTo(new[] { new ConstructedConfigurationObject(PointReflection, C, B), new ConstructedConfigurationObject(PointReflection, A, B), new ConstructedConfigurationObject(PointReflection, B, A), new ConstructedConfigurationObject(PointReflection, A, C), new ConstructedConfigurationObject(PointReflection, C, A), new ConstructedConfigurationObject(Midpoint, A, C), new ConstructedConfigurationObject(Midpoint, A, B), new ConstructedConfigurationObject(Centroid, new ConstructedConfigurationObject(Midpoint, A, C), I, H), new ConstructedConfigurationObject(Centroid, new ConstructedConfigurationObject(Midpoint, A, B), I, H), }); }
public void Test_Getting_Defining_Objects() { // Initialize some objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(Midpoint, A, B); var E = new ConstructedConfigurationObject(Midpoint, B, C); var F = new ConstructedConfigurationObject(Midpoint, C, A); var G = new ConstructedConfigurationObject(IntersectionOfLinesFromPoints, B, F, C, D); var c = new ConstructedConfigurationObject(Circumcircle, E, F, G); var X = new ConstructedConfigurationObject(Circumcenter, A, B, C); var Y = new ConstructedConfigurationObject(Midpoint, X, G); // Check loose object A.GetDefiningObjects().Should().BeEquivalentTo(A); // Check simple constructed object D.GetDefiningObjects().Should().BeEquivalentTo(A, B, D) .And.ContainInOrder(A, D) .And.HaveElementSucceeding(B, D); // Check complex constructed object c.GetDefiningObjects().Should().BeEquivalentTo(A, B, C, D, E, F, G, c) .And.ContainInOrder(E, c) .And.ContainInOrder(F, c) .And.ContainInOrder(G, c) .And.ContainInOrder(B, E) .And.ContainInOrder(C, E) .And.ContainInOrder(C, F) .And.ContainInOrder(A, F) .And.ContainInOrder(B, G) .And.ContainInOrder(F, G) .And.ContainInOrder(C, G) .And.ContainInOrder(D, G) .And.ContainInOrder(A, D) .And.ContainInOrder(B, D); // Check calling on more objects new[] { X, Y, c }.GetDefiningObjects().Should().BeEquivalentTo(A, B, C, D, E, F, G, c, X, Y) .And.ContainInOrder(E, c) .And.ContainInOrder(F, c) .And.ContainInOrder(G, c) .And.ContainInOrder(B, E) .And.ContainInOrder(C, E) .And.ContainInOrder(C, F) .And.ContainInOrder(A, F) .And.ContainInOrder(B, G) .And.ContainInOrder(F, G) .And.ContainInOrder(C, G) .And.ContainInOrder(D, G) .And.ContainInOrder(A, D) .And.ContainInOrder(B, D) .And.ContainInOrder(A, X) .And.ContainInOrder(B, X) .And.ContainInOrder(C, X) .And.ContainInOrder(X, Y) .And.ContainInOrder(G, Y); }
public void Test_That_Old_Theorem_Invalidation_Does_Not_Happen_With_Tangent_Circles() { // Create the objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var l = new ConstructedConfigurationObject(TangentLine, A, B, C); var D = new ConstructedConfigurationObject(PerpendicularProjection, B, l); var E = new ConstructedConfigurationObject(PerpendicularProjection, C, l); var F = new ConstructedConfigurationObject(ReflectionInLineFromPoints, D, B, C); var G = new ConstructedConfigurationObject(ReflectionInLineFromPoints, E, B, C); var P = new ConstructedConfigurationObject(IntersectionOfLineAndLineFromPoints, l, B, C); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, F, G, P); // Run var(oldTheorems, newTheorems, invalidOldTheorems, allTheorems) = FindTheorems(configuration); // Assert that old + new - invalidated = all oldTheorems.AllObjects.Concat(newTheorems.AllObjects).Except(invalidOldTheorems).OrderlessEquals(allTheorems.AllObjects).Should().BeTrue(); // Assert only concurrencies have been invalidated invalidOldTheorems.OrderlessEquals(new[] { new Theorem(ConcurrentLines, new[] { new LineTheoremObject(F, G), new LineTheoremObject(B, C), new LineTheoremObject(l) }), new Theorem(ConcurrentLines, new[] { new LineTheoremObject(F, G), new LineTheoremObject(B, C), new LineTheoremObject(D, E) }), new Theorem(ConcurrentLines, new[] { new LineTheoremObject(F, G), new LineTheoremObject(B, C), new LineTheoremObject(A, D) }), new Theorem(ConcurrentLines, new[] { new LineTheoremObject(F, G), new LineTheoremObject(B, C), new LineTheoremObject(A, E) }) }) .Should().BeTrue(); // Assert there is an old tangency oldTheorems.AllObjects.Should().Contain(new Theorem(TangentCircles, new[] { new CircleTheoremObject(B, D, F), new CircleTheoremObject(C, E, G) })); }
/// <summary> /// Initializes a new instance of the <see cref="DrawingRule"/> class. /// </summary> /// <param name="objectToDraw">The template of an object to be drawn. Its argument are assumed to be <see cref="LooseConfigurationObject"/>s.</param> /// <param name="auxiliaryObjects">The list of auxiliary objects that are needed to be constructed in order to draw what's needed.</param> /// <param name="drawingCommands">The commands containing the actual information about what should be drawn.</param> public DrawingRule(ConstructedConfigurationObject objectToDraw, IReadOnlyList <ConstructedConfigurationObject> auxiliaryObjects, IReadOnlyList <DrawingCommand> drawingCommands) { ObjectToDraw = objectToDraw ?? throw new ArgumentNullException(nameof(objectToDraw)); AuxiliaryObjects = auxiliaryObjects ?? throw new ArgumentNullException(nameof(auxiliaryObjects)); DrawingCommands = drawingCommands ?? throw new ArgumentNullException(nameof(drawingCommands)); }
private static Configuration HiddenExcenter() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(Incenter, A, B, C); var E = new ConstructedConfigurationObject(OppositePointOnCircumcircle, D, B, C); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, E)); }
private static Configuration Parallelogram() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(PointReflection, B, A); var E = new ConstructedConfigurationObject(PointReflection, C, A); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, D, E)); }
private static Configuration HiddenMidpoint() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(Median, A, B, C); var E = new ConstructedConfigurationObject(IntersectionOfLineAndLineFromPoints, D, B, C); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, D, E)); }
private static Configuration PerpendicularBisectorsAreConcurrent() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var l1 = new ConstructedConfigurationObject(PerpendicularBisector, B, C); var l2 = new ConstructedConfigurationObject(PerpendicularBisector, C, A); var l3 = new ConstructedConfigurationObject(PerpendicularBisector, A, B); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, A, B, C, l1, l2, l3)); }
private static Configuration Midpoints() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(Midpoint, A, B); var E = new ConstructedConfigurationObject(Midpoint, B, C); var F = new ConstructedConfigurationObject(Midpoint, C, A); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, D, E, F)); }
public void Test_Triangle_With_Midpoints_And_Feets_Of_Altitudes_Which_Should_Be_Concyclic() { // Create the objects var A = new LooseConfigurationObject(ConfigurationObjectType.Point); var B = new LooseConfigurationObject(ConfigurationObjectType.Point); var C = new LooseConfigurationObject(ConfigurationObjectType.Point); var D = new ConstructedConfigurationObject(Midpoint, B, C); var E = new ConstructedConfigurationObject(Midpoint, A, C); var F = new ConstructedConfigurationObject(Midpoint, A, B); var G = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, A, B, C); var H = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, B, C, A); var I = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, C, A, B); // Create the configuration var configuration = Configuration.DeriveFromObjects(Triangle, A, B, C, D, E, F, G, H, I); // Create the picture var picture = CreatePicture(configuration, new[] { new IAnalyticObject[] { new Point(0, 5), new Point(-2, 1), new Point(6, 1), new Point(2, 1), new Point(3, 3), new Point(-1, 3), new Point(0, 1), new Point(6.0 / 13, 61.0 / 13), new Point(-0.4, 4.2) }, new IAnalyticObject[] { new Point(0, 3), new Point(-2, 1), new Point(6, 1), new Point(2, 1), new Point(3, 2), new Point(-1, 2), new Point(0, 1), new Point(-1.2, 3.4), new Point(2, 5) } }); // Test that there is one circle which passes through 6 points (Feurbach circle) picture.AllCircles.Count(circle => circle.Points.Count == 6).Should().Be(1); // Test the number of circles passing through 4 points picture.AllCircles.Count(circle => circle.Points.Count == 4).Should().Be(3, "two vertices and corresponding feet are concyclic"); }
private static Configuration IncenterAndTangentLine() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var l1 = new ConstructedConfigurationObject(InternalAngleBisector, B, A, C); var l2 = new ConstructedConfigurationObject(InternalAngleBisector, C, A, B); var D = new ConstructedConfigurationObject(IntersectionOfLines, l1, l2); var E = new ConstructedConfigurationObject(TangentLine, D, B, C); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, A, B, C, D, E)); }
private static Configuration LineTangentToCircle() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(Incenter, A, B, C); var E = new ConstructedConfigurationObject(PerpendicularProjectionOnLineFromPoints, D, B, C); var F = new ConstructedConfigurationObject(PointReflection, E, D); var G = new ConstructedConfigurationObject(ReflectionInLineFromPoints, F, A, D); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, A, B, C, D, E, F, G)); }
private static Configuration ConcurrencyViaObjectIntroduction() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var D = new ConstructedConfigurationObject(Orthocenter, A, B, C); var E = new ConstructedConfigurationObject(Circumcenter, B, C, D); var F = new ConstructedConfigurationObject(ParallelogramPoint, A, B, C); var G = new ConstructedConfigurationObject(Incenter, B, C, E); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, A, B, C, D, E, F, G)); }
/// <summary> /// Handles a new object by commuting it with the scheduler and finding its trivial theorems and passing those to be handled /// by the normalization helper and scheduler. /// </summary> /// <param name="newObject">The new object to be handled.</param> /// <param name="helper">The normalization helper used later for the trivial theorems of the object.</param> /// <param name="scheduler">The scheduler of inference rules used for the new object and later for its trivial theorems.</param> /// <param name="builder">Either the builder to build theorem proofs; or null, if we are not constructing proofs.</param> private void HandleNewObject(ConstructedConfigurationObject newObject, NormalizationHelper helper, Scheduler scheduler, TheoremProofBuilder builder) { // Schedule after finding this object scheduler.ScheduleAfterDiscoveringObject(newObject); // Look for its trivial theorems foreach (var trivialTheorem in _producer.InferTrivialTheoremsFromObject(newObject)) { // Prepare the proof data in case we need to construct proofs var proofData = builder != null ? new ProofData(builder, new TheoremInferenceData(TrivialTheorem), assumptions: Array.Empty <Theorem>()) : null; // Let the other method handle this theorem, while ignoring whether it is geometrically valid (it just should be) HandleNonequality(trivialTheorem, helper, scheduler, proofData, out var _); } }
private static Configuration SimpleLineSegments() { // Create objects var A = new LooseConfigurationObject(Point); var B = new LooseConfigurationObject(Point); var C = new LooseConfigurationObject(Point); var l = new ConstructedConfigurationObject(TangentLine, A, B, C); var D = new ConstructedConfigurationObject(PerpendicularProjection, B, l); var E = new ConstructedConfigurationObject(PerpendicularProjection, C, l); var F = new ConstructedConfigurationObject(Midpoint, B, D); var G = new ConstructedConfigurationObject(Midpoint, C, E); // Return the configuration return(Configuration.DeriveFromObjects(Triangle, A, B, C, D, E, F, G)); }