Hmm, I take it you mean you want to be able to rotate the arm but the hand remain un-rotated in the 'world' frame of reference. When the shape is made an child of another shape all of its rotations are defined relative to the parent's frame of reference.
The problem is basically that matrix multiplication is not commutative which means that if X means rotation about x axis and if XYZ means apply Z to a vector then apply Y to the result then apply X to the result this will be a different rotation to YXZ, YZX, ZYX, XZY and ZXY if you use the (non-standard) axis orientation of
pi3d (and the opengl screen) of z in, y up and x rightwards and take the vector 0,0,1 (i.e. straight into the screen) and apply 90 degree rotations you will see that XYZ is pointing left -1,0,0 but YXZ gives 0,1,0 and YZX gives 0,0,1 i.e. doesn't change it!
pi3d always applies the rotations z then x then y ie YXZ
So, to cut a long story short to get the reversed rotation for the hand you really need to apply the negative rotations also in the reverse order i.e. -Z-X-Y(YXZ) will bring you back to where you started but -Y-X-Z(YXZ) will not do. But you can't easily do this in
pi3d. So, in order to reverse the rotation of the hand to exactly compensate for the rotation of the arm you need to find three new rotations P about the x axis Q about the y and R about the z such that QPR == -Z-X-Y which is tricky, however there are two methods in Camera which might be used in some way: Camera.matrix_from_two_vecors() and Camera.euler_angles()
OR attempt to solve the nine simultaneous equations you can derive from here
https://en.wikipedia.org/wiki/Euler_ang ... ion_matrix something like
Code: Select all
cR.cP-sR.sP.sQ cQ.sR+cR.sP.sQ -cP.sQ
-cP.sR cR.cP sP
cR.sQ+Qy.sR.sP sR.sQ-cR.cQ.sP cP.cQ
matches
cY.cZ-sY.sX.sZ -cX.sZ cY.sX.sZ
cZ.sY.sX+cY.sZ cX.cZ -cY.cZ.sX+sY.sZ
-cX.sY sX cY.cX
where RPQ are the xyz axis rotations to apply to the hand to compensate for the XYZ rotations applied to the arm.
NB you will have to check through these as I have almost certainly made several mistakes AND you need to be aware that, as well as using different axes
pi3d also uses C style arrays for its matrices (which are laid out like reading a book x is axis 0 and y is axis 1 i.e. x is the line number and y is the character along each line) whereas standard mathematical notation uses fortran arrays (x is left to right and z is up and down) AND I have to warn you that I spent quite a bit of time fiddling around getting the matrices to work with
pi3d!
After reading through what I have written I think my approach might be to create the reverse rotation matrix for the arm using numpy to save time doing lots of trig (see
pi3d.Shape.draw()) something like:
Code: Select all
rox_neg = arm.rox.copy()
rox_neg[1,2] *= -1
rox_neg[2,1] *= -1
roy_neg = arm.roy.copy()
roy_neg[0,2] *= -1
roy_neg[2,0] *= -1
roz_neg = arm.roz.copy()
roz_neg[0,1] *= -1
roz_neg[1,0] *= -1
p, q, r = camera.euler_angles(np.dot(roz_neg, np.dot(rox_neg, roy_neg)))