我正在编写一个基于整数的四叉树结构,它从节点开始构建,而不是向下构建。为此,我需要发现包含我所有元素的下一个最大节点。如果我定义了一个预先存在的节点,然后尝试在该节点的边界之外添加一个项目,它需要创建一个更大的节点来包含它们。我有(我认为很聪明的)代码用于在单点周围找到边界框:
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;
}
[请注意,点 (0,0) 周围的框在位置 (0,0) 处是大小为 (1,1) 的框, 而不是在位置 (-.5,-.5),因为它都是基于整数的]
这将始终(据我所知)返回一个适合作为节点的四叉树的框。例如,new Rectangle(0,0,2,2)
可以接受,就像 一样new Rectangle(2,2,2,2)
,但new Rectangle(1,1,2,2)
不会。
我的问题是我不知道如何为一个矩形而不是一个点来完成这个。我能想到的唯一解决方案是循环通过数量增加的盒子,但我确信必须有一些我无法想到的 O(1) 解决方案。
例子:
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)
执行:
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));
}