chaomodus/pyeuclid

Suggestion for improving quaternion get_angle_axis

Opened this issue · 0 comments

What steps will reproduce the problem?
q1 = Quaternion(1,0,0,0)
q2 = Quaternion(-1,0,0,0)
qe = q1.conjugated()*q2
qe.get_angle_axis()

What is the expected output? What do you see instead?
I would expect to get zero for the angle between these two quaternions (since 
they are the same). Instead I get the following result (an angle of 2*pi):
(6.2831853071795862, Vector3(1.00, 0.00, 0.00))

What version of the product are you using? On what operating system?
Revision #36 on Ubuntu 10.04. I looked at the latest source code, the 
get_angle_axis function has not changed since r36.

Please provide any additional information below.
The returned result is technically correct but I would think for most 
applications you would want the smallest rotation. I would recommend changing 
the get_angle_axis function to something more like this:

def get_angle_axis(self):
    if abs(self.w) > 1:
        self = self.normalized()
    angle = 2 * math.acos(abs(self.w))
    s = math.sqrt(1 - self.w ** 2)
    if s < 0.001:
        return angle, Vector3(1, 0, 0)
    elif self.w >= 0:
        return angle, Vector3(self.x / s, self.y / s, self.z / s)
    else:
        return angle,-Vector3(self.x / s, self.y / s, self.z / s)

Disclaimer: I haven't tested this function but it seems correct to me.

Original issue reported on code.google.com by chris.fl...@gmail.com on 19 Dec 2011 at 7:54