12

2 つの 2D ベクトルがあるとします。1 つはオブジェクトの現在の位置用で、もう 1 つはそのオブジェクトの前の位置用です。移動の角度方向をどのように計算できますか?

この画像は、私が求めているものを理解するのに役立つかもしれません:

(画像) http://files.me.com/james.ingham/crcvmy

4

4 に答える 4

10

移動の方向ベクトルは、2 つの位置ベクトルの差になります。

d = (x1, y1) - (x, y) = (x1 - x, y1 - y)

方向角度を尋ねると、角度を測定する方向によって異なります。x軸に対してですか?Raduの答えに行きます。任意のベクトルに対して?justjeffの答えを見てください。

編集:y軸に対する角度を取得するには:

tan (theta) = (x1 -x)/(y1 - y)          

角度の正接は、差分ベクトルの x 座標と差分ベクトルの y 座標の比率です。

そう

theta = arctan[(x1 - x)/(y1 - y)]

arctan は逆正接を意味します。多くの人が行う正接の逆数と混同しないでください。どちらも tan^-1 で示されることが多いからです。また、度またはラジアンで作業しているかどうかを確認してください。

于 2010-04-03T16:11:12.367 に答える
9

C (または同じ関数セットを使用する他の言語) を使用している場合は、おそらくその関数を探しているでしょうatan2()。あなたの図から:

double theta = atan2(x1-x, y1-y);

その角度は、マークしたように垂直軸からのもので、ラジアン(神自身の角度単位) で測定されます。

于 2010-04-03T16:15:17.970 に答える
5

象限の問題とゼロ除算を回避するために、 atan2を使用するように注意してください。それがその目的です。

float getAngle(CGPoint ptA, CGPoint ptOrigin, CGPoint ptB)
{
    CGPoint A = makeVec(ptOrigin, ptA);
    CGPoint B = makeVec(ptOrigin, ptB);

    // angle with +ve x-axis, in the range (−π, π]
    float thetaA = atan2(A.x, A.y);  
    float thetaB = atan2(B.x, B.y);

    float thetaAB = thetaB - thetaA;

    // get in range (−π, π]
    while (thetaAB <= - M_PI)
        thetaAB += 2 * M_PI;

    while (thetaAB > M_PI)
        thetaAB -= 2 * M_PI;

    return thetaAB;
}

ただし、角度が+ veか-veかを気にしない場合は、内積規則を使用してください(CPU負荷が少ない)。

float dotProduct(CGPoint p1, CGPoint p2) { return p1.x * p2.x + p1.y * p2.y; }

float getAngle(CGPoint A, CGPoint O, CGPoint B)
{
    CGPoint U = makeVec(O, A);
    CGPoint V = makeVec(O, B);

    float magU = vecGetMag(U);
    float magV = vecGetMag(V);
    float magUmagV = magU * magV;   assert (ABS(magUmagV) > 0.00001);

    // U.V = |U| |V| cos t
    float cosT = dotProduct(U, V) / magUmagV;
    float theta = acos(cosT);
    return theta;
}

上記のいずれかのコードセクションで、一方(または両方)のベクトルの長さが0に近い場合、これは失敗することに注意してください。だから、どういうわけかそれをトラップしたいかもしれません。

于 2010-09-28T11:51:40.657 に答える
2

回転行列の意味はまだわかりませんが、これは方向ベクトルから方位角を取得する単純なケースです。

複雑な答え:

通常、2D ベクトルにはいくつかの変換/ユーティリティ関数をパックする必要があります。1 つは、X、Y (デカルト) から Theta、R (極座標) に変換するためのものです。また、加算、減算、内積などの基本的なベクトル演算もサポートする必要があります。この場合の答えは次のようになります。

 double azimuth  =  (P2 - P1).ToPolarCoordinate().Azimuth;

ToPolarCoordinate() と ToCarhtesianCoordinate() は、あるタイプのベクトルから別のタイプのベクトルに切り替える 2 つの相互関数です。

シンプルなもの:

 double azimuth = acos ((x2-x1)/sqrt((x2-x1) * (x2-x1) + (y2-y1) * (y2-y1));
 //then do a quadrant resolution based on the +/- sign of (y2-y1) and (x2-x1)
 if (x2-x1)>0 {
   if (y2-y1)<0 {  azimuth = Pi-azimuth; } //quadrant 2
 } else 
 { if (y2-y1)> 0 {  azimuth = 2*Pi-azimuth;} //quadrant 4
    else  { azimuth = Pi + azimuth;} //quadrant 3
 }
于 2010-04-03T16:09:11.257 に答える