6

V1、V2、V3 の 3 つのベクトルがあります。それらの原点は軸の原点にあります。V1 から V2 まで反時計回りに移動したときに、V3 が V1 と V2 の間にあるかどうかを判断するにはどうすればよいですか?

代替テキスト http://www.freeimagehosting.net/uploads/1448ea8896.jpg

それらの角度を取得し、これらの種類の条件を評価することでは実行できません (疑似コード):

if angle(V3) > angle(V1) && angle(V3) < angle(V2) 
   printf("V3 is between V1 and V2") 
else 
   printf("out of the interval")

その欠陥を確認するために、angle関数が [-pi pi] の範囲の角度を与えると仮定します。したがって、角度(V1) = 120 (度単位)、角度(V2) = -130、および角度(V3) = 150 の場合、(上記のコードによると) 答えは「間隔外」ですが、動き回るとV1 から V2 まで反時計回りに、それらの間にあります。

angle(V2) などに 2*pi を追加することをお勧めするかもしれませんが、私はそのようなことを試しましたが、うまくいきません。

私はMATLABでプログラミングしています。

編集1:2Dです。

4

5 に答える 5

8

これは MATLAB で行っているため、次の 1 つの解決策が有効です。

crossProds = [V1(1)*V2(2)-V1(2)*V2(1) ...
              V1(1)*V3(2)-V1(2)*V3(1) ...
              V3(1)*V2(2)-V3(2)*V2(1)];
if (all(crossProds >= 0) || ...
    (crossProds(1) < 0) && ~all(crossProds(2:3) < 0)),
  disp("V3 is between V1 and V2");
else
  disp("out of the interval");
end

説明:

2 次元ベクトルV1V2の間の外積は、 crossProdsの最初の要素に格納されます。V1V2の間の反時計回りの角度が 0 度から 180 度の間である場合、この値は 0 以上になります。この場合、V3が反時計回り方向でV1V2の間にある場合、外積(V1,V3)(V3,V2)もゼロ以上になります。これは、最初の論理チェックを説明しています。

all(crossProds >= 0)

V1V2の間の反時計回りの角度が 180 度より大きい場合、これら 2 つのベクトルの外積はゼロ未満になります。この場合、V3が時計回り方向でV1V2の間にある場合、外積(V1,V3)(V3,V2)もゼロより小さくなります。したがって、これらの外積が両方とも 0 未満でない場合、V3反時計回り方向でV1V2の間にある必要があります。これにより、次の 2 つの論理チェックが説明されます。

(crossProds(1) < 0) && ~all(crossProds(2:3) < 0)

上記の論理チェックは、考えられるすべての状況をカバーする必要があります。演算子 || および && はMATLABの短絡演算子です。2 番目のステートメントが必要ない場合はスキップされます。たとえば、OR の最初のステートメントが true の場合、結果が true になるためには OR の 1 つの引数のみが true である必要があるため、2 番目のステートメントをチェックする必要はありません。

于 2009-03-29T01:51:26.190 に答える
3

角度 (V1)、角度 (V2)、および角度 (v3) (a1、a2、a3) を計算します。

a2 と a3 を変更して (必要に応じて 2*pi を追加)、次のようにします。

a1 <= a2 < a1 + 2*pi
a1 <= a3 < a1 + 2*pi

ここで、a2 と a3 を比較するだけです。V3 は V1 と V2 の間にあるため、a3 は a2 よりも劣っています。

于 2009-03-29T00:01:27.780 に答える
2

V1は赤いニシンです。一度に 3 つの角度について考えると、混乱するだけです。

  1. すべてを時計回りに角度だけ回転させる(V1)
  2. 残りの 2 つの角度を [0,360) に正規化します。

問題は単純に、ノルム (角度 (V2)-角度 (V1)) とノルム (角度 (V3) - 角度 (V1)) を比較することです。

于 2009-03-29T02:59:21.097 に答える
0

他のほとんどのプログラミング言語では、やや簡単な方法です。

V1、V2、V3 にベクトルが与えられ、天気 V3 が V1 と V2 の間にあり、Ri = atan2(Vi) (-pi から pi までの角度をラジアンで返す) を決定する必要がある場合:

時計回り

R1 -= R3;
R2 -= R3;

if (R1 < 0) R1 += 2 * PI;
if (R2 <= 0) R2 += 2 * PI;

return (r1 < r2);

反時計回りの場合は、R1 と R2 を交換するだけです。

于 2014-12-06T13:47:21.210 に答える
-2

この条件をテストするには、2 つの三角形の巻きを計算する必要があります。

  1. V1、原点、および V3 によって形成される三角形。この三角形は反時計回りでなければなりません。

  2. V3、原点、および V2 によって形成される三角形。この三角形も反時計回りでなければなりません。

三角形の曲がりをテストするには、頂点の 2D 外積の符号を確認するだけで十分です。

テストは次のようになります (申し訳ありません - C コード):

int IsBetween (vector v1, vector v2, vector v3)
{
  float winding1 = (v1.x * v3.y - v1.y * v3.x);
  float winding2 = (v3.x * v2.y - v3.y * v2.x);

  // this test could be exactly the wrong way around. This depends
  // on how you define your coordinate system (e.g. is Y going up or down?)

  if ((winding1 <0) && (winding2 < 0))
  {
    printf ("V3 is between them\n");
  }
  else
  {
    printf ("it's not\n");
  }
}
于 2009-03-29T00:55:22.703 に答える