ジョイントの計算に必要になったのでメモ。
arc
/**
* v1からv2へと向かう円弧の回転を表すクォータニオンを作成します。
* v1とv2は正規化されている必要があることに注意してください。
* @param v1 開始
* @param v2 終了
* @return
*/
public function arc(v1:Vec3, v2:Vec3):Quat {
var x1:Number = v1.x;
var y1:Number = v1.y;
var z1:Number = v1.z;
var x2:Number = v2.x;
var y2:Number = v2.y;
var z2:Number = v2.z;
var d:Number = x1 * x2 + y1 * y2 + z1 * z2; // v1とv2が正規化されていれば内積は cos(theta) を表す
if (d == -1) { // cos(theta) = -1 であるので180度回転している
x2 = y1 * x1 - z1 * z1;
y2 = -z1 * y1 - x1 * x1;
z2 = x1 * z1 + y1 * y1;
d = 1 / Math.sqrt(x2 * x2 + y2 * y2 + z2 * z2);
s = 0;
x = x2 * d; // v1に垂直なベクトルを設定
y = y2 * d;
z = z2 * d;
return this;
}
var cx:Number = y1 * z2 - z1 * y2; // 外積
var cy:Number = z1 * x2 - x1 * z2;
var cz:Number = x1 * y2 - y1 * x2;
s = Math.sqrt((1 + d) * 0.5); // 半角の公式により cos(theta/2) を得る
d = 0.5 / s;
// ここで d = sin(theta/2) / sin(theta)
x = cx * d;
y = cy * d;
z = cz * d;
return this;
}
クォータニオンクラスの概要
Quat.as
public class Quat {
public var s:Number; // 実部
public var x:Number; // 以下虚部
public var y:Number;
public var z:Number;
}
ベクトルクラスの概要
Vec3.as
public class Vec3 {
public var x:Number;
public var y:Number;
public var z:Number;
}