コード例 #1
0
ファイル: MetapostDrawer.cs プロジェクト: PatrikBak/GeoGen
 /// <summary>
 /// Initializes a new instance of the <see cref="MetapostDrawer"/> class.
 /// </summary>
 /// <param name="settings"><inheritdoc cref="_settings" path="/summary"/></param>
 /// <param name="data"><inheritdoc cref="_data" path="/summary"/></param>
 /// <param name="constructor"><inheritdoc cref="_constructor" path="/summary"/></param>
 /// <param name="verifier"><inheritdoc cref="_verifier" path="/summary"/></param>
 public MetapostDrawer(MetapostDrawerSettings settings, MetapostDrawerData data, IGeometryConstructor constructor, IGeometricTheoremVerifier verifier)
 {
     _settings    = settings ?? throw new ArgumentNullException(nameof(settings));
     _data        = data ?? throw new ArgumentNullException(nameof(data));
     _constructor = constructor ?? throw new ArgumentNullException(nameof(constructor));
     _verifier    = verifier ?? throw new ArgumentNullException(nameof(verifier));
 }
コード例 #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProblemGenerator"/> class.
 /// </summary>
 /// <param name="settings">The settings for the problem generator.</param>
 /// <param name="generator">The generator of configurations.</param>
 /// <param name="constructor">The constructor that perform geometric construction of configurations.</param>
 /// <param name="finder">The finder of theorems in generated configurations.</param>
 /// <param name="tracer">The tracer of potential geometry failures.</param>
 public ProblemGenerator(ProblemGeneratorSettings settings,
                         IConfigurationGenerator generator,
                         IGeometryConstructor constructor,
                         ITheoremFinder finder,
                         IGeometryFailureTracer tracer)
 {
     _settings    = settings ?? throw new ArgumentNullException(nameof(settings));
     _generator   = generator ?? throw new ArgumentNullException(nameof(generator));
     _constructor = constructor ?? throw new ArgumentNullException(nameof(constructor));
     _finder      = finder ?? throw new ArgumentNullException(nameof(finder));
     _tracer      = tracer ?? throw new ArgumentNullException(nameof(tracer));
 }
コード例 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TrivialTheoremProducer"/> class.
 /// </summary>
 /// <param name="constructor">The constructor used to construct underlying configurations of composed constructions.</param>
 /// <param name="finder">The theorem finder used to determine theorems of composed constructions.</param>
 public TrivialTheoremProducer(IGeometryConstructor constructor, ITheoremFinder finder)
 {
     _constructor = constructor ?? throw new ArgumentNullException(nameof(constructor));
     _finder      = finder ?? throw new ArgumentNullException(nameof(finder));
 }
コード例 #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GeometricTheoremVerifier"/> class.
 /// </summary>
 /// <param name="constructor">The constructor used for construction of unknown objects of theorems.</param>
 public GeometricTheoremVerifier(IGeometryConstructor constructor)
 {
     _constructor = constructor ?? throw new ArgumentNullException(nameof(constructor));
 }
コード例 #5
0
        /// <summary>
        /// Constructs a given <see cref="Configuration"/> to a given number of pictures, using the
        /// loose object drawing that is in some cases more flexible than the drawing from  the method
        /// <see cref="LooseObjectLayoutDrawing.ConstructUniformLayout(LooseObjectLayout)"/>. These cases
        /// are two: Triangle, when <see cref="RandomLayoutsHelpers.ConstructNiceAcuteTriangle"/> is used,
        /// and Quadrilateral, when <see cref="RandomLayoutsHelpers.ConstructRandomConvexQuadrilateralWithHorizontalSide"/>
        /// or <see cref="RandomLayoutsHelpers.ConstructRandomConvexQuadrilateralWithHorizontalDiagonal"/>
        /// if the picture is symmetric in such a way that it would look better with a horizontal diagonal,
        /// or <see cref="RandomLayoutsHelpers.ConstructRandomConvexQuadrilateralWithHorizontalSide"/> otherwise.
        /// </summary>
        /// <param name="configuration">The configuration to be constructed.</param>
        /// <param name="theorem">The theorem that is used to determine symmetry be constructed.</param>
        /// <param name="numberOfPictures">The number of <see cref="Picture"/>s where the configuration should be drawn.</param>
        /// <returns>The tuple consisting of the pictures and the construction data.</returns>
        /// <exception cref="ConstructorException">Thrown when the construction couldn't be carried out correctly.</exception>
        public static PicturesOfConfiguration ConstructWithFlexibleLayoutRespectingSymmetry(this IGeometryConstructor constructor, Configuration configuration, Theorem theorem, int numberOfPictures)
        {
            #region Loose object layout construction

            // Prepare the function that will construct the loose objects
            IAnalyticObject[] LooseObjectsConstructor()
            {
                // The layout is drawn based on its type
                switch (configuration.LooseObjectsHolder.Layout)
                {
                // We want to draw less uniform triangles
                case LooseObjectLayout.Triangle:
                {
                    // Create the points
                    var(point1, point2, point3) = RandomLayoutsHelpers.ConstructNiceAcuteTriangle();

                    // Return them in an array
                    return(new IAnalyticObject[] { point1, point2, point3 });
                }

                // In quadrilateral cases we need to have a look at its symmetry
                case LooseObjectLayout.Quadrilateral:
                {
                    // Assume we're drawing a quadrilateral ABCD
                    var A = configuration.LooseObjects[0];
                    var B = configuration.LooseObjects[1];
                    var C = configuration.LooseObjects[2];
                    var D = configuration.LooseObjects[3];

                    // We will use a simple local function that checks whether a mapping is symmetric
                    bool IsSymmetric(IReadOnlyDictionary <LooseConfigurationObject, LooseConfigurationObject> mapping)
                    // Take the real mappings
                    => theorem.GetSymmetryMappings(configuration)
                    // And have a look whether any behaves as our
                    .Any(symmetryMapping => mapping.All(pair => symmetryMapping[pair.Key].Equals(pair.Value)));

                    // Find out if the mapping for when the diagonal BD is horizontal is symmetric.
                    // In that case, we need to exchange B and D
                    var canDiagonalBeHorizontal = IsSymmetric(new Dictionary <LooseConfigurationObject, LooseConfigurationObject>
                        {
                            { A, A },
                            { B, D },
                            { C, C },
                            { D, B }
                        });

                    // Find out if the mapping for when the side AB is horizontal is symmetric.
                    // In that case, we need to exchange A, B and also C, D
                    var canSideBeHorizontal = IsSymmetric(new Dictionary <LooseConfigurationObject, LooseConfigurationObject>
                        {
                            { A, B },
                            { B, A },
                            { C, D },
                            { D, C }
                        });

                    // We will want to have horizontal mapping preferably, i.e. if it is possible or the diagonal is not
                    if (canSideBeHorizontal || !canDiagonalBeHorizontal)
                    {
                        // Construct the layout
                        var(point1, point2, point3, point4) = RandomLayoutsHelpers.ConstructRandomConvexQuadrilateralWithHorizontalSide();

                        // Return the points in an array
                        return(new IAnalyticObject[] { point1, point2, point3, point4 });
                    }
                    // Otherwise the side cannot be horizontal, but at least the diagonal can be
                    else
                    {
                        // Construct the layout
                        var(point1, point2, point3, point4) = RandomLayoutsHelpers.ConstructRandomConvexQuadrilateralWithHorizontalDiagonal();

                        // Return the points in an array
                        return(new IAnalyticObject[] { point1, point2, point3, point4 });
                    }
                }

                // By default fall-back to the default uniform layout
                default:
                    return(LooseObjectLayoutDrawing.ConstructUniformLayout(configuration.LooseObjectsHolder.Layout));
                }
            }

            #endregion

            try
            {
                // Try to construct the configuration where the passed theorem holds using our custom layout drawer
                var(pictures, constructionData) = constructor.Construct(configuration, numberOfPictures, LooseObjectsConstructor);

                // Make sure there is no inconstructible object
                if (constructionData.InconstructibleObject != default)
                {
                    throw new ConstructionException("The configuration cannot be constructed, because it contains an inconstructible object.");
                }

                // Make sure there are no duplicates
                if (constructionData.Duplicates != default)
                {
                    throw new ConstructionException("The configuration cannot be constructed, because it contains duplicate objects");
                }

                // If everything is correct, return the pictures
                return(pictures);
            }
            catch (InconsistentPicturesException e)
            {
                // If there is an inconsistency problem, re-throw it with a better exception
                throw new ConstructionException("Construction of the configuration failed due to inconsistencies.", e);
            }
        }
コード例 #6
0
 /// <summary>
 /// Constructs a given <see cref="Configuration"/> to a given number of pictures, using the
 /// loose object drawing from the class <see cref="LooseObjectLayoutDrawing.ConstructUniformLayout(LooseObjectLayout)"/>.
 /// Throws an <see cref="InconsistentPicturesException"/> if the construction couldn't be carried out consistently.
 /// </summary>
 /// <param name="configuration">The configuration to be constructed.</param>
 /// <param name="numberOfPictures">The number of <see cref="Picture"/>s where the configuration should be drawn.</param>
 /// <returns>The tuple consisting of the pictures and the construction data.</returns>
 public static (PicturesOfConfiguration pictures, ConstructionData data) ConstructWithUniformLayout(this IGeometryConstructor constructor, Configuration configuration, int numberOfPictures)
 // Call the drawing function that uses a custom loose object drawer
 => constructor.Construct(configuration, numberOfPictures, () => LooseObjectLayoutDrawing.ConstructUniformLayout(configuration.LooseObjectsHolder.Layout));