【Unity】Quaternionの使い方まとめ

下の記事でQuaternionについてまとめたので、
ついでにUnityでQuaternionを使う方法をまとめてみます。

light11.hatenadiary.com

作り方

Quaternionはいろんな方法で作れます。

// 回転角度と回転軸から作る
transform.rotation = Quaternion.AngleAxis(90, Vector3.forward);

// 角軸に対する回転角度を指定して作る
transform.rotation = Quaternion.Euler(0, 0, 90);

// 第一引数のベクトルを第二引数のベクトルまで回転させるためのQuaternionを作る
transform.rotation = Quaternion.FromToRotation(Vector3.up, Vector3.left);

// 無回転のQuaternionを作る
transform.rotation = Quaternion.identity;

また、Quaternionの仕組みを知っていれば成分の値を直接入れることもできます。
あまりやらないとは思いますが。

var axis = Vector3.forward;
var halfRad = 90 * Mathf.Deg2Rad * 0.5f;
var sin = Mathf.Sin(halfRad);
var cos = Mathf.Cos(halfRad);
transform.rotation = new Quaternion(axis.x * sin, axis.y * sin, axis.z * sin, cos);

回転を合成する

回転を合成するにはQuaternionの積を求めます。

var a = Quaternion.AngleAxis(90, Vector3.forward);
var b = Quaternion.AngleAxis(90, Vector3.up);
var rotation = a * b;

ベクトルを回転する

ベクトルを回転するにはQuaternionとVector3の積を求めます。

var vec = Quaternion.AngleAxis(90, Vector3.forward) * Vector3.up;

演算子としては積を計算していますが、内部的には下記の計算をしています。

 { \displaystyle
p' = qpq^{-1}
}

 { q } : Quaternion
 { p } : 回転させるベクトルにw=1を加えて4次元にしたもの
 { q^{-1} } : 共役Quaternion

逆回転にする

回転を逆にするためには、Quaternion.Inverse()を使います。

var quaternion = Quaternion.AngleAxis(90, Vector3.forward);
transform.rotation = Quaternion.Inverse(quaternion);

また、Quaternionは下記のように定義されます。

 { \displaystyle
q = \big(\vec{u} sin \big( \frac{\theta}{2} \big), cos \big( \frac{\theta}{2} \big)\big)
}

 { \vec{u} } : 回転軸
 { \theta} : 回転角度

このため、 { \vec{u} }に-1をかける、 つまり { x } { y } { z }成分に-1を掛けても逆回転のQuaternionを求められます。

var quaternion = Quaternion.AngleAxis(90, Vector3.forward);
quaternion.x *= -1;
quaternion.y *= -1;
quaternion.z *= -1;
transform.rotation = quaternion;

Quaternion間の角度を求める

Quaternion間の角度はQuaternion.Angle()を用いて求めます。

var a = Quaternion.identity;
var b = Quaternion.AngleAxis(90, Vector3.forward);
Quaternion.Angle(a, b);

また、内積を使って下記のように求めることもできます。

//a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
var cos = Quaternion.Dot(a, b);
var rad = Mathf.Acos(cos) * 2;
rad * Mathf.Rad2Deg;

回転軸を求める

回転軸を求めるには、Quaternionのxyz成分を使って3次元ベクトルを作り、必要に応じて正規化します。

var quaternion = Quaternion.AngleAxis(90, Vector3.forward);
var axis = Vector3.zero;
axis.x = quaternion.x;
axis.y = quaternion.y;
axis.z = quaternion.z;
axis.Normalize();

回転角度も同時に求めたい場合はQuaternion.ToAngleAxis()を使うのが良いと思います。

関連

light11.hatenadiary.com