通过位运算符检查点是否在矩形内

时间:2012-04-07 05:33:34

标签: algorithm geometry bit-manipulation

几天前,我的老师告诉我,可以仅使用位运算符检查给定点是否在给定矩形内。这是真的吗?如果是这样,我该怎么做?

3 个答案:

答案 0 :(得分:3)

这可能无法解答您的问题,但您正在寻找的可能是这个 These are the tricks由Sean Eron Anderson编写,他甚至为那些能找到一个bug的人提供了10美元的赏金。我在这里找到的最接近的是一个宏,它可以找到任何整数 X 是否有一个between M and N

  

确定单词是否在m和n之间有一个字节

     

当m < n,该技术测试单词x是否包含无符号字节值,使得m <1。价值&lt; ñ。当n和m为常数时,它使用7次算术/逻辑运算。   注意:等于n的字节可以通过可能在误报之间报告,因此如果需要某个结果,则应该按字符检查。

     

要求:x&gt; = 0; 0℃; = M&LT; = 127; 0℃; = N&LT; = 128

#define likelyhasbetween(x,m,n) \
((((x)-~0UL/255*(n))&~(x)&((x)&~0UL/255*127)+~0UL/255*(127-(m)))&~0UL/255*128)
     

这种技术适用于快速预测试。一个变量需要再做一次操作(对于常数m和n总共8次),但提供的确切答案是:

#define hasbetween(x,m,n) \
((~0UL/255*(127+(n))-((x)&~0UL/255*127)&~(x)&((x)&~0UL/255*127)+~0UL/255*(127-(m)))&~0UL/255*128)

答案 1 :(得分:2)

x,如果{x0<x<x1 and y0<y<y1}

,则y位于矩形{x0<x and x<x1 and y0<y and y<y1}

如果我们可以模拟&lt;有了位操作符,那我们就好了。

说些什么是什么意思?在二进制?考虑

a: 0 0 0 0 1 1 0 1
b: 0 0 0 0 1 0 1 1

在上面,a> b,因为它包含第一个1,其中b中的对应部分是0.我们是那些寻找最左边位的那些myBit!=otherBit。 (==或equiv是一个按位运算符,可以用和/或/不表示)

然而,我们需要一些方法来将信息以一位传播到多位。所以我们问自己:我们可以仅使用“位”运算符“编码”一个函数,这相当于if(q,k,a,b) = if q[k] then a else b。答案是肯定的:

  • 我们创建一个位字,包括在每个位上复制q [k]。我有两种方法可以做到这一点:
    • 1)左移k,然后通过单词右移(有效,但只有当你有移位运算符复制最后一位时才有效)
    • 2)效率低但理论上正确的方法:
      • 我们左移q乘以k位
      • 我们将此结果与and一起使用10000 ... 0
      • 我们右移1位,or右移版本。这将位首先复制到第二位。我们重复这个过程,直到整个单词与第一位相同(例如64次)
  • 调用此结果mask,我们的函数为(mask and a) or (!mask and b):如果a的{​​{1}}位为真,则结果为k,其他为结果将是q

取位向量c = b,我们使用a!=b and a==1111..1 and b==0000..0函数连续测试第一位是1,然后第二位是1,等等:

if

这需要a<b := if(c,0, if(a,0, B_LESSTHAN_A, A_LESSTHAN_B), if(c,1, if(a,1, B_LESSTHAN_A, A_LESSTHAN_B), if(c,2, if(a,2, B_LESSTHAN_A, A_LESSTHAN_B), if(c,3, if(a,3, B_LESSTHAN_A, A_LESSTHAN_B), if(... if(c,64, if(a,64, B_LESSTHAN_A, A_LESSTHAN_B), A_EQUAL_B) ) ...) ) ) ) ) 个步骤。但是,如果不允许递归,则可以使用递归定义的函数写入3行,或者使用定点组合符。

然后我们将其转换为更大的功能:wordsize

答案 2 :(得分:2)

如果数字是有限正整数,则可能。

假设我们有一个由(a1,b1)(a2,b2)表示的矩形。给定一个点(x,y),我们只需要评估表达式(a1<x) & (x<a2) & (b1<y) & (y<b2)。所以现在的问题是找到表达式c的相应位操作

ci为数字c的第i位(可以通过屏蔽ci和位移来获得)。我们证明,对于最多n位的数字,c<d相当于r_(n-1),其中

r_i = ((ci^di) & ((!ci)&di))  |  (!(ci^di) & r_(i-1))

证明:cidi不同时,左边的表达式可能为真(取决于((!ci)&di)),否则正确的表达式可能是是(取决于r_(i-1),这是下一位的比较)。

表达式((!ci)&di)实际上等同于位比较ci < di。因此,这个递归关系返回true,它从左到右逐位比较,直到我们可以确定c小于d

因此,对应于比较运算符的纯位运算表达式,因此可以使用纯位运算在矩形内找到一个点。

编辑:实际上不需要条件语句,只需展开r_(n+1),然后完成。