しおんの部屋

3DCG とか スクリプト とか…

Quaternion の回転式の展開[Blender 3DCG]

2020年04月21日 | Blender Python
Quaternion の積の展開[Blender 3DCG]の続き

今回は Quaternionの積の展開結果 を利用して Quaternionの回転式 の展開を行う。

Quaternion(w,x,y,z) で 点(p,q,r) を回転した後の 点(P,Q,R) を求める式は
  (O,P,Q,R)=(w,x,y,z)(o,p,q,r)(w,-x,-y,-z)       O=0 , o=0
この式を展開用に、前回求めた Quaternionの積の展開結果① と ①を変形した② を準備する。
  (w,x,y,z)(o,p,q,r)          (a,b,c,d)(w,-x,-y,-z)
  =( wo-xp-yq-zr               =( +aw+bx+cy+dz
   , wp+xo+yr-zq                , -ax+bw-cz+dy
   , wq-xr+yo+zp                , -ay+bz+cw-dx
   , wr+xq-yp+zo ) …①         , -az-by+cx+dw ) …②
②の(a,b,c,d)に①を代入すれば、点(P,Q,R) を求める回転式が得られる。
( w,x,y,z,o,p,q,r はすべて実数なので通常の演算が可能 )
  (O,P,Q,R)
  =(w,x,y,z)(o,p,q,r)(w,-x,-y,-z)
  
  =( +(+wo-xp-yq-zr)w+(+wp+xo+yr-zq)x+(+wq-xr+yo+zp)y+(+wr+xq-yp+zo)z
   , -(+wo-xp-yq-zr)x+(+wp+xo+yr-zq)w-(+wq-xr+yo+zp)z+(+wr+xq-yp+zo)y
   , -(+wo-xp-yq-zr)y+(+wp+xo+yr-zq)z+(+wq-xr+yo+zp)w-(+wr+xq-yp+zo)x
   , -(+wo-xp-yq-zr)z-(+wp+xo+yr-zq)y+(+wq-xr+yo+zp)x+(+wr+xq-yp+zo)w )

  =( (+wo-xp-yq-zr)w +(+wp+xo+yr-zq)x +(+wq-xr+yo+zp)y +(+wr+xq-yp+zo)z
   , (-wo+xp+yq+zr)x +(+wp+xo+yr-zq)w +(-wq+xr-yo-zp)z +(+wr+xq-yp+zo)y
   , (-wo+xp+yq+zr)y +(+wp+xo+yr-zq)z +(+wq-xr+yo+zp)w +(-wr-xq+yp-zo)x
   , (-wo+xp+yq+zr)z +(-wp-xo-yr+zq)y +(+wq-xr+yo+zp)x +(+wr+xq-yp+zo)w )
  
  =( +wwo-xwp-ywq-zwr +wxp+xxo+yxr-zxq +wyq-xyr+yyo+zyp +wzr+xzq-yzp+zzo
   , -wxo+xxp+yxq+zxr +wwp+xwo+ywr-zwq -wzq+xzr-yzo-zzp +wyr+xyq-yyp+zyo
   , -wyo+xyp+yyq+zyr +wzp+xzo+yzr-zzq +wwq-xwr+ywo+zwp -wxr-xxq+yxp-zxo
   , -wzo+xzp+yzq+zzr -wyp-xyo-yyr+zyq +wxq-xxr+yxo+zxp +wwr+xwq-ywp+zwo )
  
  =( (+ww+xx+yy+zz)o +(-xw+wx+zy-yz)p +(-yw-zx+wy+xz)q +(-zw+yx-xy+wz)r
   , (-wx+xw-yz+zy)o +(+xx+ww-zz-yy)p +(+yx-zw-wz+xy)q +(+zx+yw+xz+wy)r
   , (-wy+xz+yw-zx)o +(+xy+wz+zw+yx)p +(+yy-zz+ww-xx)q +(+zy+yz-xw-wx)r
   , (-wz-xy+yx+zw)o +(+xz-wy+zx-yw)p +(+yz+zy+wx+xw)q +(+zz-yy-xx+ww)r )
  
  =( (+ww+xx+yy+zz)o +(-wx+wx+yz-yz)p +(-wy-zx+wy+zx)q +(-wz+xy-xy+wz)r
   , (-wx+wx-yz+yz)o +(+xx+ww-zz-yy)p +(+xy-wz-wz+xy)q +(+zx+wy+zx+wy)r
   , (-wy+zx+wy-zx)o +(+xy+wz+wz+xy)p +(+yy-zz+ww-xx)q +(+yz+yz-wx-wx)r
   , (-wz-xy+xy+wz)o +(+zx-wy+zx-wy)p +(+yz+yz+wx+wx)q +(+zz-yy-xx+ww)r )
  
  =( (ww+xx+yy+zz)o +(0          )p +(0          )q +(0          )r
   , (0          )o +(ww+xx-yy-zz)p +(2xy-2wz    )q +(2zx+2wy    )r
   , (0          )o +(2xy+2wz    )p +(ww-xx+yy-zz)q +(2yz-2wx    )r
   , (0          )o +(2zx-2wy    )p +(2yz+2wx    )q +(ww-xx-yy+zz)r )
回転式としてまとめると o=0 , O=0 より以下が得られる。
  (0,P,Q,R)
  =(w,x,y,z)(0,p,q,r)(w,-x,-y,-z)
  =( 0
   , (ww+xx-yy-zz)p +(2xy-2wz    )q +(2zx+2wy    )r
   , (2xy+2wz    )p +(ww-xx+yy-zz)q +(2yz-2wx    )r
   , (2zx-2wy    )p +(2yz+2wx    )q +(ww-xx-yy+zz)r )
実際に Blender2.8 の Pythonコンソール で試算してみる。
通常の演算で求めた p2 と、今回の展開式から求めた p3 が一致していることがわかる。
--Python--

b1 = bpy.context.active_pose_bone
q1 = b1.rotation_quaternion
p1 = Quaternion((0,1.1,1.2,1.3))
w,x,y,z = q1
o,p,q,r = p1
#
p2 = q1 @ p1 @ q1.inverted()
p3 = Quaternion((0
                ,(w*w+x*x-y*y-z*z)*p+(2*x*y-2*w*z)*q+(2*z*x+2*w*y)*r
                ,(2*x*y+2*w*z)*p+(w*w-x*x+y*y-z*z)*q+(2*y*z-2*w*x)*r
                ,(2*z*x-2*w*y)*p+(2*y*z+2*w*x)*q+(w*w-x*x-y*y+z*z)*r))
#
print( "q1    =" , q1    )
print( "p1    =" , p1    )
print( "p2    =" , p2    )
print( "p3    =" , p3    )

--実行結果--

q1    = <Quaternion (w=0.6884, x="0.7204," y="0.0192," z="0.0822)">
p1    = <Quaternion (w=0.0000, x="1.1000," y="1.2000," z="1.3000)">
p2    = <Quaternion (w=0.0000, x="1.1700," y="-1.1921," z="1.2450)">
p3    = <Quaternion (w=0.0000, x="1.1700," y="-1.1921," z="1.2450)">

コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« Quaternion の積の展開[Blend... | トップ | 肩のねじれを防ぐ Quaternion... »

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。

Blender Python」カテゴリの最新記事