4

浮動小数点の精度が原因で、2 つの線分が同一線上にあるかどうかを判断するのに問題があります。線分が許容範囲内で同一線上にあるかどうかを判断するにはどうすればよいですか?

4

4 に答える 4

3

編集:

線分に同じ点が 2 つ含まれている場合、それらの線分は共線です。1 つのポイントを共有し、ほぼ平行である場合、それらはほぼ同一線上にあります。

ベクトル間の角度が指定したしきい値よりも小さい場合、ベクトルは事実上平行です。おそらく 0.000027 度未満であり、これは 10 分の 1 度秒に相当します (これは緯度の距離であり、赤道での経度の距離に相当します。約 10 フィートの差です。これは、民間の GPS の精度とほぼ同じです)。 )。

使用している言語またはライブラリを教えてくれませんでした。.NET の System.Windows.Media.3D ライブラリには、AngleBetween() メソッドを持つ Vector3D 構造体があり、このチェックをワンライナーにしています。

「基本的な」数学 (実際にはベクトル三角法であり、ほとんどの定義による「基本的な」概念ではありません) は、θ=cos -1 ( A*B / |A||B| ) です。つまり、2 つのベクトルのスカラー積をその大きさの積で割った量の逆余弦です。

ベクトル A とベクトル B の内積は、どちらもコンポーネント X、Y、および Z を含み、X A X B + Y A Y B + Z A Z Bです。ベクトル A の大きさは sqrt(X A 2 + Y A 2 + Z A 2 ) です。

したがって、疑似 C 風に:

//Vector is a simple immutable class or struct containing integer X, Y and Z components
public bool CloseEnough(Vector a, Vector b, decimal threshold = 0.000027m)
{
   int dotProduct = a.X*b.X + a.Y*b.Y + a.Z*b.Z;
   decimal magA = sqrt(a.X*a.X + a.Y*a.Y + a.Z*a.Z); //sub your own sqrt
   decimal magB = sqrt(b.X*b.X + b.Y*b.Y + b.Z*b.Z); //sub your own sqrt

   decimal angle = acos(dotProduct/(magA*magB)); //sub your own arc-cosine

   if(angle <= threshold
}
于 2012-04-10T22:18:30.923 に答える