2012-05-10 2425 views

回答

4

當有人說「其複雜的」答案總是過於複雜,因爲我從來不知道你有什麼。所以我會介紹一些基本的想法。

如果曲線是已知的非線性函數,則使用符號工具箱開始。例如,考慮函數y = x^3-3 * x + 5,以及x,y平面中的點(x0,y0)=(4,3)。

寫下距離的平方。歐幾里德距離很容易寫。

(x - x0)^2 + (y - y0)^2 = (x - 4)^2 + (x^3 - 3*x + 5 - 3)^2 

所以,在MATLAB中,我會用符號工具箱來完成這個工作。最小距離必須位於一階導數的根部。

sym x 
distpoly = (x - 4)^2 + (x^3 - 3*x + 5 - 3)^2; 
r = roots(diff(distpoly)) 
r = 
     -1.9126    
     -1.2035    
     1.4629    
     0.82664 + 0.55369i 
     0.82664 - 0.55369i 

我對複雜的根沒有興趣。

r(imag(r) ~= 0) = [] 
r = 
     -1.9126 
     -1.2035 
     1.4629 

哪一個是距離平方的最小值?

subs(P,r(1)) 
ans = 
    35.5086 

subs(P,r(2)) 
ans = 
    42.0327 

subs(P,r(3)) 
ans = 
    6.9875 

這是距離的平方,這裏最小化了列表中的最後一個根。考慮到x的最小位置,當然我們可以通過代入y(x)= x^3-3 * x + 5的表達式來找到y。

subs('x^3-3*x+5',r(3)) 
ans = 
     3.7419 

因此,如果曲線可以用上面簡單的函數形式寫出,那麼相當容易。對於僅從飛機上的一組點獲知的曲線,您可以使用我的distance2curve實用程序。它可以在n維空間曲線樣條插值上找到最接近給定點的點。

對於其他曲線,比如說一個橢圓,解決方案可能最容易通過轉換爲極座標來解決,其中橢圓很容易以參數形式寫成極角的函數。一旦完成,按照以前的方式寫出距離,然後求解導數的根。

要解決的一個難題就是函數描述不太平滑的地方。這是噪音還是非微分曲線?例如,三次樣條在某個級別上「不太平滑」。分段線性函數在休息時更不平滑。如果您實際上只是有一組數據點,其中有一些噪音,您必須決定是否消除噪音。你是否希望在平滑近似中找到最接近的點,或者你是否正在尋找插值曲線上的最近點?

有關數據點的列表,如果您的目標是不做任何平滑,那麼使用線性插值,我的distance2curve實用程序再次是一個不錯的選擇。如果你想自己做計算,如果你有足夠的數據點,那麼你可以通過簡單地選擇最接近的數據點本身來找到一個很好的近似值,但是如果你的數據不是非常接近的話,這可能是一個很差的近似值。

如果你的問題不在於這些類之一,你仍然可以使用各種方法來解決它,但我需要知道更多關於該問題的細節以獲得更多幫助。

2

有兩種方法可以解決這個問題。

最簡單的方法,如果你的曲線相當平滑,你不需要精密過高,將工作在密集的多個點來評估你的曲線,簡單地找到最小距離:

t = (0:0.1:100)'; 
minDistance = sqrt(min(sum(bxsfun(@minus, [x(t),y(t)], yourPoint).^2,2))); 

更困難的辦法是儘量減少t(或x)函數描述的距離

distance = @(t)sum((yourPoint - [x(t),y(t)]).^2); 
%# you can use the minimum distance from above as a decent starting guess 
tAtMin = fminsearch(distance,minDistance); 

minDistanceFitte = distance(tAtMin);