Самый маленький узел дерева квадрантов ограничения

Я пишу основанную на целом числе структуру дерева квадрантов, которая растет от узла, и не вниз. Чтобы сделать это, я должен обнаружить следующий самый большой узел, который содержит все мои элементы. Если мне определили существующий ранее узел, то попытайтесь добавить объект за пределами границ того узла, он должен создать больший узел для затрагивания их обоих. Я имею (что я думаю, умно), код для нахождения ограничительной рамки вокруг единственной точки:

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) является boxof размером (1,1) в местоположении (0,0), не в местоположении (-.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));
}
5
задан dlras2 21 July 2010 в 13:46
поделиться