Tôi đang viết một cấu trúc quadtree dựa trên số nguyên được xây dựng từ nút và không xuống. Để làm điều này, tôi cần khám phá nút lớn nhất tiếp theo chứa tất cả các phần tử của tôi. Nếu tôi có một nút đã xác định trước, sau đó thử thêm một mục bên ngoài các giới hạn của nút đó, nó cần tạo một nút lớn hơn để bao gồm cả hai nút đó. Tôi có (những gì tôi nghĩ là thông minh) mã cho việc tìm kiếm hộp bounding xung quanh một điểm duy nhất:Nút tứ giác nhỏ nhất
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;
}
[Lưu ý rằng hộp xung quanh điểm (0,0) là một kích thước boxof (1,1) tại vị trí (0,0), không phải tại vị trí (-.5, -. 5), vì tất cả đều dựa trên số nguyên]
Điều này luôn luôn (từ những gì tôi có thể nói) trả về một hộp phù hợp với một quadtree như một nút. Ví dụ: new Rectangle(0,0,2,2)
sẽ được chấp nhận, như là new Rectangle(2,2,2,2)
, nhưng new Rectangle(1,1,2,2)
sẽ không được chấp nhận.
Vấn đề của tôi là tôi không thể tìm ra cách để thực hiện điều này cho một hình chữ nhật, thay vì một điểm. Giải pháp duy nhất tôi có thể nghĩ đến là lặp qua các hộp tăng cường độ lớn, nhưng tôi chắc rằng có một số giải pháp O (1) mà tôi không thể nghĩ ra.
Ví dụ:
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)
Thực hiện:
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));
}
Câu hỏi hay. Tôi sẽ làm việc này ở nhà nếu nó không được trả lời bởi sau đó. – mquander
Cảm ơn.Nó đã được bugging cho tôi một chút. Tôi nghĩ tôi sẽ khóc với những người thông minh hơn ở SO. =] – dlras2
Bạn định làm gì với hình chữ nhật chồng lên nhau nhiều nút tứ giác? tức là (1,1,3,3) chồng lên 4 nút của chiều rộng/chiều cao 2. Nếu bạn muốn nói rằng đó là bên trong (0,0,4,4) thì bạn sẽ luôn luôn có những thứ nhỏ trong thư mục gốc của cây (nút lớn nhất). – phkahler