有没有聪明的方法来确定一个点是否在矩形中?

时间:2011-10-01 01:14:02

标签: algorithm

我想计算一个点(x,y)是否位于由两个点(a,b)(c,d)确定的矩形内。

如果a<=cb<=d,则很简单:

a<=x&&x<=c&&b<=y&&y<=d

但是,由于不知道a<=c还是b<=d,代码应该是

(a<=x&&x<=c||c<=x&&x<=a)&&(b<=y&&y<=d||d<=y&&y<=b)

此代码可能有效,但时间太长。我可以编写一个函数并使用它,但我想知道是否有更短的方法(应该执行得非常快 - 代码被调用很多)来编写它。

我能想象的是:

((c-x)*(x-a)>=0)&&((d-y)*(y-b)>=0)

有更聪明的方法吗?

(并且有没有什么好方法可以从c中迭代?)

4 个答案:

答案 0 :(得分:3)

根据需要交换变量,使a = x min ,b = y min

if a > c: swap(a,c)
if b > d: swap(b,d)

a <= x <= c and b <= y <= d

更短但效率稍低:

min(a,c) <= x <= max(a,c) and min(b,d) <= y <= max(b,d)

与优化时一样,您应该分析不同的选项并比较硬数字。流水线操作,指令重新排序,分支预测以及其他现代编译器/处理器优化技术使得程序员级微优化是否值得进行不明显。例如,过去乘法比分支要贵得多,但不再总是如此。

答案 1 :(得分:3)

我喜欢这个:

((c-x)*(x-a)>=0)&&((d-y)*(y-b)>=0)

但是有更多的空白和更多的对称性:

(c-x)*(a-x) <= 0 && (d-y)*(b-y) <= 0

它在数学上很优雅,也可能是最快的。您需要进行测量以确定哪个是最快的。使用现代流水线处理器,我希望使用最少数量的运算符的直线代码运行得最快。

答案 2 :(得分:1)

虽然在接受的答案中建议对(a, b)(c, d)对进行排序可能是这种情况下的最佳解决方案,但更好地应用此方法可能会提升{{1} }和a < b要求程序范围的不变量。即要求程序中的所有矩形从一开始就以这种“规范化”形式创建和维护。因此,在你的矩形测试函数中,你应该简单地断言c < da < b,而不是在每次调用中实际对它们进行排序时浪费CPU资源。

答案 3 :(得分:0)

定义中间变量i = min(a,b)j = min(c,d)k = max(a,b)l = max(c,d)
那么你只需要i<=x && x<=k && j<=y && y<=l

编辑:请注意,在效率方面,最好在函数中使用“太长”的代码。