1. ホーム
  2. algorithm

[解決済み] ポイントルック アット ポイント

2022-01-25 02:12:40

質問

3D空間に1点、3D空間にカメラの位置と回転があります。

つまり、基本的には Vector3 をオブジェクトに追加します。 カメラ Vector3Quaternion .

その点をどう見るか、が必要なんです。

そのポイントに移動する方法をユーザーに伝えたい。 カメラを左右どちらに向ければいいのか、それとも後ろに向ければいいのか。

どのように解決するのですか?

一つの方法として、現在カメラが向いている方向をヨー角(コンパスの方位のようなもの)として計算し、その点を見るために必要な方向を計算します。

一方を引き算して、その結果が-180度から180度(または-πからπラジアン)の範囲になるように調整し、その符号に基づいてユーザーに左折または右折を指示します。絶対値が120度(または設定可能な値)以上であれば、後ろであることを告げます。

カメラの現在の方位を知るには、ベクトル (0, 0, 1) をクォータニオンで変換して前方ベクトルを取得し、次のように方位を計算します。 atan2(forward.z, forward.x) .

その点を見るために必要な方位を計算するには、その点から現在のカメラ位置を引いて、希望する前方ベクトルを求め、atanに渡します。

Vector3 desired_forward = point - camera_pos;
float desired_heading = atan2(desired_forward.z, desired_forward.x);

次に、必要な回転を求めます。

float rotation_needed = desired_heading - heading;
if(rotation_needed > Math.PI)
    rotation_needed -= 2 * Math.PI;
if(rotation_needed < -Math.PI)
    rotation_needed += 2 * Math.PI;

ここで、必要な回転の符号に基づいて、左回転または右回転を指示します。

ルックアップ/ダウンで行う場合は、まずXZ平面上の前方ベクトルの長さを計算し、再度atan2を使うことでピッチ角を計算することができます。

float xzLength = sqrt(forward.x * forward.x + forward.z * forward.z);
float pitch_angle = atan2(forward.y, xzLength);

希望する前方ベクトルについても同様に、希望する前方ベクトルから現在を引きます。上向きか下向きかを知らせるために、符号をチェックします。

ややこしいことになりそうなことがいくつかあります。例えば、カメラクォータニオンがワールド空間からカメラ空間への変換を指定するか、その逆を指定するかによって、計算されたカメラヘディングを否定する必要があるかもしれません。