我可以简化不等式“距离(p1,p2)<距离(p1,p3)吗?”


14

我正在研究一些矢量逻辑,所以问:可以通过简化以下不等式来节省处理器时间:

distance(vector1, vector2) < distance(vector1, vector3)

我看到这vector1两种情况都是重复的。


10
简要说明一下:您当前的方法可读性强,可以立即理解其功能。其中一些答案可能会完成您所请求的任务,但是不清楚。如果性能至关重要,那么可以,但是请确保对其进行适当注释以弥补清晰度的损失。
MikeS

3
要继续@MikeS的评论,仅在这种情况下(如果您已经进行了分析或配置文件并且已将此调用确定为瓶颈),性能才是至关重要的。如果我们谈论的是305fps和303fps之间的差异,那么可维护性将击败原始性能。
Phoshi

Answers:


24

是的,您可以简化此过程。首先,停止称它们为向量。他们是要点。让我们给他们打电话ABC

因此,您需要这样做:

dist(A, B) < dist(A, C)

替换的距离的距离的平方,然后用点积(从定义欧几里德长度替换。ACAB + BC(现在这些都是真实的载体)展开,简化因子:

dist(A, B < dist(A, C
dot(AB, AB) < dot(AC, AC)
dot(AB, AB) < dot(AB + BC, AB + BC)
dot(AB, AB) < dot(AB, AB) + dot(BC, BC) + 2 dot(AB, BC)
0 < dot(BC, BC) + 2 dot(AB, BC)
0 < dot(BC + 2 AB, BC)

你在这:

dot(AB + AC, BC) > 0

使用您的矢量符号:

dot(v2 - v1 + v3 - v1, v3 - v2) > 0

这是几个添加项和一个点产品,而不是之前的两个点产品。


您能解释一下如何用点积产品替换a + b b = a a + c c吗?
TravisG

2
@TravisG我不确定您要问什么。如果您的问题与为什么dist(A, B)²相同dot(AB, AB),那么它来自欧几里得长度的确切定义。
sam hocevar

2
显然,这确实(在某种程度上)在数学上简化了等式,但不一定为OP“节省处理器时间”。与仅从原始距离方程中删除平方根相比,这导致更多的复杂性和更多的计算。
MichaelHouse

1
如果我错了,请纠正我,但两个点积是每个点积5个运算加上两个vec3减法,总共16个运算,您的方式有3个vec3减法加上一个加法,该加法运算使12个运算加上点积使得17
路易斯·w ^

2
有趣的是,结果是平行四边形的两个相对对角线的点积。但这无关紧要。我想说的是,通过这种完全简化并不会获得太多收益。正如其他人提到的那样,它会使混淆或复杂化您实际上要计算的内容确实相当不错。但是,您肯定要使用第一步。避免不必要的平方根总是值得的。只是比较距离的平方是一样的,因为即使在复杂平面上,距离也是正定的。
TASagent

16

是。假设distance函数使用平方根,则可以通过删除平方根来简化此过程。

尝试查找较大(或更小)的距离时,x^2 > y^2仍然成立x > y

但是,进一步简化数学公式的尝试可能毫无意义。之间的距离vector1vector2是不一样的距离vector1vector3。虽然方程可以如Sam的答案所示那样在数学上进行简化,但是从处理器使用的角度来看,当前方程的形式可能很简单。


我没有足够的代表,但我认为这从根本上是不正确的,我相信:“我可以通过简化这种不平等来节省处理器时间吗?” 答案是肯定的。
我很困惑

如果距离方程使用平方根,则答案是肯定的。我提到。
MichaelHouse

有意思的是,我撤回了声明。但是,有99%的保证用户表示欧几里德距离sqrt(sum(维数平方的平方))
非常困惑

@imsoconfused很公平,我已经更改了答案的顺序,以首先说明最有可能(99%)的情况。
MichaelHouse

2
是的,我的经验是,当您处理此类事情时,DistanceSquared函数非常有用。同样清楚,并且避免了昂贵的sqrt操作。
罗伦·佩希特尔

0

一些数学可能会有所帮助。

您正在尝试做的是:

<v1, v2> < <v1, v3> =>
sqrt((y2-y1)^2+(x2-x1)^2) < sqrt((y3-y1)^2+(x3-x1)^2) =>
y2^2 - 2*y2y1 + y1^2 + x2^2 - 2*x2x1 + x1^2 < y3^2 - 2*y3y1 + y1^2 + x3^2 - 2*x3x1 + x1^2

您可以从中删除重复的变量,并对其他变量进行分组。您必须检查的操作是:

y3^2 - y2^2 - 2*y1(y3-y2) + x3^2 - x2^2 - 2*x1(x3-x2) > 0

希望能帮助到你。


-1

真正的问题似乎是如何减少确定最近物体的计算量?

优化这往往是在做游戏,虽然所有的优化应该是档案导引,并经常不简化的东西。

避免不必要的距离计算来确定最近的物体或某个范围内的所有物体的方法是使用空间索引,例如八叉树

这只有在存在大量对象的情况下才有回报。对于仅三个对象,不太可能得到回报,当然也不能简化代码。


4
我认为实际问题相当简单,这个答案并不能解决这个问题。如果您想推测OP的更深层次,未陈述的问题,并且如果您不打算真正回答所提出的问题,则应将其作为评论来完成。

我之所以反对这一点,是因为调用可能的过早优化并不是解决以下问题的答案:显式优化既不会损害可读性,代码可维护性,也不会鼓励晦涩的实践。当您实际上可以编写简单且经过优化的代码时,为什么不这样做呢?即使您有更高级别的计划,这样做也绝对不会造成伤害(任何游戏开发人员都不会拒绝每帧多出几微秒的时间,尤其是在控制台上)。
teodron

@teodron:“当您实际上可以编写简单且经过优化的代码时,为什么不这样做呢?” -因为OP (现在是我们)现在花费了不可忽略的时间来优化某些东西,因此可能不会给他带来任何好处。
BlueRaja-Danny Pflughoeft13年

@ BlueRaja-DannyPflughoeft我同意这是次要的(因此,如果每帧用于数百次调用,那么微不足道的优化,但是如果幅度因数增加到数千,则情况肯定会改变)。但是,我们都可以不浪费时间来尝试回答/优化我们认为不可行的事情。OP要求做一件事,人们认为OP不了解更高级别的策略和配置方法。我个人更喜欢在评论中而不是在答复中这样说。对不起,如此冗长:(。
teodron

-3

这取决于distance(v1,v2)的输出是什么

如果它是向量的小数点(浮点数或双精度数),则distancesquared可能会更快


5
我不知道这float与任何事情有什么关系。
MichaelHouse

我的意思是在另一个向量上浮动,但解释得不是特别好(我想你知道)
RoughPlace 2013年

5
我不是故意误会。我仍然不确定你的意思。我不知道为什么距离函数会返回一个向量。
MichaelHouse
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.