/// <summary> /// Creates a formatted string describing a given geometric object. /// </summary> /// <param name="formatter">The output formatter.</param> /// <param name="geometricObject">The geometric object.</param> /// <returns>The string representing the geometric object.</returns> public static string FormatGeometricObject(this OutputFormatter formatter, GeometricObject geometricObject) { // Prepare the result var result = ""; // If the physical object is present, append it's name if (geometricObject.ConfigurationObject != null) { result += formatter.GetObjectName(geometricObject.ConfigurationObject); } // Furthermore switch based on type switch (geometricObject) { // If we have an object with points... case DefinableByPoints objectWithPoints: // If there are no points, then we're done if (objectWithPoints.Points.IsEmpty()) { return(result); } // Otherwise we convert points var pointsString = objectWithPoints.Points // By taking their names .Select(point => formatter.GetObjectName(point.ConfigurationObject)) // Ordering them .Ordered() // And joining with commas .ToJoinedString(); // And return based on whether this is a line or circle return(objectWithPoints switch { // Enclose line points in [] LineObject _ => $"{result}[{pointsString}]", // Enclose circle points in () CircleObject _ => $"{result}({pointsString})", // Otherwise we have an unhandled type _ => throw new ConstructorException($"Unhandled type of {nameof(DefinableByPoints)}: {objectWithPoints.GetType()}") });
/// <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> /// Adds a line to the collection of lines passing through this point. /// </summary> /// <param name="line">The passing line</param> internal void AddLine(LineObject line) => _lines.Add(line);