MATLAB関数を使用して、点と曲線の間の最小の長さを見つけたいですか?曲線は、非常に滑らかではない複雑な関数によって記述されます。したがって、これを計算するためにmatlabの既存のツールを使用したいと思います。たまたま知っていますか?
2 に答える
誰かが「それは複雑だ」と言うとき、私はあなたが何を持っているのか正確にはわからないので、答えも常に複雑です。それで、私はいくつかの基本的な考えを説明します。
曲線が既知の非線形関数である場合は、最初にシンボリックツールボックスを使用します。たとえば、関数y = x ^ 3-3 * x + 5を考え、x、y平面の点(x0、y0)=(4,3)を考えます。
距離の2乗を書き留めます。ユークリッド距離は書きやすいです。
(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
距離の2乗の最小値はどれですか?
subs(P,r(1))
ans =
35.5086
subs(P,r(2))
ans =
42.0327
subs(P,r(3))
ans =
6.9875
これは距離の2乗であり、ここではリストの最後のルートによって最小化されています。xの最小位置を考えると、もちろん、y(x)= x ^ 3-3 * x+5の式に代入することでyを見つけることができます。
subs('x^3-3*x+5',r(3))
ans =
3.7419
したがって、曲線を上記のように単純な関数形式で記述できれば、かなり簡単です。平面内の一連のポイントからのみ認識される曲線の場合、distance2curveユーティリティを使用できます。与えられた点に最も近いn次元の空間曲線スプライン補間上の点を見つけることができます。
他の曲線、たとえば楕円の場合、解は極座標に変換することでおそらく最も簡単に解かれます。この場合、楕円は極角の関数としてパラメトリック形式で簡単に記述されます。それが終わったら、前と同じように距離を書き、導関数の根を解きます。
解決するのが難しいケースは、関数が非常にスムーズではないと説明されている場合です。このノイズですか、それとも微分不可能な曲線ですか?たとえば、3次スプラインはあるレベルでは「あまり滑らかではありません」。区分的線形関数は、ブレークでさらに滑らかではありません。実際に、ノイズが少し含まれているデータポイントのセットがある場合は、ノイズを平滑化するかどうかを決定する必要があります。基本的に、平滑化された近似で最も近い点を見つけたいですか、それとも補間された曲線で最も近い点を探していますか?
データポイントのリストについて、平滑化を行わないことが目標である場合は、線形補間を使用した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);