[英]Find the better intersection of two moving objects
我想優化我的算法之一,我將嘗試以最佳方式解釋它。
我們在t = 0時處於2D歐幾里得系統中。 在這個系統中有兩個對象: O1和O2 。
O1和O2分別位於PA和PC點。
O1以點PB的方向以恆定且已知的速度移動。 當物體到達PB時,物體將停止。
O2可以在任何方向上以不同或不同的O1的恆定和已知速度移動。 在時間0,O2 沒有方向 ,我們需要為它找到一個。
知識參數:
這是系統的一個小圖。
我們希望找到點P1和時間ti ,其中: Position of O1 at the time ti = Position of O2 at the time ti = PI
。 然后我們將使對象O2移動到點P1以獲得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%的項目系統在某些情況下需要資源,因此改進可以真正提高系統的穩定性和響應性。
不失一般性,讓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中的二次方程。 我們可以簡單地應用二次公式來找到t
的兩個可能值(如果方程沒有解,那是因為沒有攔截是可能的)。 您可能希望使用最早的未來攔截,即較小的t> 0。
一旦你計算了t
,找到攔截點,從那里攔截方向應該很容易。
總而言之,這個問題可以在恆定的時間內解決,不需要迭代。
你似乎過分思考問題,它應該只是簡單的幾何。
撇開如何定義最近點的問題 ,讓我們解決所需點位於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施加一些額外的約束,否則總有一個解決方案,並且它是在一些簡單的數學運算中計算出來的。
更新:@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技術迭代地快速解決,GPS用於從衛星信號中計算您的位置。 當然,要填寫細節並實施這將需要一些工作!
更新:我認為 @Alnitak可能會將您的問題線性化,而不是整齊。 也許他的方法和我的方法的組合因此會繁榮。 (我仍然認為你會想要使用Newton-Raphson迭代來收斂@ Altinak的T
)
由於速度是固定的,這應該可以使用並行導航的思想來解決。 這樣想吧。 在時間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的初始位置的三角形的任何其他方面和交點。 自從我使用高中三年以來已經很多年了,所以我可能會錯過這個簡化,但這有希望解釋我最初描述的解決方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.