親キャンバスに複数の子キャンバスをランダムに配置しようとしています。兄弟キャンバスをオーバーラップ (または衝突) させたくないので、衝突検出を使用しています。
衝突があるため、明らかに何か間違ったことをしていますが、指を置くことはできません。
私の draw メソッド (毎秒呼び出されます)
private void draw(int args)
{
parent.Children.Clear();
List<MyCanvas> children = fetchManyChildren(100);
Random rand = new Random();
foreach (MyCanvas child in children)
{
child.xPos = nextDouble(rand, 0, parent.ActualWidth - child.Width);
child.yPos = nextDouble(rand, 0, parent.ActualHeight - child.Height);
foreach (MyCanvas sibling in parent.Children)
{
while (child.collidesWith(sibling))
{
child.xPos = nextDouble(rand, 0, parent.ActualWidth - child.Width);
child.yPos = nextDouble(rand, 0, parent.ActualHeight - child.Height);
}
}
Canvas.SetLeft(child, child.xPos);
Canvas.SetTop(child, child.yPos);
parent.Children.Add(child);
}
}
いくつかのヘルパー メソッド:
private List<MyCanvas> fetchManyChildren(int amount)
{
List<MyCanvas> children = new List<MyCanvas>(amount);
Random rand = new Random();
for (int i = 1; i <= amount; i++)
{
double size = nextDouble(rand, 1, MAX_SIZE);
MyCanvas child = new MyCanvas(0, 0, size, size);
child.Background = randomBrush(rand);
children.Add(child);
}
return children;
}
private double nextDouble(Random rand, double min, double max)
{
return min + (rand.NextDouble() * (max - min));
}
Canvas に x/y 位置を指定し、衝突をチェックできる Canvas から派生したクラス:
public class MyCanvas : Canvas
{
public double xPos = 0;
public double yPos = 0;
public MyCanvas(double x, double y, double w, double h)
{
this.xPos = x;
this.yPos = y;
this.Width = w;
this.Height = h;
}
public bool collidesWith(MyCanvas p)
{
double bottom = this.yPos + this.Height;
double top = this.yPos;
double left = this.xPos;
double right = this.xPos + this.Width;
return !((bottom < p.yPos) ||
(top > p.yPos + p.Height) ||
(left > p.xPos + p.Width) ||
(right < p.xPos));
}
}