Why does Quaternion.rotation_difference() always return 12.666471 for x-rotation? I tried to calculate the angle between two vectors. 

First 3 Quaternion rotations (qx,qy,qz) are defined and multiplied to q. A vector v (1,0,0) is rotated by q. 

From the vectors q and qrot I want to recreate the original roation qcalc but the x-value of qcalc is always 0.

from math import cos,sin,radians,degrees,sqrt
from mathutils import Quaternion,Vector

def eprint(e):
    print("euler X=%f Y=%f Z=%f" % (degrees( e.x ),degrees( e.y ),degrees( e.z )))    


qx =  Quaternion((1.0, 0.0, 0.0), radians( 15.0 )) # &lt;--- has no influence to the result
qy =  Quaternion((0.0, 1.0, 0.0), radians( 30.0 ))
qz =  Quaternion((0.0, 0.0, 1.0), radians( 45.0 ))
q = qz * qy *qx
#q = qx * qy *qz
print("-"*40)
eprint(q.to_euler('XYZ'))
print(str(q))

v = Vector(( 1.0 , 0.0 , 0.0 ))
print("v=" + str(v))
vrot =  q * v 
print("vrot=" + str(vrot))
qcalc = v.rotation_difference( vrot )
eprint( qcalc.to_euler( 'XYZ' ))
print(str(qcalc))


prints

----------------------------------------
euler X=14.999997 Y=30.000008 Z=45.000005
&lt;Quaternion (w=0.8977, x=0.0183, y=0.2853, z=0.3353)&gt;
v=&lt;Vector (1.0000, 0.0000, 0.0000)&gt;
vrot=&lt;Vector (0.6124, 0.6124, -0.5000)&gt;
euler X=12.666476 Y=30.000008 Z=45.000008
&lt;Quaternion (w=0.8979, x=-0.0000, y=0.2784, z=0.3410)&gt;


It doesn't matter which value for x-rotation is used for qx the result is always X=12.666471 why is that?
The Quaternion should be WXYZ: .898, .018, .285, .335

I verified the rotation order in the console with enabled mathvis addon:

# show quaternion rotation order
qx =  Quaternion((1.0, 0.0, 0.0), radians( 15.0 ))
qy =  Quaternion((0.0, 1.0, 0.0), radians( 30.0 ))
qz =  Quaternion((0.0, 0.0, 1.0), radians( 45.0 ))
q = qz * qy *qx
qx = qy = qz = None
o = Vector((0,0,0))
right = Vector((1,0,0))
r2 = q * right
r3 = [o,r2]




Another implementation I've adapted from ogre has the same issue (x-rot in quaternion is 0)

# https://bitbucket.org/sinbad/ogre/src/9db75e3ba05c/OgreMain/include/OgreVector3.h?fileviewer=file-view-default#cl-651
def rotation_between2( u,  v):
    cross = u.cross(v)
    cross.normalize()
    ul2 = u.length * u.length
    vl2 = v.length * v.length
    d = u.dot(v)
    l = d / sqrt(ul2 * vl2) 
    w = acos(l)
    q = Quaternion( cross , w )
    q.normalize()
    return q
The issue is the test data, the vector v = Vector(( 1.0 , 0.0 , 0.0 )) lies exactly on the x-axis and a rotation around x has absolutely no effect, therefore the information is lost.

In order to get the rotation from v to vrot it is requiresd to invoke rotation_difference() on v insteadof vrot.