我想计算一个点(x,y)
是否位于由两个点(a,b)
和(c,d)
确定的矩形内。
如果a<=c
和b<=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中迭代?)
答案 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 < d
和a < 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
。
编辑:请注意,在效率方面,最好在函数中使用“太长”的代码。