[[数学]]~
[[Maxima]]~


*概要 [#d16149c0]
-即刻導出できるようにするための資料
-12パターンある上に不定性があって,毎回考えなおすのはつらいので.

*全部軸が違うよパターン [#y92c91a9]
-[[参考>http://d.hatena.ne.jp/It_lives_vainly/20070829/1188384519]]
-6パターンあるが,順番をZYXだけ解説すればよい.そしてアルファベータガンマだと直感的でないのでx,y,zで代用
-まずmaximaでzyxを計算 (maxima -b rot.maxima)

 Z:matrix([cos(z), -sin(z), 0],[sin(z), cos(z), 0], [0, 0, 1]);
 Y:matrix([cos(y), 0, sin(y)],[0, 1, 0], [-sin(y), 0, cos(y)]);
 X:matrix([1, 0, 0],[0, cos(x), -sin(x)], [0, sin(x), cos(x)]);
 
 Z.Y.X;
 trigreduce(ev(Z.Y.X, y = -%pi/2));
 trigreduce(ev(Z.Y.X, y = +%pi/2));
 
 readline(?\*standard\-input\*);
 
-結果

 (%i5) Z . Y . X
                [ cos(y) cos(z) ]
                [               ]
 (%o5)  Col 1 = [ cos(y) sin(z) ]
                [               ]
                [   - sin(y)    ]
          [ sin(x) sin(y) cos(z) - cos(x) sin(z) ]
          [                                      ]
  Col 2 = [ sin(x) sin(y) sin(z) + cos(x) cos(z) ]
          [                                      ]
          [            sin(x) cos(y)             ]
          [ sin(x) sin(z) + cos(x) sin(y) cos(z) ]
          [                                      ]
  Col 3 = [ cos(x) sin(y) sin(z) - sin(x) cos(z) ]
          [                                      ]
          [            cos(x) cos(y)             ]
 (%i6) trigreduce(ev(Z . Y . X,y = (-%pi)/2))
                        [ 0  - sin(z + x)  - cos(z + x) ]
                        [                               ]
 (%o6)                  [ 0   cos(z + x)   - sin(z + x) ]
                        [                               ]
                        [ 1       0             0       ]
 (%i7) trigreduce(ev(Z . Y . X,y = (+%pi)/2))
                        [  0   - sin(z - x)  cos(z - x) ]
                        [                               ]
 (%o7)                  [  0    cos(z - x)   sin(z - x) ]
                        [                               ]
                        [ - 1       0            0      ]
 

-実際求めてみると,2番目の回転の成分が一項だけのものが出てくる.これを鍵要素と定義する.ここではm20=-sin(y)が鍵要素であり,yが鍵.-pi/2<=y<=+pi/2で動くと仮定
++cos(鍵)が0でないとき(つまりyが-pi/2でもpi/2でもないとき)
---yを普通にasinで解く.y = asin(-m20)
---x, zは,鍵要素を有する行と列を割り算することで,tanが出てくるので普通に解く.x = atan2(m21, m22), z = atan2(m10, m00)
++cos(鍵)が0の時
---m20が1ならy=-pi/2, m20が-1ならy=+pi/2
---1番目回転-3番目回転が項にまとまってしまい,不定になるので,3番目回転のx=0としてしまう.
---z = atan2(m12, m02)

-実装
     // zyx Euler
     double x = 0, y = 0, z = 0; // [rad]
     if (std::abs(_0sR(2, 0) /*zyxで最も単純になる行列要素*/ - 1) > EPS && std::abs(_0sR(2, 0) + 1) > EPS) {
       y = asin(_0sR(2, 0));
       y = asin(-_0sR(2, 0));
       x = atan2(_0sR(2, 1), _0sR(2, 2));
       z = atan2(_0sR(1, 0), _0sR(0, 0));
     } else {
       if (_0sR(2, 0) > 0) {  // _0sR(2, 0) == 1
         y = -M_PI / 2;
       } else { // _0sR(2, 0) == -1
         y = +M_PI / 2;
       }
       x = 0; // xzの不定性より
       z = atan2(_0sR(1, 2), _0sR(0, 2));
     }
     cerr << x << " " << y << " " << z << "#euler" << endl;


// euler

*初めに回転させた軸でもう一回回転させるよパターン [#m96b9100]
-6パターンある
-まだ必要になっていないので書かない

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS