Skip to main content

線型代数学

ベクトル

 ベクトルとは、一般的には「大きさと向きをもつ量」であり「矢印で表すことのできる量」である。

image.png

 2次元のベクトルは2つの成分(x, y)があり、3次元の場合は3の成分(x, y, z)がある。Unityでは Vector2Vector3 の構造体があり、それぞれのベクトルを作成ができる。

Vector2 vec2D = new Vector2(vx, vy);     // vxとvyはfloatである
Vector3 vec3D = new Vector3(vx, vy, vz); // vzもfloatである

 ゲームの中で、ベクトルをよく使うものである。例えば、3D空間で、キャラクターの速度が「左向き:秒速2メートル、前方:秒速10メートル」であるとしたら…

// 3D空間だと、x:左右、y:上下、z:前後
Vector3 velocity = new Vector3(-2, 0, 10);

 また、ゲームの場合は、向きと量はもちろんそうであるが、その他に「位置」もベクトルで表現する。

// プレーヤーはシーンの中心点から前方100メートルにいる
Vector3 playerPosition = new Vector3(0, 0, 100);

演算

 やはり、ベクトルは重要なので、ベクトルの演算を学ばないといけない。

加算

 2つのベクトルを足すことができる。その結果は各成分の足し算である:

2次元の場合

image.png

3次元の場合

image.png

Unityでは「+」の演算子で2つのベクトルを足すことができる

Vector3 v = new Vector3(vx, vy, vz); // vx, vyとvzは何かのfloat型の数値
Vector3 w = new Vector3(wx, wy, wz); // wx, wyとwzは何かのfloat型の数値
Vector3 vw = v + w;

 幾何学的に、足し算は2つの矢印を連続し、1つ目のベクトルの始点から2つ目のベクトルの終点までに新しいベクトルを作成するイメージ:

image.png

減算

 引き算は同じ形で行う:

image.png

Vector3 v = new Vector3(vx, vy, vz); // vx, vyとvzは何かのfloat型の数値
Vector3 w = new Vector3(wx, wy, wz); // wx, wyとwzは何かのfloat型の数値
Vector3 vw = v - w;

 幾何学的には、引くベクトルの向きを反転してから連続に繋がる

image.png

練習

加算と減算を使い、2つのオブジェクトを相対的に移動

  • シーンに2つの3Dゲームオブジェクトを追加し、距離的に放してください。
    • 1つ目の名前は「Control」
    • 2つ目の名前は「Follower」
  • スクリプト「VectorTest」を作成し…
    • Follower と Control の相対位置を求める(減算)
    • Control をシーン内で動かしたら、Follower が移動を真似する(加算)
スクリプト:VectorTest
// ベクトル演算の練習」
public class VectorTest : MonoBehaviour
{
    // 移動すべきのオブジェクト
    [SerializeField] private GameObject control;

    // controlを追跡するオブジェクト
    [SerializeField] private GameObject follower;

    // controlとfollowerの相対位置
    private Vector3 relativePosition;
    
    private void Start()
    {
        // 初期位置を取得
        var v = control.transform.position;
        var w = follower.transform.position;
        
        // 相対位置を計算(減算で)
        relativePosition = w - v;
    }

    private void Update()
    {
        // followerの位置が、controlの位置 + 相対位置
        follower.transform.position = 
            control.transform.position + relativePosition;
    }
}

実数との掛け算、割り算

 ベクトルを実数との掛け算ができる。各成分との掛け算になる:

image.png

Unityでは、普通の掛け算演算子「*」で計算できる:

Vector3 v = new Vector3(vx, vy, vz); // vx, vyとvzは何かのfloat型の数値
Vector3 nv = v * n;                  // nは何かの実数(float)である

練習

先ほど作った「VectorTest」を更新し、相対位置の「倍率(scale)」を Inspector で変えられるようにする。

スクリプト:VectorTest
// ベクトル演算の練習」
public class VectorTest : MonoBehaviour
{
    // 移動すべきのオブジェクト
    [SerializeField] private GameObject control;

    // controlを追跡するオブジェクト
    [SerializeField] private GameObject follower;

    // 相対位置の倍率
    [SerializeField] private float scale = 1;
    
    // controlとfollowerの相対位置
    private Vector3 relativePosition;
    
    private void Start()
    {
        // 初期位置を取得
        var v = control.transform.position;
        var w = follower.transform.position;
        
        // 相対位置を計算(減算で)
        relativePosition = w - v;
    }

    private void Update()
    {
        // 倍率を適用する
        Vector3 scalePos = relativePosition * scale;
        
        // followerの位置が、controlの位置 + 相対位置
        follower.transform.position = 
            control.transform.position + scalePos;
    }
}

ベクトルの長さ

場合により、ベクトルの長さを求めたいときもある。これには「ピタゴラスの定理」(三平方の定理)を利用する。ピタゴラスの定理を思い出しましょう。直角三角形があれば…

image.png

c 辺の長さは:

image.png

つまり…

image.png

これはベクトルの成分とよく似ているので:

image.png

これができる!

image.png

ここで || v || はベクトルの「ノルム」といわれ、ベクトルの長さを表している。Unityでは、Vectorの便利な「magnitude」がある:

Vector2 p = new Vector2(3, 4);
float len = p.magnitude; // len は p の長さ(5)である

単位ベクトル