/// <summary> /// Creates a random simple polygon within the specified area.</summary> /// <param name="x"> /// The smallest x-coordinate for any polygon vertex.</param> /// <param name="y"> /// The smallest y-coordinate for any polygon vertex.</param> /// <param name="width"> /// The width of the area containing all polygon vertices.</param> /// <param name="height"> /// The height of the area containing all polygon vertices.</param> /// <returns> /// An <see cref="Array"/> containing the <see cref="PointD"/> coordinates that are the /// vertices of the created polygon.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="width"/> or <paramref name="height"/> is equal to or less than zero. /// </exception> /// <remarks> /// <b>RandomPolygon</b> moves in a full circle around the center of the specified area, /// placing vertices at random angles and radii within the area. Any two vertices are /// separated by a minimum angular distance of 6 degrees. The resulting polygon is simple, /// i.e. covering a single contiguous space without self-intersections.</remarks> public static PointD[] RandomPolygon(double x, double y, double width, double height) { if (width <= 0) { ThrowHelper.ThrowArgumentOutOfRangeException( "width", width, Strings.ArgumentNotPositive); } if (height <= 0) { ThrowHelper.ThrowArgumentOutOfRangeException( "height", height, Strings.ArgumentNotPositive); } // drawing range extending from center of drawing area SizeD range = new SizeD(width / 2.0, height / 2.0); PointD center = new PointD(x + range.Width, y + range.Height); // radius of circle circumscribed around drawing area double radius = Math.Sqrt(range.Width * range.Width + range.Height * range.Height); // create vertices as series of random polar coordinates var polygon = new List <PointD>(); for (double degrees = 0; degrees < 360; degrees += 6.0) { // random increment of angle for next vertex degrees += MersenneTwister.Default.NextDouble() * 110; if (degrees >= 360) { break; } double radians = degrees * Angle.DegreesToRadians; // axis projections of circumscribed radius at current angle double dx = Math.Cos(radians) * radius; double dy = Math.Sin(radians) * radius; // shorten total radius where it extends beyond area double dxLimit = range.Width / Math.Abs(dx); double dyLimit = range.Height / Math.Abs(dy); double factor = Math.Min(dxLimit, dyLimit); // additional random shortening to determine vertex factor *= MersenneTwister.Default.NextDouble(); polygon.Add(new PointD(center.X + dx * factor, center.Y + dy * factor)); } return(polygon.ToArray()); }
/// <summary> /// Converts the specified <see cref="SizeD"/> to a WPF <see cref="Size"/>.</summary> /// <param name="size"> /// The <see cref="SizeD"/> instance to convert.</param> /// <returns> /// A new WPF <see cref="Size"/> instance whose dimensions equal those of the specified /// <paramref name="size"/>.</returns> public static Size ToWpfSize(this SizeD size) { return(new Size(size.Width, size.Height)); }