代码之家  ›  专栏  ›  技术社区  ›  dlras2

最小边界四叉树节点

  •  5
  • dlras2  · 技术社区  · 15 年前

    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;
    }
    

    在位置(-.5,-.5),因为它都是基于整数的]

    new Rectangle(0,0,2,2) new Rectangle(2,2,2,2) ,但是 new Rectangle(1,1,2,2)


    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));
    }
    
    1 回复  |  直到 15 年前
        1
  •  3
  •   Tom Sirgedas    15 年前

    让我们先考虑一下这个的一维版本。不是矩形,而是偏移量和长度。

    边界矩形的“大小”告诉您要忽略多少位。

    1234 = 10011010010
    1289 = 10100001001
    

    显然,我们需要忽略除前2位以外的所有位(忽略9位)。

    我们可以通过1234xor 1289(即475)编程找到这个

    1234 = 10011010010
    1289 = 10100001001
     475 = 00111011011
    

    然后找到475的最高有效位。大多数处理器都有这样的指令(在Windows上,它是位扫描反转)。

    现在,对于二维情况,我们需要得到X轴和Y轴的异或。然后,我们或这两个结果一起。最后,找到最有效的集合位。

    所以,在伪代码中:

    magnitude = MSBof( ( X ^ (X+width-1) ) | ( Y ^ (Y+height-1) ) )
    

    要得到实际的矩形,只需使用post中的函数。传入新点(X,Y)。

    推荐文章