2011-06-05 18 views
0

一條線由兩個端點P1 [x1,y1],P2 [x2,y2]定義。設Q [xq,yq]是一個測試點。兩個座標都是雙倍的。C++,2D中的點和線位置對於舍入誤差和位置穩健

Differencies:

dx1 = x2 - x1 
dy1 = y2 - y1 
dx2 = xq - x1 
dy2 = yq - y1 

規範

double n1_sq = sqrt(dx1 * dx1 + dy1 * dy1); 
double n2_sq = sqrt(dx2 * dx2 + dy2 * dy2); 

我的假設:與歸一化矢量的測試是較不敏感的舍入誤差

double test = (dx1/n1_sq ) * (dy2/n2_sq) - (dx2/n2_sq) * (dy1/n1_sq); 

double test = dx1 * dy2 - dx2 * dy1; 

問題出現在以下情況下:

A)測試點是Q爲上線

Q = [0.5(x1 + x2), 0.5(y1 + y2)] 

在許多情況下,結果是不爲零,但

test >> 0 

B)線路/測試點的配置不合適

案例1)長段:

讓我們移動測試點到開始點,DIST(Q,| P1,P2 |)= 7E-4

P1 = [0, 0] 
P2 = [1000000000.00001, 1000000000.00001] 
Q = [0.0,0.001] 

歸一化測試:0.7 非標準化測試:1.0E + 6

情況2)長的段:

讓我們移動測試點到終點DIST(Q,| P1,P2 |)= 7E-4

P1 = [0, 0] 
P2 = [1000000000.00001, 1000000000.00001] 
Q = [1000000000.0, 1000000000.001] 

歸一化測試:5.0E-13 非標準化testt:1.1 E + 6

情況3)短鏈段:

讓我們移動測試點到開始點,DIST(Q ,| P1,P2 |)= 7E-4

P1 = [0, 0] 
P2 = [0.00001, 0.00001] 
Q = [0.0,0.001] 

歸一化測試:0.7 非標準化測試:1.0E-8

結果:

A)長段標準化測試不太可靠。案例2可以被視爲機器零點,具有以下決定:Q在| p1,p2 | ...

B)對於短片段,情況相反,非標準化測試給出機器零點。

但是兩個測試的結果都不是恆定的,結果值不會提供關於點Q到行| p1,p2 |的實際距離的任何信息。在兩次測試中使用閾值都不會帶來正確的結果...並且閾值的值不能在之前確定。

我該怎麼辦?

我的解決方案是用新測試代替兩個測試:測試點Q和線P1,P2的距離並使用某個閾值eps。與

dist (Q,|P1,P2|) < eps, (for example 1e-10) 

點Q將被放置上線P1,P2,...,測試的結果並不取決於點的配置(即,如果我們沿着移動區段P1測試點Q,P2)

是否有人使用更好的測試或有不同的解決方案?

回答

0

我不明白你的測試。它似乎沒有涉及到Q的座標。此外,對於uv這兩個值,範數的最小舍入計算爲M * sqrt(1 + m/M),其中M = max(|u|, |v|)m = min(|u|, |v|)。至於dist函數,這是最好的方法,但您可能想要使閾值成爲線段長度的函數。這真的取決於你的應用程序。

0

您正在使用楔形產品(在2D中是行列式)來查找距離。我想問題是,你可能會減去類似的數量,以便你的結果被截斷錯誤所克服。嘗試使用點積代替。 d = d1.d2/| d1 |。