sunday-labの日本語訳版です。英語版のXOOPS Cube関連記事を翻訳作業中...

2008年4月16日水曜日

Get pitch, yaw, roll from Quaternion

クォータニオンからオイラー角を取り出す場合、
  • Z-ROLLを無視することにして、向きのベクトルを与えてピッチ角とヨー角を計算して取り出す
  • 向きのベクトルと、それに直行するベクトルを与えて、ロール角も取り出す

という2つの計算方法がまず考えられます。この方法はクォータニオンを元にベクトルを回転させて、その2つのベクトルのなす角度を計算しています。

他方、クォータニオンの4元数 x, y, z, w から直接計算する式もあります。

float Quaternion::getPitch()
{
return atan2(2*(y*z + w*x), w*w - x*x - y*y + z*z);
}

float Quaternion::getYaw()
{
return asin(-2*(x*z - w*y));
}

float Quaternion::getRoll()
{
return atan2(2*(x*y + w*z), w*w + x*x - y*y - z*z);
}


計算される角度は最短距離の角度であり、ベクトルを使って射影し、なす角度を測る場合に比べると、クォータニオンらしい値が出てくることになります。たとえば真後ろへの振り向きがヨー180°ではなく、ロール180°ピッチ-180°だったり……この値は再計算や保存値に使うには心もとないですが、単独で計算できるため、画面出力やダンプに向いています。

4 件のコメント:

匿名 さんのコメント...

初めまして!

内藤 さんのコメント...

すみません・・・↑は間違って投稿してしまいました。申し訳ございません。

改めて初めまして!
先日クォータニオンからオイラー角を求める方法を検索していてたどり着いた内藤と申します。

このエントリで紹介されていた式が大いに参考になりまして本当に感謝しております!
ただ今一つ困っている事がありまして、こちらの式はXYZのオーダーで回転させたクォータニオンからオイラー角を求める式だと思うのですが、オーダーがZXYの場合はオイラー角を求める式はどのようになるのでしょうか?
不躾なお願いで恐縮なのですがもし教えて頂けたら幸いと存じます。

minahito さんのコメント...

こんにちは!

すみません紹介しておいて何なのですが、実は僕はこのコード使ってません...反転付近の答えが二通りあるのがダメで...

正確にとる場合は、縦軸と横軸のベクトルを指定して、そのなす角を測定したほうが確実だと思います。

オーダーの逆順に角度を測りつつ回転をほどいていけば、どんなオーダーにも対応できるようになります。

いま時間がないので、コードは1~2日待ってください。(^^;

内藤 さんのコメント...

>いま時間がないので、コードは1~2日待ってください。(^^;
本当にありがとうございます~。
お手数かけてしまいまして申し訳ございません。