我想优化其中一个算法,我会尝试以最好的方式解释它。
我们在 t = 0 时处于2D欧几里德系统中。 在这个系统中有两个对象: O1 和 O2 。
O1 和 O2 分别位于 PA 和 PC 点。
O1 在 PB 点的方向上以恒定且已知的速度移动。当物体到达PB时,物体将停止。
O2 可以在任何方向上以恒定且已知速度不同或不的O1移动。在0时,O2有没有方向,我们需要为它找到一个。
知识参数:
这是系统的一个小图。
我们希望找到 PI 点和时间 ti :Position of O1 at the time ti = Position of O2 at the time ti = PI
。然后我们将对象O2移动到PI点以获得 O2方向。
当选择O2的方向(点PI)且移动的物体O1和O2时,对象将永远不会停止或等待。
在这种情况下,结果将是这样的(PI在此图片上标注为D)。
你可以在jsfiddle找到用JS编写的工作算法,这也是理解这个问题的好方法。
此时我使用一个简单的算法,但是可以进行大量的操作,我会获得最佳的交叉时间,然后获得交叉位置。
为了得到这个时间,我会立刻检查O1的位置,并检查此时O2是否可能到达此位置。如果O2无法及时到达目标,我们会将时间增加150%,但如果O2当时可以越过O1-B线,我们将把时间缩短50%。
最终,经过多次近似,我们将找到两个物体相遇的最佳时间。
伪代码
function getOptimalIntersectionTime time
if distance between O1 and O2 at the time `time` < 1
return time
else if O2 could not reach the object O1 at the time `time`
return getOptimalIntersectionTime time * 1.5
else
return getOptimalIntersectionTime time * 0.5
我的算法有效,但在某些情况下(例如jsFiddle中的“反向案例”),需要大量的微积分才能找到最佳点。
在这个jsFiddle中,我们使用的是位置(-1000到1000)和速度(1-200)的小值,但是这个算法在数字越大时就越慢。
我知道过早优化是一个坏主意,但我在项目的最后(包括数据库插入/选择和数据分析,包括这个算法多次调用),这个算法最多需要80在某些情况下,项目系统的百分比会重新获得资源,因此改进可以真正提高系统的稳定性和响应能力。
答案 0 :(得分:9)
不失一般性,让O2位于(0,0)。
让s
和v
为O1的位置和速度向量,v2
为O2的速度,t为拦截时间。然后我们有:
|s + v * t| = t * v2
根据距离的定义:
(sx + vx * t) ^ 2 + (sy + vy * t) ^ 2 = (t * v2) ^ 2
将此乘以及重新排序的术语给出:
sx^ 2 + 2 * sx * vx * t + vx^2 * t^2
+ sy^ 2 + 2 * sy * vy * t + vy^2 * t^2
- v2^2 * t^2
= 0
即
sx^2 + sy^2 + (2 * sx * vx + 2 * sy * vy) * t + (vx^2 + vy^2 - v2^2) * t^2 = 0
\--- ---/ \------------ ----------/ \-------- ------/
\ / \ / \ /
c b a
如您所见,这是t中的二次方程。我们可以简单地应用quadratic formula来找到t
的两个可能值(如果等式没有解,那是因为没有拦截是可能的)。您可能希望使用最早的未来拦截,即较小的t>&gt; 0.
一旦你计算了t
,就找到拦截点,并且截取方向应该很容易。
总而言之,这个问题可以在恒定时间内解决,不需要迭代。
答案 1 :(得分:1)
你似乎过分思考问题,它应该只是简单的几何。
不考虑如何定义最近点的问题,让我们解决所需点位于PA
和PB
之间的情况。
我们必须假设整个周期的时间段,我们称之为T
。
PI = (PB - PA) / 2; // simplified
TI = T / 2; // simplified
[分别分解x和y坐标的所有公式]。
确定点(PC)与线(PA - > PB)的最近交点有相对简单的公式,但是当该线不是无限长时,它的定义是如何复杂的。
然后你需要:
V1 = (PB - PA) / T; // O1's velocity
V2 = (PI - PC) / T; // O2's velocity
最后两行不依赖于先前的假设 - 如果你知道截取点,那么速度就是行进的距离除以所花费的时间。
因此,除非你对V2施加一些额外的约束,否则总是一个解决方案,并且它是在几个简单的数学运算中计算的。
答案 2 :(得分:1)
更新:@Meriton后来的回答比我好。我建议尝试他的第一个。
如你所知,我们在三个未知数vx2,vy2和t中分别有三个联立方程 - 分别是02和x的y和y速度。遗憾的是,这些方程式并非都是线性的:
x1o + vx1*t == x2o + vx2*t
y1o + vy1*t == y2o + vy2*t
vx2*vx2 + vy2*vy2 == vy*vy
(这里,x1o,y1o,x2o和y2o是初始位置的坐标。)
如果有办法线性化问题,我看不到它。然而,您可以通过相同的Newton-Raphson technique GPS使用来迭代地快速解决,从而根据卫星信号计算您的位置。当然,要填写细节并实施这将需要一些工作!
更新:我认为 @Alnitak可能已经相当整齐地线性化了您的问题。也许他的方法和我的方法的组合因此会繁荣。 (我仍然认为你会想要使用Newton-Raphson迭代来收敛@ Altinak的T
。)
答案 3 :(得分:0)
由于速度是固定的,这应该可以使用并行导航的思想来解决。这样想吧。在时间0,在O1和O2之间存在一条线(LOS或视线)。如果O2遵循最佳交叉路径,则在时间1,O1和O2之间的线将与时间0 LOS平行。由于您具有O2的速度,您可以计算它在时间0和时间1之间行进的距离,并且可以计算它与时间1 LOS相交的位置。想想在O2的原始位置周围划一圈,其半径等于它在该时间间隔内行进的距离。该圆与第二个LOS的交叉点将包含解决方案。如果没有相交,则没有解决方案。这本在线书的开头有一个图表和公式,显示了这个概念:
http://www.crcnetbase.com/doi/abs/10.1201/9781420062281.ch2
此问题具有真实世界的应用程序,您可能也会发现此解决方案。例如,潜艇可以使用它来绘制并保持与目标的拦截航线,方法是在目标靠近目标时保持目标的LOS方向不变。
编辑:
此图显示了我在说什么。这可以使用三角函数来解决,除了目标O1直接朝向或远离导弹O2移动的特殊情况(可以通过简单的方法解决)。
在上图中,我们可以花费一些任意的时间。在那个时间t1期间,O1将具有行进距离b,并且O2将具有行进距离f。在时间t0,O1和O2之间的线与在时间t1的O1和O2之间的线平行。由于我们给出了O1和O2的初始位置,我们知道距离d,因为我们得到了O1的方向,我们可以简单地计算角度A.
So given A, b, f, and d, using the law of Cosines,
a = sqrroot(c^2 + b^2 - (2cb * cos(A)))
and
B = arccos((a^2 + c^2 - b^2)/2ac)
Using the law of Sines
E = arcsin((a * sin(B))/f) or the ambiguous value of 180 - that value
and with that
BC = 180 - E (because C = 180 - B - E so C+B = 180 - E
对于BC,我们有解,并且可以类似地计算O1和O2的初始位置的三角形的任何其他方面和交点。
自从我使用高中三年以来已经很多年了,所以我可能会错过这个简化,但这有希望解释我最初描述的解决方法。