/// <summary> /// Finds all intersections of given analytic objects. They must not /// contain <see cref="Point"/>s and duplicate objects. /// </summary> /// <param name="objects">The objects to be intersected.</param> /// <returns>The intersections array.</returns> public static Point[] Intersect(params IAnalyticObject[] objects) { // Find which of the passed objects are lines and circles var lines = objects.OfType <Line>().ToArray(); var circles = objects.OfType <Circle>().ToArray(); // Prepare an array of possible intersections Point[] intersections; // Prepare an array or intersected objects IAnalyticObject[] intersected; // First check if we have two lines... if (lines.Length >= 2) { // If yes, then we intersect them var intersection = lines[0].IntersectionWith(lines[1]); // If there is no intersection, then we can immediately return an empty array if (intersection == null) { return(Array.Empty <Point>()); } // Otherwise we set the intersections to this single one intersections = new[] { intersection.Value }; // And set the intersected objects intersected = new IAnalyticObject[] { lines[0], lines[1] }; } // If we don't have two lines, check if we have at best one line else if (lines.Length == 1) { // If yes, we'll intersect this line with a circle (there must be at least one) intersections = circles[0].IntersectWith(lines[0]); // And set the intersected objects intersected = new IAnalyticObject[] { lines[0], circles[0] }; } // If we don't have any line... else { // We intersect the first two circles intersections = circles[0].IntersectWith(circles[1]); // And set the intersected objects intersected = new IAnalyticObject[] { circles[0], circles[1] }; } // Now we find the remaining (non-intersected) objects var remaningObjects = objects.Where(analyticObject => !intersected.Contains(analyticObject)).ToArray(); // And select those intersection points that lie on all the remaining objects return(intersections.Where(point => remaningObjects.All(analyticObject => LiesOn(analyticObject, point))).ToArray()); }
/// <summary> /// Checks if a given point lies on a given analytic object. The object must not be a point. /// </summary> /// <param name="analyticObject">The analytic object.</param> /// <param name="point">The point.</param> /// <returns>true, if the point lies on the object; false otherwise.</returns> public static bool LiesOn(IAnalyticObject analyticObject, Point point) => // Switch based on the analytic object analyticObject switch {