2017-03-17 7 views
0

ポイントが同じ行にあるかどうかをチェックする方法を試しています。線が斜めであれば動作するように見えますが、縦または横にまっすぐには失敗します。ポイントがライン上の2つの他のポイントの間にあるかどうかを確認する

これは私の方法である:

public bool isBetween(Vector3 C, Vector3 A, Vector3 B) 
{ 
    Vector3 sum = Vector3.Cross(A,B) + Vector3.Cross(A,C) + Vector3.Cross(B,C); 

    if (sum.x == 0 && sum.z == 0 && sum.y == 0) 
    { 
     Vector3 min = Vector3.Min(A, B); 
     Vector3 max = Vector3.Max(A, B); 

     // only checking 2 dimensions 
     if (C.x > min.x && C.x < max.x && C.z > min.z && C.z < max.z) 
     { 
      return true; 
     } 
    } 
    return false; 
} 

それはすべてのケースのために、100%、特定の場合のために動作しますが、ありません。それが動作するように修正する方法がわからない。

+0

どのような場合に適していますか?どのような場合にはうまくいかないのですか? – gdc

答えて

2

point1とpoint2が異なると仮定すると、最初にポイントがライン上にあるかどうかをチェックします。そのためには、単にベクトルpoint1 - > currPointとpoint1 - > point2の "積集合"が必要です。

dxc = currPoint.x - point1.x; 
dyc = currPoint.y - point1.y; 

dxl = point2.x - point1.x; 
dyl = point2.y - point1.y; 

cross = dxc * dyl - dyc * dxl; 

十字がゼロに等しい場合にのみ、あなたのポイントはライン上にあります。

if (cross != 0) 
return false; 

ここでポイントがライン上にあることがわかっているので、それは元のポイント間にあるかどうかを確認するときです。入力データは、それすなわち、積分完全一体である場合ならば、これは容易に上記のアルゴリズムこと線は「垂直よりも水平」である場合、X座標を比較することによって行われ、またはYは、さもなければ

if (abs(dxl) >= abs(dyl)) 
return dxl > 0 ? 
    point1.x <= currPoint.x && currPoint.x <= point2.x : 
    point2.x <= currPoint.x && currPoint.x <= point1.x; 
else 
return dyl > 0 ? 
    point1.y <= currPoint.y && currPoint.y <= point2.y : 
    point2.y <= currPoint.y && currPoint.y <= point1.y; 

座標注することができます整数入力に対して浮動小数点演算を必要としません。クロスを計算すると潜在的なオーバーフローに注意してください。

P.S.このアルゴリズムは絶対的に正確です。つまり、直線に非常に近く、正確に直線上にない点は拒否されます。時にはこれは必要なものではありません。しかしそれは別の話です。

+0

私はあなたの例を試してみましょう。私はもともと、ここで似たようなものを試しました:http://pastebin.com/xhCPaeSGしかし、それは動作しませんでした。 – Sir

+0

サイドノート:回答をhttp://stackoverflow.com/questions/7050186/find-if-point-lays-on-line-segmentに移動したい場合があります。 –

+0

これらの回答の半分はC#でも計算距離でもありません。私はペーストビンに書いたものを公式化するためにその回答ページを使っていましたが、それは機能しませんでした。 – Sir

関連する問題