/// <summary> /// Clones the pictures. /// </summary> /// <param name="newConfiguration">The new configuration of the pictures.</param> /// <returns>The cloned pictures.</returns> internal PicturesOfConfiguration Clone(Configuration newConfiguration) { // Clone the pictures var picturesList = _pictures.Select(picture => picture.Clone()).ToList(); // Create a pictures instance with the cloned pictures var pictures = new PicturesOfConfiguration(newConfiguration, picturesList); // Return them return(pictures); }
/// <summary> /// Initializes a new instance of the <see cref="ContextualPicture"/> class. Throws /// an <see cref="InconsistentPicturesException"/> if it cannot be done. /// </summary> /// <param name="pictures">The pictures that hold all the representations of the configuration.</param> /// <param name="createEmpty">Indicates if we should leave the picture empty without adding any objects or pictures.</param> private ContextualPicture(PicturesOfConfiguration pictures, bool createEmpty) { Pictures = pictures ?? throw new ArgumentNullException(nameof(pictures)); // If we should add objects, do it if (!createEmpty) { // Initialize the dictionary mapping pictures to the object maps Pictures.ForEach(picture => _objects.Add(picture, new Map <GeometricObject, IAnalyticObject>())); // Get the objects that will be added var objects = pictures.Configuration.AllObjects; // Add them, where the last object is a new one. objects.ForEach((configurationObject, index) => Add(configurationObject, isNew: index == objects.Count - 1)); } }
/// <inheritdoc/> public (PicturesOfConfiguration pictures, ConstructionData data) Construct(Configuration configuration, int numberOfPictures, Func <IAnalyticObject[]> looseObjectConstructor) { // Create pictures for the configuration var pictures = new PicturesOfConfiguration(configuration, numberOfPictures); // First we add loose objects to all pictures foreach (var picture in pictures) { // Construct the loose object for the picture var constructedLooseObjects = looseObjectConstructor(); // Add them one by one configuration.LooseObjects.Zip(constructedLooseObjects).ForEach(pair => { // Safely try to add them picture.TryAdd(pair.First, pair.Second, out var equalObject); // If there is an equal object, then we have a weird problem if (equalObject != default) { throw new ConstructorException("Construction of loose objects yielded equal objects! This must be a bug..."); } }); } // Then we add all constructed object foreach (var constructedObject in configuration.ConstructedObjects) { // Construct the object using another method var data = Construct(pictures, constructedObject, addToPictures: true); // Find out if the result is correct var correctResult = data.InconstructibleObject == default && data.Duplicates == default; // If it's not, we directly return the current data without dealing with the remaining objects if (!correctResult) { return(null, data); } } // If we got here, then there are no inconstructible objects and no duplicates return(pictures, new ConstructionData(default, default));
/// <summary> /// Clones the contextual picture by cloning the current one and adding only the last object of the configuration /// represented in the pictures. The last object must already be constructed in the underlying <see cref="Pictures"/>. /// Throws an <see cref="InconsistentPicturesException"/> if it cannot be done. /// </summary> /// <param name="newPictures">The pictures that should be used to construct the contextual picture.</param> /// <returns>The contextual picture containing this cloned picture.</returns> public ContextualPicture ConstructByCloning(PicturesOfConfiguration newPictures) { // Create an empty picture var newPicture = new ContextualPicture(newPictures, createEmpty: true); // We need to have geometric objects cloned // Thus we prepare a dictionary mapping old to newly created ones // To get all the geometric objects we take some map from the _objects var geometricObjectMap = _objects.First().Value.Select(pair => pair.Item1).Select(geometricObject => geometricObject switch { // Point PointObject point => (oldObject: geometricObject, newObject: new PointObject(point.ConfigurationObject) as GeometricObject), // Point LineObject line => (oldObject: geometricObject, newObject: new LineObject(line.ConfigurationObject)), // Circle CircleObject circle => (oldObject: geometricObject, newObject: new CircleObject(circle.ConfigurationObject)), // Unhandled cases _ => throw new ConstructorException($"Unhandled type of {nameof(GeometricObject)}: {geometricObject.GetType()}") })
/// <summary> /// Initializes a new instance of the <see cref="ContextualPicture"/> class. Throws /// an <see cref="InconsistentPicturesException"/> if it cannot be done. /// </summary> /// <param name="pictures">The pictures that hold all the representations of the configuration.</param> public ContextualPicture(PicturesOfConfiguration pictures) : this(pictures, createEmpty : false) { }