指向2D轴内对齐的矩形,没有分支

时间:2012-12-03 14:03:46

标签: c algorithm 2d

我正在寻找最优化的方法来检测一个点是否在轴对齐的矩形内。

最简单的解决方案需要4个分支(如果),这对性能不利。

5 个答案:

答案 0 :(得分:7)

给定一个细分[x0, x1]x时,细分(x0 - x) * (x1 - x) <= 0位于细分中。

在二维情况下,你需要做两次,所以它需要两个条件。

答案 1 :(得分:5)

考虑BITWISE-ANDing XMin-X,X-XMax,YMin-Y,Y-YMax的值并使用得到的符号位。

可以同时使用整数和浮点数。

答案 2 :(得分:2)

我认为无论如何你都需要四个测试,但是如果你知道这个点是否更有可能进入或超出矩形,你可以确保这四个测试只在最坏的情况下运行。 / p>

如果内在点的可能性较高,你可以

if ((x>Xmax) || (x<Xmin) || (y>Ymax) || (y<Ymin)) {
 // point not in rectangle
}

否则,反之亦然:

if ((x<=Xmax) && (x>=Xmin) && (y<=Ymax) && (y>=Ymin)) {
 // point in rectangle
}

我很好奇,如果真的会有更好的东西......(除非你可以对矩形边缘的位置做出一些假设,比如它们与2s的力量对齐或类似于那些时髦的东西)

答案 3 :(得分:1)

许多架构支持无分支绝对值操作。如果不是,它可以通过乘法来模拟,或者左移一个有符号值并且对特定的&#34;实现依赖&#34;行为。

同样很可能在英特尔和ARM架构中,操作可以无分支进行

((x0<x) && (x<x1))&((y0<y) && (y<y1))

原因是范围检查通常针对序列进行优化:

mov ebx, 1       // not needed on arm
sub eax, imm0    
sub eax, imm1    // this will cause a carry only when both conditions are met
cmovc eax, ebx   // movcs reg, #1    on ARM

(x)和(y)表达式之间的按位也是无分支的。

编辑最初的想法是:

给定测试范围:a&lt; = x&lt; = b,首先定义中间点。然后可以使用|(x-mid)|来测试两侧&LT;一个;乘以因子B使A的幂为2 ......      (x-mid)* B&lt; 2 ^ n和平方
     ((x-mid)* B)^ 2&lt; 2 ^ 2n

该值仅将位设置为最低有效2n位(如果满足条件)。对范围y和OR进行相同的操作。在这种情况下,必须选择因子C,使得(y-midy)^ 2缩放到相同的2 ^ 2n。

 return (((x-mid)*B)*(((x-mid)*B) | ((y-mid)*C)*((y-mid)*C))) >> (n*2);

对于AABB中的x,y,返回值为0,对于x,y为非,对于x,y为非零。 (这里的操作是,因为人们对(a&amp;&amp; b)&amp;(c&amp; d)的补充感兴趣,这是(!(a&amp;&amp; b) )| |(!(c&amp; dd));

答案 4 :(得分:0)

您没有告诉我们您对所需的可能值和分辨率的范围以及您希望优化的标准的了解。

解决方案是预先计算一组二维布尔值(如果你可以使用它),你可以查找你的坐标对。成本1乘(或移位),1加(用于地址计算)和1个内存读取。

或两个一维布尔阵列。成本2增加,两个内存读取和1个AND,表格更小。