Author: bugman Date: Tue Sep 8 19:17:29 2009 New Revision: 9484 URL: http://svn.gna.org/viewcvs/relax?rev=9484&view=rev Log: Created the maths_fns.rotation_matrix.axis_angle_to_quaternion() function. This is accompanied by 2 unit tests. Modified: 1.3/maths_fns/rotation_matrix.py 1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py Modified: 1.3/maths_fns/rotation_matrix.py URL: http://svn.gna.org/viewcvs/relax/1.3/maths_fns/rotation_matrix.py?rev=9484&r1=9483&r2=9484&view=diff ============================================================================== --- 1.3/maths_fns/rotation_matrix.py (original) +++ 1.3/maths_fns/rotation_matrix.py Tue Sep 8 19:17:29 2009 @@ -83,6 +83,40 @@ R[2, 2] = z*zC + ca +def axis_angle_to_quaternion(axis, angle, quat, norm_flag=True): + """Generate the quaternion from the axis-angle notation. + + Conversion equations + ==================== + + From Wolfram MathWorld (http://mathworld.wolfram.com/Quaternion.html), the conversion is given by:: + + q = (cos(angle/2), n * sin(angle/2)), + + where q is the quaternion and n is the unit vector representing the rotation axis. + + + @param axis: The 3D rotation axis. + @type axis: numpy array, len 3 + @param angle: The rotation angle. + @type angle: float + @param quat: The quaternion structure. + @type quat: numpy 4D, rank-1 array + @keyword norm_flag: A flag which if True forces the axis to be converted to a unit vector. + @type norm_flag: bool + """ + + # Convert to unit vector. + if norm_flag: + axis = axis / norm(axis) + + # The scalar component of q. + quat[0] = cos(angle/2) + + # The vector component. + quat[1:] = axis * sin(angle/2) + + def euler_zyz_to_R(alpha, beta, gamma, R): """Function for calculating the z-y-z Euler angle convention rotation matrix. Modified: 1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py URL: http://svn.gna.org/viewcvs/relax/1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py?rev=9484&r1=9483&r2=9484&view=diff ============================================================================== --- 1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py (original) +++ 1.3/test_suite/unit_tests/_maths_fns/test_rotation_matrix.py Tue Sep 8 19:17:29 2009 @@ -109,6 +109,46 @@ self.assertEqual(R[i, j], R_true[i, j]) + def test_axis_angle_to_quaternion_no_rot(self): + """Test the axis-angle to quaternion conversion for a zero angle rotation.""" + + # Random axis and zero angle. + axis = array([-1, 1, 1], float64) / sqrt(3) + angle = 0.0 + + # The quaternion matrix. + quat = zeros(4, float64) + axis_angle_to_quaternion(axis, angle, quat) + print("Quaternion:\n%s" % quat) + + # The correct result. + quat_true = array([1, 0, 0, 0], float64) + + # Checks. + for i in range(4): + self.assertEqual(quat[i], quat_true[i]) + + + def test_axis_angle_to_quaternion_180_complex(self): + """Test the axis-angle to quaternion conversion for a 180 degree rotation about [1, 1, 1].""" + + # Random axis and zero angle. + axis = array([1, 1, 1], float64) / sqrt(3) + angle = pi + + # The quaternion matrix. + quat = zeros(4, float64) + axis_angle_to_quaternion(axis, angle, quat) + print("Quaternion:\n%s" % quat) + + # The correct result. + quat_true = array([0, 1, 1, 1], float64) / sqrt(3) + + # Checks. + for i in range(4): + self.assertAlmostEqual(quat[i], quat_true[i]) + + def test_axis_angle_to_R_z_30(self): """Test the quaternion to rotation matrix conversion for a 30 degree rotation about z."""