DirectX
相手が右にいるのか左にいるのかを判断する


HomeProgramming TipsDirectX Tips [DX8-002]

 ダウンロード : 左右判定サンプル(2005/03/21) 

相手が右にいるのか左にいるのかを判断する方法は、DicretX の内積を用いると簡単に実現できます。
D3DXVec2Dot() とするだけで角度が求まります。

簡単に言うと法線がプラスかマイナスかで左右の向きを判定してします。
そのため、本来の方向から 90度回転させてから判定しています。
90度回転の行列は毎回計算する必要はありませんので、初期化のタイミングで一度作ってしまえば OK です。


    D3DXMATRIX  mtxRot90;    // メンバ変数で宣言する
    D3DXMatrixRotationZ(&mtxRot90, D3DXToRadian(90));


自分の座標を vec2Player、相手の座標を vec2Target とします。
自分の進行方向は vec2Direction とします。 座標系を自分中心とするため、相手の座標から自分の座標を引きます。
これで相手の座標は自分のローカル座標内にいることになります。

相手の位置を90度回転させるには D3DXVec2TransformCoord() 関数を使います。
これはベクトル×行列の関数であり、結果はベクトルで返ります。
その結果得られた新しいベクトルと相手の位置(ベクトル)の内積を取ります。
計算する値が単位ベクトルでないため得られた結果にあまり意味はなく、符号だけに重要な意味があります。


    D3DXVECTOR2 vec2Temp;
    D3DXVECTOR2 vec2Local = vec2Target - vec2Player;    // ローカル座標を計算する
    FLOAT fAngle = D3DXVec2Dot(                         // 内積を得る
        D3DXVec2TransformCoord(&vec2Temp, &vec2Direction, &mtxRot90),
        &vec2Local
    );


さて、この結果得られた値がゼロならば、
自分の進行方向の線上(真っ正面か真後ろ)に相手が存在することになります。
但し、FLOAT なので、その値がゼロになることはありません。

余談ですが、浮動小数点の値と 0.0f で判定するのはナンセンスです。
ゼロと見なすべき範囲を設定して、その範囲内ならばゼロとします。
下記の参考例では、10.0f としましたが、実際に試して適当な値にすればよいです。


#define RANGE_ZERO      (10.0f)     // ゼロと判断する値の範囲

    if (fAngle < +RANGE_ZERO && fAngle > -RANGE_ZERO) {

        // 相手は自分の進行ベクトルの線上にいます。

    } else if (fAngle > 0.0f) {

        // 相手は右にいます。

    } else {

        // 相手は左にいます。

    }



 Copyright 2005 VALGUS. All Rights Reserved.