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)">