首先,兩個幾何對象A和B之間的距離是多少?它是A和B上任意兩點之間的最小距離,即。 dist(A,B) = min { EuclideanLength(x - y) | x in A, y in B}
。 (如果它存在並且是唯一的,它在你的情況下就是這樣)。
這裏你已經知道了EuclideanLength((x,y,z)) = sqrt(x^2 + y^2 + z^2)
。由於sqrt
嚴格增加,所以最大限度地減少SquareEuclideanLength((x,y,z)) = x^2 + y^2 + z^2
,這大大簡化了問題。
在你的問題中,對象是一條線段A := {v1 + t*(v2-v1) | 0 <= t <= 1}
和一條線B := {p + s*d | s is any real number}
。 (別擔心,你問一個光線,一條線是你真正想要的東西。)
現在,計算距離歸結爲尋找合適的t
和s
,從而SquareEuclideanLength(v1 + t*(v2-v1) - p - s*d)
是最小的,然後計算EuclideanLength(v1 + t*(v2-v1) - p - s*d)
得到真正的距離。
要解決這個問題,我們需要一些解析幾何。因爲d
不爲零,所以我們可以將每個矢量v
寫爲與d
正交的部分和d
:的倍數的部分的和。對於這樣的「正交分解」,它始終保持爲SquareEuclideanLength(v) = SquareEuclideanLength(Ov) + SquareEuclideanLength(Mv)
。
由於
d = Md
在上述
SquareEuclideanLength(v1 + t*(v2-v1) - p - s*d) = SquareEuclideanLength(Ov1 + t*(Ov2-Ov1) - Op) + SquareEuclideanLength(Mv1 + t*(Mv2-Mv1) - Mp - s*d)
左加數不依賴於s
並且按照自己的選擇t
你可以找到一個s
使得右加數爲0! (請記住,Mv1
,Mv2
...是d
數倍。)
因此找到你只需要找到這樣的地圖O
,如上M
,找到極小t
最小。
假設d
是標準化的,這實際上是由Ov := CrossProduct(v, d)
和Mv := DotProduct(v, d)*d
給出,只是相信我,這也適用,如果d
不歸。
所以尋找遠處的食譜是現在:找到0 <= t <= 1
,最大限度地減少
SquareEuclideanLength(Cross(v1 - p, d) + t*Cross(v2 - v1, d)) = SquareEuclideanLength(Cross(v1 - p, d)) + 2*t*Dot(Cross(v1 - p, d), Cross(v2 - v1, d)) + t^2 SquareEuclideanLength(Cross(v2 - v1, d))
。
你就已經知道從點線距離計算這個公式(這就是它是什麼),它是由相對於分化爲t
和等於0
解決,使這個方程的極小是 t = -Dot(Cross(v1 - p, d), Cross(v2 - v1, d))/SquareEuclideanLength(Cross(v2 - v1, d))
使用此t
,您可以計算v1 + t*(v2 - v1)
,線段A上距離線B最近的點,並且可以將其插入到點線距離算法中以查找追求的距離。
我希望這可以幫助你!
確定您的拾取點是否在邊緣的可接受「半徑」內 - 使用與線公式的距離。然後對邊緣進行正交投影,以便在必要時在邊緣產生「點」。 –
@Brett Hale你說'使用距離線公式'。其實我被困在這一點上。實際上我還沒有能夠實現Ray-Line相交。如果您將其作爲答案發布並提供更多詳細信息,則會更有幫助。感謝您的寶貴意見:) –
啊...其實我仍然卡住:(需要幫助...請。 –