public List<Circle> FillWithRandomCircles(SizeF areaSize) { const float margin = 1f; const float maxSize = 10f; const float minSize = 3f; const int maxTries = 1000; const int numCirclesAttempts = 2000; var circles = new List<Circle>(); for (var i = 0; i < numCirclesAttempts; i++) { PointF newPoint; float newRadius; List<CircleDistance> distances; int tries = 0; do { newPoint = new PointF(_random.Next(0, (int)areaSize.Width) , _random.Next(0, (int)areaSize.Height) ); distances = circles.Select(c => DistanceFromCircle(c, newPoint)).ToList(); newRadius = distances.Any() ? Math.Min((float)distances.Min(d => d.Distance - d.Radius), maxSize) - margin : maxSize; } while (tries++ < maxTries && (newRadius < minSize || IsOutOfBounds(newPoint, newRadius, areaSize) || distances.Any(d => d.Distance < d.Radius + margin))); if (tries < maxTries) { var newCircle = new Circle { Color = RandomPastelColor(), Position = newPoint, RadiusSize = newRadius, }; circles.Add(newCircle); } else break; } return circles; }
private CircleDistance DistanceFromCircle(Circle circle, PointF point) { var distance = Distance(circle.Position, point); return new CircleDistance {Radius = circle.RadiusSize, Distance = distance}; }