J'écris une structure de quadtree basée sur un nombre entier qui se construit à partir du nœud, et non vers le bas. Pour ce faire, j'ai besoin de découvrir le prochain nœud le plus grand qui contient tous mes éléments. Si j'ai un nœud préexistant défini, alors essayez d'ajouter un élément en dehors des limites de ce nœud, il doit créer un nœud plus grand pour les englober tous les deux. J'ai (ce je pense est intelligent) code pour trouver la zone de délimitation autour d'un seul point:Plus petit nœud de quadtree de limitation
public static Rectangle BoundingRectangle(Point p, int magnitude)
{
Rectangle bounds = new Rectangle()
{
X = (p.X & ~((1 << magnitude) - 1)),
Y = (p.Y & ~((1 << magnitude) - 1)),
Width = (1 << magnitude),
Height = (1 << magnitude)
};
return bounds;
}
[Notez que la zone autour du point (0,0) est une taille Boxof (1,1) à l'emplacement (0,0), pas à l'emplacement (-.5, -. 5), puisque tout est basé sur les entiers]
Cela sera toujours (à partir de ce que je peux dire,) retourner une boîte qui serait s'intégrer dans un quadtree en tant que nœud. Par exemple, new Rectangle(0,0,2,2)
serait acceptable, tout comme new Rectangle(2,2,2,2)
, mais new Rectangle(1,1,2,2)
ne serait pas.
Mon problème est que je ne peux pas comprendre comment accomplir ceci pour un rectangle, au lieu d'un point. La seule solution que je puisse envisager serait de faire des boucles de boîtes de plus en plus grandes, mais je suis sûr qu'il doit y avoir une solution O (1) à laquelle je ne peux pas penser.
Exemples:
Rectangle(X,Y,1,1) -> Rectangle(X,Y,1,1)
Rectangle(0,0,2,2) -> Rectangle(0,0,2,2)
Rectangle(1,1,2,2) -> Rectangle(0,0,4,4)
Rectangle(1,1,3,3) -> Rectangle(0,0,4,4)
Rectangle(0,5,2,2) -> Rectangle(0,4,4,4)
Rectangle(3,3,2,2) -> Rectangle(0,0,8,8)
Mise en œuvre:
private static int BitScanReverse(int mask)
{
int index = 0;
while (mask > 1)
{
mask >>= 1;
index++;
}
return index;
}
public static Rectangle BoundingRectangle(Point p, int magnitude)
{
Rectangle bounds = new Rectangle()
{
X = (p.X & ~((1 << magnitude) - 1)),
Y = (p.Y & ~((1 << magnitude) - 1)),
Width = (1 << magnitude),
Height = (1 << magnitude)
};
return bounds;
}
public static Rectangle BoundingRectangle(Rectangle r, int magnitude)
{
int msb = BitScanReverse((r.X^(r.X + r.Width - 1)) | (r.Y^(r.Y + r.Height - 1)));
return BoundingRectangle(r.Location, Math.Max(msb + 1, magnitude));
}
Super question. Je vais travailler sur ce à la maison si ce n'est pas répondu d'ici là. – mquander
Merci.Ça m'a dérangé un peu. Je pense que je crierais aux gens beaucoup plus intelligents à SO. =] – dlras2
Qu'avez-vous l'intention de faire avec les rectangles qui chevauchent plusieurs nœuds quadtree? ie (1,1,3,3) chevauche 4 nœuds de largeur/hauteur 2. Si vous voulez dire que c'est dedans (0,0,4,4) alors vous aurez toujours de petites choses dans la racine de l'arbre (le plus grand noeud). – phkahler