0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Vector2から求めた角度で、プレイヤーを回転させる - C++

Posted at

少し苦戦したのでメモ書き。
c++20です。

やり方

1フレーム前と現在フレームの入力ベクトルを比較し、  
プレイヤーの向きがどの程度変わったのかを算出します。

#include <cmath>
#include <numbers>

// 2次元ベクトル構造体
struct Vector2
{    
    float x;
    float y;

    // 内積
    float Dot(const Vector2& arg_v)
    {
        return x * v.x + y * v.y;
    }
}

int main(void)
{
    // 1フレーム前の入力ベクトル
    Vector2 input_old{};
    // 現在フレームの入力ベクトル
    Vector2 input_current{};

    while(GetIsTrigger(DIK_R) != true)
    {
        // 入力ベクトルの取得(正規化済み)
        input_current = GetInput();

        // 現在の入力ベクトルと、1フレーム前の入力ベクトルとの内積値
        const float dot = input_current.Dot(input_old);
        // 内積値からラジアンを取得
        const float radian_temp = std::acosf(dot);

        // プレイヤーを回転させるのに使用するラジアン
        float radian_rotate = radian_temp;

        if(input_current.x < 0)
        {
            const float pi = std::numbers::pi;
            // 180度 + 180度超えていた差分
            radian_rotate = pi + (pi - radian_temp); 
        }

        // プレイヤーを回転させる
        player.rotate = radian_rotate;

        input_old = input_current;
    }

    return 0;
}

解説

苦戦したのは、std::acosで算出されるラジアンの範囲が、0~πまでしかない点。
入力ベクトルが { 0, -1 } の時、算出されるラジアンは最大値のπとなり、
それより値が大きくなることはない。(本当は2πまでは大きくなり続けてほしい。)
  

なので、入力ベクトルのx成分が 0 より小さくなった時のラジアンが、
2πまで大きくなるようにした。

簡単な図説vec_deteil.png

radian_rotate(input_old から input_current までの 角度)の算出
radian_rotate = π + (π - radian_temp);

最後に

※GetInput()は入力を取得する関数です。
何か間違い等あれば指摘をお願いします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?