開発環境 |
Microsoft Visual C# 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
空のプロジェクト |
プロジェクト名 |
Quaternion |
四元数(しげんすう、クォータニオン)の用途には2種類ある。
1.座標を表す。
2.回転軸と角度を表す。
1.の方は値のセットも取得も行う。
2.の方は値をセットし利用はするが、取得はあまり行わない。
3次元の座標の四元数での表現
ある座標(x,y,z)を四元数で表すには、
Quaternion p = new Quaternion(new Vector3(x, y, z), 0);
とする。
ちなみに、4番目の要素wをゼロ以外の値にしても問題ないようだが、ゼロ以外にする意味はないと思う。
回転の四元数での表現
原点を回転の中心として、回転の軸が(x,y,z)で
(右手系の座標定義では、ベクトル(x,y,z)の進む方向に向かって眺めて反時計回りに)
t度回す回転を表す四元数は
Quaternion q = Quaternion.CreateFromAxisAngle(new Vector3(x, y, z), MathHelper.ToRadians(t));
Quaternion r = Quaternion.Quaternion.Conjugate(Q);
と作る。(ちなみにrはqの共役四元数という)
回転を実行するには、
Quaternion rpq = r * p * q;
と計算する。rpqの(x,y,z)が回転した後の座標である。
原点以外を通る回転軸の場合、回転軸が原点を通るように座標を平行移動して回転し、平行移動しなおす。
(もっといい方法があるかもしれない)
参考
Program.cs
// Quaternion4.1
using System;
using Microsoft.Xna.Framework; // .NET参照
class Program
{
static void Main()
{
Vector3 v = new Vector3(0, 1, 0); // 回転軸の方向を表すベクトル
for (int t = 0; t <= 360; t += 45)
{
Quaternion q = Quaternion.CreateFromAxisAngle(v, MathHelper.ToRadians(t));
Console.Write(string.Format("t={0} / ", t));
Print(q);
}
Console.ReadLine();
}
static void Print(Quaternion q)
{
Console.WriteLine(string.Format("x={0:f2} y={1:f2} z={2:f2} w={3:f2} len={4:f2}",
q.X, q.Y, q.Z, q.W, q.Length()));
}
}
出力
t=0 / x=0.00 y=0.00 z=0.00 w=1.00 len=1.00
t=45 / x=0.00 y=0.38 z=0.00 w=0.92 len=1.00
t=90 / x=0.00 y=0.71 z=0.00 w=0.71 len=1.00
t=135 / x=0.00 y=0.92 z=0.00 w=0.38 len=1.00
t=180 / x=0.00 y=1.00 z=0.00 w=0.00 len=1.00
t=225 / x=0.00 y=0.92 z=0.00 w=-0.38 len=1.00
t=270 / x=0.00 y=0.71 z=0.00 w=-0.71 len=1.00
t=315 / x=0.00 y=0.38 z=0.00 w=-0.92 len=1.00
t=360 / x=0.00 y=0.00 z=0.00 w=-1.00 len=1.00
考察
t=0のときqはQuaternion.Identity(=(0,0,0,1))と同じ値になり無回転を表す。
t=180のときqは(0,1,0)の座標と同じ値であるが、使われ方によってその意味は異なる。
Program.cs
// Quaternion4.2 任意の回転軸で点を回転
using System;
using Microsoft.Xna.Framework; // .NET参照
class Program
{
static void Main()
{
float a = (float)Math.Sin(MathHelper.ToRadians(45)) * 10;
Quaternion p = new Quaternion(new Vector3(a, a, 0), 0); // 回転させたい点
Vector3 v = new Vector3(0, 1, 0); // 回転軸の方向を表すベクトル
for (int t = 0; t <= 360; t += 45)
{
Quaternion q = Quaternion.CreateFromAxisAngle(v, MathHelper.ToRadians(t));
//Quaternion r = Quaternion.CreateFromAxisAngle(-v, MathHelper.ToRadians(n));
Quaternion r = Quaternion.Conjugate(q); // 共役。↑と同じ
Quaternion rpq = r * p * q;
Console.Write(string.Format("t={0} / ", t));
Print(rpq);
}
Console.ReadLine();
}
static void Print(Quaternion q)
{
Console.WriteLine(string.Format("x={0:f2} y={1:f2} z={2:f2} w={3:f2} len={4:f2}",
q.X, q.Y, q.Z, q.W, q.Length()));
}
}
出力
t=0 / x=7.07 y=7.07 z=0.00 w=0.00 len=10.00
t=45 / x=5.00 y=7.07 z=5.00 w=0.00 len=10.00
t=90 / x=0.00 y=7.07 z=7.07 w=0.00 len=10.00
t=135 / x=-5.00 y=7.07 z=5.00 w=0.00 len=10.00
t=180 / x=-7.07 y=7.07 z=0.00 w=0.00 len=10.00
t=225 / x=-5.00 y=7.07 z=-5.00 w=0.00 len=10.00
t=270 / x=0.00 y=7.07 z=-7.07 w=0.00 len=10.00
t=315 / x=5.00 y=7.07 z=-5.00 w=0.00 len=10.00
t=360 / x=7.07 y=7.07 z=0.00 w=0.00 len=10.00
Program.cs
// Quaternion4.3 任意の回転軸・原点で点を回転
using System;
using Microsoft.Xna.Framework; // .NET参照
class Program
{
static void Main()
{
Vector3 v = new Vector3(0, 1, 0); // 回転軸の方向を表すベクトル
Vector3 o = new Vector3(10, 0, 0); // 回転の原点
Quaternion p = new Quaternion(new Vector3(20, 0, 0) - o, 0); // 回転させたい点-回転の原点
for (int t = 0; t <= 360; t += 45)
{
Quaternion q = Quaternion.CreateFromAxisAngle(v, MathHelper.ToRadians(t));
//Quaternion r = Quaternion.CreateFromAxisAngle(-v, MathHelper.ToRadians(n));
Quaternion r = Quaternion.Conjugate(q); // 共役。↑と同じ
Quaternion rpq = r * p * q;
Vector3 pos = QV(rpq) + o; // 回転後の点+回転の原点
Console.Write(string.Format("t={0} / ", t));
Print(pos);
}
Console.ReadLine();
}
static void Print(Vector3 v)
{
Console.WriteLine(string.Format("x={0:f2} y={1:f2} z={2:f2}", v.X, v.Y, v.Z));
}
static Vector3 QV(Quaternion q)
{
return new Vector3(q.X, q.Y, q.Z);
}
}
出力
t=0 / x=20.00 y=0.00 z=0.00
t=45 / x=17.07 y=0.00 z=7.07
t=90 / x=10.00 y=0.00 z=10.00
t=135 / x=2.93 y=0.00 z=7.07
t=180 / x=0.00 y=0.00 z=0.00
t=225 / x=2.93 y=0.00 z=-7.07
t=270 / x=10.00 y=0.00 z=-10.00
t=315 / x=17.07 y=0.00 z=-7.07
t=360 / x=20.00 y=0.00 z=0.00
最終更新:2012年12月17日 12:33