回転行列からオイラー角を求めるために紙に計算をしてたら、あってんだか間違ってるんだかわけわからなくなってきたので作った。
結果の方をあとで使うので、まず結果から貼っとく。
[["XYZ", [["cosY*conZ", "-cosY*sinZ", "sinY"], ["sinX*sinY*conZ+cosX*sinZ", "-sinX*sinY*sinZ+cosX*cosZ", "-sinX*conY"], ["-cosX*sinY*conZ+sinX*sinZ", "cosX*sinY*sinZ+sinX*cosZ", "cosX*conY"]]], ["XZY", [["conZ*cosY", "-sinZ", "conZ*sinY"], ["cosX*sinZ*cosY+sinX*sinY", "cosX*cosZ", "cosX*sinZ*sinY+-sinX*conY"], ["sinX*sinZ*cosY+-cosX*sinY", "sinX*cosZ", "sinX*sinZ*sinY+cosX*conY"]]], ["YXZ", [["cosY*conZ+sinY*sinX*sinZ", "-cosY*sinZ+sinY*sinX*cosZ", "sinY*cosX"], ["cosX*sinZ", "cosX*cosZ", "-sinX"], ["-sinY*conZ+conY*sinX*sinZ", "sinY*sinZ+conY*sinX*cosZ", "conY*cosX"]]], ["YZX", [["cosY*conZ", "-cosY*sinZ*cosX+sinY*sinX", "cosY*sinZ*sinX+sinY*cosX"], ["sinZ", "cosZ*cosX", "-cosZ*sinX"], ["-sinY*conZ", "sinY*sinZ*cosX+conY*sinX", "-sinY*sinZ*sinX+conY*cosX"]]], ["ZXY", [["conZ*cosY+-sinZ*sinX*sinY", "-sinZ*cosX", "conZ*sinY+sinZ*sinX*conY"], ["sinZ*cosY+cosZ*sinX*sinY", "cosZ*cosX", "sinZ*sinY+-cosZ*sinX*conY"], ["-cosX*sinY", "sinX", "cosX*conY"]]], ["ZYX", [["conZ*cosY", "-sinZ*cosX+conZ*sinY*sinX", "sinZ*sinX+conZ*sinY*cosX"], ["sinZ*cosY", "cosZ*cosX+sinZ*sinY*sinX", "-cosZ*sinX+sinZ*sinY*cosX"], ["-sinY", "conY*sinX", "conY*cosX"]]]]
出すのに使ったプログラム
#! ruby -Ku # coding: utf-8 # 行列の乗算を文字列にして見たかった require 'matrix' class String alias :plus :+ alias :mul :* def +(x) x = x.to_s case x when '0'; self.clone else ; "#{self}+#{x}" end end def *(x) x = x.to_s case x when '0'; 0 when '1'; self.clone else # 単項マイナスをキレイにする if x[0] == '-' if self[0] == '-' # - * - "#{self[1..-1]}*#{x[1..-1]}" else # + * - "-#{self}*#{x[1..-1]}" end else # + * + "#{self}*#{x}" end end end end class Fixnum alias :plus :+ alias :mul :* def +(x) case x when String self == 0 ? x.clone : self.to_s + x else self == 0 ? x : self.plus(x) end end def *(x) case x when String case self when 0; 0 when 1; x.clone else ; "#{self}*#{x}" end else self.mul(x) end end end rx = Matrix[ [ 1, 0, 0], [ 0, 'cosX','-sinX'], [ 0, 'sinX', 'cosX'], ] ry = Matrix[ [ 'cosY', 0,'sinY'], [ 0, 1, 0], ['-sinY', 0,'conY'], ] rz = Matrix[ [ 'conZ','-sinZ', 0], [ 'sinZ', 'cosZ', 0], [ 0, 0, 1], ] a = { 'XYZ'=>rx*ry*rz, 'XZY'=>rx*rz*ry, 'YXZ'=>ry*rx*rz, 'YZX'=>ry*rz*rx, 'ZXY'=>rz*rx*ry, 'ZYX'=>rz*ry*rx, } # 表示の前に元に戻す class String alias :+ :plus alias :* :mul end require 'pp' pp a.map{|k,v| [k, v.to_a]}
野良プログラムすぎるので細かいことは気にしない方向で。 * と + で文字列連結して、ちょっと小細工してキレイに見えるようにしただけ。1.8 でも動くけど、order hash な 1.9 がよいよい。
/ にも対応したら逆数とかも見れるようになるんだろうか。めんどくさいからやらないけど。