在面板上画圆,圆的大小,位置都是随机的,怎么样才能保证每次新添加的圆与之前全部的圆都不相交呢?求知道的大牛们帮帮忙,小弟想了许久也不知该如何解决这个问题
------解决思路----------------------
记录下每个圆心的位置,和半径 。
再用你新画的这个圆心计算出和其圆心的距离,如果这个距离小于两个圆的半径相加,则有重合部分。
------解决思路----------------------
圆心之间的直线距离大于两个圆的半径之和
------解决思路----------------------
如果圆的半径是已知的(假设为R),基本上流程可能是:
将区域中所有可能的点进行随机次序排序,然后遍历,找到第一个点,使得它与任何圆(如果半径是r)之间的距离(计算两点中间的距离需要几何知识)都不小于 R+r。如果全都不满足,那就没有所谓的“随机位置”了。
这个程序肯定会非常非常地慢。它没有什么优化的处理方法,完全是暴利简单地判断。
------解决思路----------------------
先给个示例代码
private void panel1_Paint(object sender, PaintEventArgs e)
{
var list = new List<Rectangle>();
var rand = new Random();
var g = e.Graphics;
int N = 100; //圆的个数
for (int i = 0; i < 1000; i++) //限定最多试探次数,以免出现死循环
{
var x = rand.Next(0, panel1.Width);
var y = rand.Next(0, panel1.Height);
var r = rand.Next(4, 20);
var rct = new Rectangle(x, y, 2*r, 2*r);
if (list.IndexOf(rct) < 0) //已经画过的就不画了
{
var rs = list.Where(t => t.IntersectsWith(rct)).ToArray();//这是关键:检查圆控制矩形是否相交
if (rs.Length > 0) continue;
list.Add(rct);
g.DrawEllipse(Pens.Red, rct);
if (--N == 0) break;
}
}
}
使用了比较简陋的判别方法:
画园时需要一个控制矩形,所以只要这些控制矩形不想交,那么圆就不会相交(至多相切)
而 C# 已经提供了判别矩形是否相交的方法 IntersectsWith,所以速度不会慢
当然,这个算法会使一些本可以画的地方画不上,但由于都是随机的,所以无碍大局。当圆很多很密时就看出来了
精准一点的还是要通过圆的方程进行判断,计算量要大些,也不一定就慢