Package test_suite :: Package unit_tests :: Package _maths_fns :: Module test_rotation_matrix
[hide private]
[frames] | no frames]

Source Code for Module test_suite.unit_tests._maths_fns.test_rotation_matrix

   1  ############################################################################### 
   2  #                                                                             # 
   3  # Copyright (C) 2009-2010 Edward d'Auvergne                                   # 
   4  #                                                                             # 
   5  # This file is part of the program relax.                                     # 
   6  #                                                                             # 
   7  # relax is free software; you can redistribute it and/or modify               # 
   8  # it under the terms of the GNU General Public License as published by        # 
   9  # the Free Software Foundation; either version 2 of the License, or           # 
  10  # (at your option) any later version.                                         # 
  11  #                                                                             # 
  12  # relax is distributed in the hope that it will be useful,                    # 
  13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
  14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
  15  # GNU General Public License for more details.                                # 
  16  #                                                                             # 
  17  # You should have received a copy of the GNU General Public License           # 
  18  # along with relax; if not, write to the Free Software                        # 
  19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
  20  #                                                                             # 
  21  ############################################################################### 
  22   
  23  # Python module imports. 
  24  from copy import deepcopy 
  25  from math import acos, asin, pi, sqrt 
  26  from numpy import array, eye, float64, zeros 
  27  from numpy.linalg import norm 
  28  from random import shuffle, uniform 
  29  from unittest import TestCase 
  30   
  31  # relax module imports. 
  32  from generic_fns.angles import wrap_angles 
  33  from maths_fns.rotation_matrix import * 
  34   
  35   
  36  # Global variables (reusable storage). 
  37  R = zeros((3, 3), float64) 
  38  R2 = zeros((3, 3), float64) 
  39   
  40   
41 -class Test_rotation_matrix(TestCase):
42 """Unit tests for the maths_fns.rotation_matrix relax module.""" 43
44 - def setUp(self):
45 """Set up data used by the unit tests.""" 46 47 # Axes. 48 self.x_axis_pos = array([1, 0, 0], float64) 49 self.y_axis_pos = array([0, 1, 0], float64) 50 self.z_axis_pos = array([0, 0, 1], float64) 51 52 # Axes (do everything again, this time negative!). 53 self.x_axis_neg = array([-1, 0, 0], float64) 54 self.y_axis_neg = array([0, -1, 0], float64) 55 self.z_axis_neg = array([0, 0, -1], float64)
56 57
58 - def check_return_conversion(self, euler_to_R=None, R_to_euler=None, alpha_start=None, beta_start=None, gamma_start=None, alpha_end=None, beta_end=None, gamma_end=None):
59 """Check the Euler angle to rotation matrix to Euler angle conversion.""" 60 61 # Print out. 62 print_out = "" 63 print_out = print_out + "\n\n# Checking the %s() and %s() conversions.\n\n" % (euler_to_R.__name__, R_to_euler.__name__) 64 65 # A small number. 66 epsilon = 1e-15 67 68 # End angles. 69 if alpha_end == None: 70 alpha_end = alpha_start 71 if beta_end == None: 72 beta_end = beta_start 73 if gamma_end == None: 74 gamma_end = gamma_start 75 76 # Generate the rotation matrix. 77 euler_to_R(alpha_start, beta_start, gamma_start, R) 78 print_out = print_out + "R: |%8.5f, %8.5f, %8.5f|\n" % (R[0, 0], R[0, 1], R[0, 2]) 79 print_out = print_out + " |%8.5f, %8.5f, %8.5f|\n" % (R[1, 0], R[1, 1], R[1, 2]) 80 print_out = print_out + " |%8.5f, %8.5f, %8.5f|\n" % (R[2, 0], R[2, 1], R[2, 2]) 81 82 # Get back the angles. 83 alpha_new, beta_new, gamma_new = R_to_euler(R) 84 85 # Print out. 86 print_out = print_out + "Original angles: (%8.5f, %8.5f, %8.5f)\n" % (alpha_start, beta_start, gamma_start) 87 print_out = print_out + "End angles: (%8.5f, %8.5f, %8.5f)\n" % (alpha_end, beta_end, gamma_end) 88 print_out = print_out + "New angles: (%8.5f, %8.5f, %8.5f)\n" % (alpha_new, beta_new, gamma_new) 89 90 # Wrap the angles. 91 alpha_new = wrap_angles(alpha_new, 0-epsilon, 2*pi-epsilon) 92 beta_new = wrap_angles(beta_new, 0-epsilon, 2*pi-epsilon) 93 gamma_new = wrap_angles(gamma_new, 0-epsilon, 2*pi-epsilon) 94 95 # Print out. 96 print_out = print_out + "New angles (wrapped) (%8.5f, %8.5f, %8.5f)\n" % (alpha_new, beta_new, gamma_new) 97 98 # Second solution required! 99 if abs(beta_end - beta_new) > 1e-7: 100 # Collapse the multiple beta solutions. 101 if beta_new < pi: 102 alpha_new = alpha_new + pi 103 beta_new = pi - beta_new 104 gamma_new = gamma_new + pi 105 else: 106 alpha_new = alpha_new + pi 107 beta_new = 3*pi - beta_new 108 gamma_new = gamma_new + pi 109 110 # Wrap the angles. 111 alpha_new = wrap_angles(alpha_new, 0-epsilon, 2*pi-epsilon) 112 beta_new = wrap_angles(beta_new, 0-epsilon, 2*pi-epsilon) 113 gamma_new = wrap_angles(gamma_new, 0-epsilon, 2*pi-epsilon) 114 115 # Print out. 116 print_out = print_out + "New angles (2nd sol) (%8.5f, %8.5f, %8.5f)\n" % (alpha_new, beta_new, gamma_new) 117 118 # Print out. 119 eps = 1e-5 120 if abs(alpha_new - alpha_end) > eps or abs(beta_new - beta_end) > eps or abs(gamma_new - gamma_end) > eps: 121 print(print_out) 122 123 # Checks. 124 self.assertAlmostEqual(alpha_end, alpha_new) 125 self.assertAlmostEqual(beta_end, beta_new) 126 self.assertAlmostEqual(gamma_end, gamma_new)
127 128
129 - def check_rotation(self, R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg):
130 """Check that the rotation matrix is correct.""" 131 132 # Rotate the 6 axes. 133 x_new_pos = dot(R, self.x_axis_pos) 134 y_new_pos = dot(R, self.y_axis_pos) 135 z_new_pos = dot(R, self.z_axis_pos) 136 137 x_new_neg = dot(R, self.x_axis_neg) 138 y_new_neg = dot(R, self.y_axis_neg) 139 z_new_neg = dot(R, self.z_axis_neg) 140 141 # Print out. 142 print("Rotated and true axes (beta = pi/4):") 143 print(("x pos rot: %s" % x_new_pos)) 144 print(("x pos real: %s\n" % x_real_pos)) 145 print(("y pos rot: %s" % y_new_pos)) 146 print(("y pos real: %s\n" % y_real_pos)) 147 print(("z pos rot: %s" % z_new_pos)) 148 print(("z pos real: %s\n" % z_real_pos)) 149 150 print(("x neg rot: %s" % x_new_neg)) 151 print(("x neg real: %s\n" % x_real_neg)) 152 print(("y neg rot: %s" % y_new_neg)) 153 print(("y neg real: %s\n" % y_real_neg)) 154 print(("z neg rot: %s" % z_new_neg)) 155 print(("z neg real: %s\n" % z_real_neg)) 156 157 # Checks. 158 for i in range(3): 159 self.assertAlmostEqual(x_new_pos[i], x_real_pos[i]) 160 self.assertAlmostEqual(y_new_pos[i], y_real_pos[i]) 161 self.assertAlmostEqual(z_new_pos[i], z_real_pos[i]) 162 163 self.assertAlmostEqual(x_new_neg[i], x_real_neg[i]) 164 self.assertAlmostEqual(y_new_neg[i], y_real_neg[i]) 165 self.assertAlmostEqual(z_new_neg[i], z_real_neg[i])
166 167
169 """Test the quaternion to rotation matrix conversion for a zero angle rotation.""" 170 171 # Quaternion of zero angle. 172 axis = array([-1, 1, 1], float64) / sqrt(3) 173 angle = 0.0 174 175 # The rotation matrix. 176 axis_angle_to_R(axis, angle, R) 177 print("Rotation matrix:\n%s" % R) 178 179 # The correct result. 180 R_true = eye(3) 181 182 # Checks. 183 for i in range(3): 184 for j in range(3): 185 self.assertEqual(R[i, j], R_true[i, j])
186 187
189 """Test the axis-angle to quaternion conversion for a zero angle rotation.""" 190 191 # Random axis and zero angle. 192 axis = array([-1, 1, 1], float64) / sqrt(3) 193 angle = 0.0 194 195 # The quaternion matrix. 196 quat = zeros(4, float64) 197 axis_angle_to_quaternion(axis, angle, quat) 198 print("Quaternion:\n%s" % quat) 199 200 # The correct result. 201 quat_true = array([1, 0, 0, 0], float64) 202 203 # Checks. 204 for i in range(4): 205 self.assertEqual(quat[i], quat_true[i])
206 207
209 """Test the axis-angle to quaternion conversion for a 180 degree rotation about [1, 1, 1].""" 210 211 # Random axis and zero angle. 212 axis = array([1, 1, 1], float64) / sqrt(3) 213 angle = pi 214 215 # The quaternion matrix. 216 quat = zeros(4, float64) 217 axis_angle_to_quaternion(axis, angle, quat) 218 print("Quaternion:\n%s" % quat) 219 220 # The correct result. 221 quat_true = array([0, 1, 1, 1], float64) / sqrt(3) 222 223 # Checks. 224 for i in range(4): 225 self.assertAlmostEqual(quat[i], quat_true[i])
226 227
228 - def test_axis_angle_to_R_z_30(self):
229 """Test the quaternion to rotation matrix conversion for a 30 degree rotation about z.""" 230 231 # Axis-angle values. 232 axis = array([0, 0, 1], float64) 233 angle = pi / 6 234 235 # Generate the rotation matrix. 236 axis_angle_to_R(axis, angle, R) 237 print("Rotation matrix:\n%s" % R) 238 239 # Rotated pos_axes (real values). 240 x_real_pos = array([cos(pi/6), sin(pi/6), 0], float64) 241 y_real_pos = array([-sin(pi/6), cos(pi/6), 0], float64) 242 z_real_pos = array([0, 0, 1], float64) 243 244 # Rotated neg axes (real values). 245 x_real_neg = array([-cos(pi/6), -sin(pi/6), 0], float64) 246 y_real_neg = array([sin(pi/6), -cos(pi/6), 0], float64) 247 z_real_neg = array([0, 0, -1], float64) 248 249 # Check the rotation. 250 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
251 252
254 """Test the quaternion to rotation matrix conversion for a 180 degree rotation about [1, 1, 1].""" 255 256 # Axis-angle values. 257 axis = array([1, 1, 1], float64) / sqrt(3) 258 angle = 2 * pi / 3 259 260 # Generate the rotation matrix. 261 axis_angle_to_R(axis, angle, R) 262 print("Rotation matrix:\n%s" % R) 263 264 # Rotated pos axes (real values). 265 x_real_pos = array([0, 1, 0], float64) 266 y_real_pos = array([0, 0, 1], float64) 267 z_real_pos = array([1, 0, 0], float64) 268 269 # Rotated neg axes (real values). 270 x_real_neg = array([0, -1, 0], float64) 271 y_real_neg = array([0, 0, -1], float64) 272 z_real_neg = array([-1, 0, 0], float64) 273 274 # Check the rotation. 275 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
276 277
278 - def test_euler_cycle_1(self):
279 """Cycle through all the hard-coded conversion functions returning to the starting point. 280 281 The nested cycling is as follows: 282 - start with random Euler angles alpha, beta, gamma, 283 - convert to a rotation matrix using euler_to_R_xyx(), 284 - xyx cycle: 285 - R_to_euler_xyx() 286 - euler_to_R_xyx(), 287 - R_to_axis_angle(), 288 - axis_angle_to_euler_xyx(), 289 - euler_to_axis_angle_xyx(), 290 - axis_angle_to_R(), 291 - xyz cycle: 292 - R_to_euler_xyz() 293 - euler_to_R_xyz(), 294 - R_to_axis_angle(), 295 - axis_angle_to_euler_xyz(), 296 - euler_to_axis_angle_xyz(), 297 - axis_angle_to_R(), 298 - xzx cycle: 299 - R_to_euler_xzx() 300 - euler_to_R_xzx(), 301 - R_to_axis_angle(), 302 - axis_angle_to_euler_xzx(), 303 - euler_to_axis_angle_xzx(), 304 - axis_angle_to_R(), 305 - xzy cycle: 306 - R_to_euler_xzy() 307 - euler_to_R_xzy(), 308 - R_to_axis_angle(), 309 - axis_angle_to_euler_xzy(), 310 - euler_to_axis_angle_xzy(), 311 - axis_angle_to_R(), 312 - yxy cycle: 313 - R_to_euler_yxy() 314 - euler_to_R_yxy(), 315 - R_to_axis_angle(), 316 - axis_angle_to_euler_yxy(), 317 - euler_to_axis_angle_yxy(), 318 - axis_angle_to_R(), 319 - yxz cycle: 320 - R_to_euler_yxz() 321 - euler_to_R_yxz(), 322 - R_to_axis_angle(), 323 - axis_angle_to_euler_yxz(), 324 - euler_to_axis_angle_yxz(), 325 - axis_angle_to_R(), 326 - yzx cycle: 327 - R_to_euler_yzx() 328 - euler_to_R_yzx(), 329 - R_to_axis_angle(), 330 - axis_angle_to_euler_yzx(), 331 - euler_to_axis_angle_yzx(), 332 - axis_angle_to_R(), 333 - yzy cycle: 334 - R_to_euler_yzy() 335 - euler_to_R_yzy(), 336 - R_to_axis_angle(), 337 - axis_angle_to_euler_yzy(), 338 - euler_to_axis_angle_yzy(), 339 - axis_angle_to_R(), 340 - zxy cycle: 341 - R_to_euler_zxy() 342 - euler_to_R_zxy(), 343 - R_to_axis_angle(), 344 - axis_angle_to_euler_zxy(), 345 - euler_to_axis_angle_zxy(), 346 - axis_angle_to_R(), 347 - zxz cycle: 348 - R_to_euler_zxz() 349 - euler_to_R_zxz(), 350 - R_to_axis_angle(), 351 - axis_angle_to_euler_zxz(), 352 - euler_to_axis_angle_zxz(), 353 - axis_angle_to_R(), 354 - zyx cycle: 355 - R_to_euler_zyx() 356 - euler_to_R_zyx(), 357 - R_to_axis_angle(), 358 - axis_angle_to_euler_zyx(), 359 - euler_to_axis_angle_zyx(), 360 - axis_angle_to_R(), 361 - zyz cycle: 362 - R_to_euler_zyz() 363 - euler_to_R_zyz(), 364 - R_to_axis_angle(), 365 - axis_angle_to_euler_zyz(), 366 - euler_to_axis_angle_zyz(), 367 - axis_angle_to_R(), 368 - return to start with R_to_euler_xyx(). 369 """ 370 371 # Starting angles. 372 alpha_init = uniform(0, 2*pi) 373 beta_init = uniform(0, pi) 374 gamma_init = uniform(0, 2*pi) 375 376 # The start point. 377 euler_to_R_xyx(alpha_init, beta_init, gamma_init, R) 378 euler_to_R_xyx(alpha_init, beta_init, gamma_init, R2) 379 380 # Print out. 381 print("Original data:") 382 print(("alpha: %s" % alpha_init)) 383 print(("beta: %s" % beta_init)) 384 print(("gamma: %s\n" % gamma_init)) 385 print(("R:\n%s\n" % R2)) 386 387 # The different notations. 388 sets = ['xyx', 'xyz', 'xzx', 'xzy', 'yxy', 'yxz', 'yzx', 'yzy', 'zxy', 'zxz', 'zyx', 'zyz'] 389 shuffle(sets) 390 391 # Cycle over the notations. 392 for set in sets: 393 # Header printout. 394 print("\n\n# %s cycle.\n" % set) 395 396 # Alias the functions. 397 axis_angle_to_euler = globals()['axis_angle_to_euler_'+set] 398 euler_to_axis_angle = globals()['euler_to_axis_angle_'+set] 399 euler_to_R = globals()['euler_to_R_'+set] 400 R_to_euler = globals()['R_to_euler_'+set] 401 402 # R -> Euler. 403 a, b, g = R_to_euler(R) 404 print("R -> Euler: [%-8.5f, %-8.5f, %-8.5f]\n" % (a, b, g)) 405 406 # Euler -> R 407 euler_to_R(a, b, g, R) 408 print(("Euler -> R:\n%s\n" % R)) 409 410 # R -> axis, angle. 411 axis, angle = R_to_axis_angle(R) 412 print("R -> axis, angle: [%-8.5f, %-8.5f, %-8.5f], %s\n" % (axis[0], axis[1], axis[2], angle)) 413 414 # axis, angle -> Euler. 415 a, b, g = axis_angle_to_euler(axis, angle) 416 print("axis, angle -> Euler: [%-8.5f, %-8.5f, %-8.5f]\n" % (a, b, g)) 417 418 # Euler -> axis, angle. 419 axis, angle = euler_to_axis_angle(a, b, g) 420 print("Euler -> axis, angle: [%-8.5f, %-8.5f, %-8.5f], %s\n" % (axis[0], axis[1], axis[2], angle)) 421 422 # axis, angle -> R. 423 axis_angle_to_R(axis, angle, R) 424 print(("axis, angle -> R:\n%s\n" % R)) 425 426 # Print out the rotation matrix. 427 print("Rotation matrix difference:\n%s\n" % (R2-R)) 428 429 # Check the rotation matrix. 430 for i in range(3): 431 for j in range(3): 432 self.assertAlmostEqual(R[i, j], R2[i, j]) 433 434 # The end point. 435 alpha_end, beta_end, gamma_end = R_to_euler_xyx(R) 436 437 # Print out. 438 print("End data:") 439 print(("alpha: %s" % alpha_end)) 440 print(("beta: %s" % beta_end)) 441 print(("gamma: %s\n" % gamma_end)) 442 print(("R:\n%s\n" % R)) 443 444 # Checks. 445 self.assertAlmostEqual(alpha_init, alpha_end) 446 self.assertAlmostEqual(beta_init, beta_end) 447 self.assertAlmostEqual(gamma_init, gamma_end)
448 449
451 """Bounce around all the conversion functions to see if the original angles are returned.""" 452 453 # Starting angles. 454 alpha = uniform(0, 2*pi) 455 beta = uniform(0, pi) 456 gamma = uniform(0, 2*pi) 457 458 # Print out. 459 print("Original angles:") 460 print(("alpha: %s" % alpha)) 461 print(("beta: %s" % beta)) 462 print(("gamma: %s\n" % gamma)) 463 464 # Init. 465 axis = zeros(3, float64) 466 quat = zeros(4, float64) 467 468 # 1) Euler angles to rotation matrix. 469 euler_to_R_zyz(alpha, beta, gamma, R) 470 471 # 2) Rotation matrix to axis-angle. 472 axis, angle = R_to_axis_angle(R) 473 474 # 3) Axis-angle to quaternion. 475 axis_angle_to_quaternion(axis, angle, quat) 476 477 # 4) Quaternion to axis-angle. 478 axis, angle = quaternion_to_axis_angle(quat) 479 480 # 5) Axis-angle to rotation matrix. 481 axis_angle_to_R(axis, angle, R) 482 483 # 6) Rotation matrix to quaternion. 484 R_to_quaternion(R, quat) 485 486 # 7) Quaternion to rotation matrix. 487 quaternion_to_R(quat, R) 488 489 # 8) Rotation matrix to Euler angles. 490 alpha_new, beta_new, gamma_new = R_to_euler_zyz(R) 491 492 # 9) Euler angles to axis-angle. 493 axis, angle = euler_to_axis_angle_zyz(alpha_new, beta_new, gamma_new) 494 495 # 10) Axis-angle to Euler angles. 496 alpha_new, beta_new, gamma_new = axis_angle_to_euler_zyz(axis, angle) 497 498 # Wrap the angles. 499 alpha_new = wrap_angles(alpha_new, 0, 2*pi) 500 beta_new = wrap_angles(beta_new, 0, 2*pi) 501 gamma_new = wrap_angles(gamma_new, 0, 2*pi) 502 503 # Print out. 504 print("New angles:") 505 print(("alpha: %s" % alpha_new)) 506 print(("beta: %s" % beta_new)) 507 print(("gamma: %s\n" % gamma_new)) 508 509 # Checks. 510 self.assertAlmostEqual(alpha, alpha_new) 511 self.assertAlmostEqual(beta, beta_new) 512 self.assertAlmostEqual(gamma, gamma_new)
513 514
516 """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" 517 518 # Generate the rotation matrix. 519 euler_to_R_zyz(pi/6, 0.0, 0.0, R) 520 521 # Rotated pos axes (real values). 522 x_real_pos = array([cos(pi/6), sin(pi/6), 0], float64) 523 y_real_pos = array([-sin(pi/6), cos(pi/6), 0], float64) 524 z_real_pos = array([0, 0, 1], float64) 525 526 # Rotated neg axes (real values). 527 x_real_neg = array([-cos(pi/6), -sin(pi/6), 0], float64) 528 y_real_neg = array([sin(pi/6), -cos(pi/6), 0], float64) 529 z_real_neg = array([0, 0, -1], float64) 530 531 # Check the rotation. 532 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
533 534
536 """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" 537 538 # Generate the rotation matrix. 539 euler_to_R_zyz(0.0, pi/4, 0.0, R) 540 541 # Rotated pos axes (real values). 542 x_real_pos = array([cos(pi/4), 0, -sin(pi/4)], float64) 543 y_real_pos = array([0, 1, 0], float64) 544 z_real_pos = array([sin(pi/4), 0, cos(pi/4)], float64) 545 546 # Rotated neg axes (real values). 547 x_real_neg = array([-cos(pi/4), 0, sin(pi/4)], float64) 548 y_real_neg = array([0, -1, 0], float64) 549 z_real_neg = array([-sin(pi/4), 0, -cos(pi/4)], float64) 550 551 # Check the rotation. 552 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
553 554
556 """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" 557 558 # Generate the rotation matrix. 559 euler_to_R_zyz(0.0, 0.0, pi/12, R) 560 561 # Rotated pos axes (real values). 562 x_real_pos = array([cos(pi/12), sin(pi/12), 0], float64) 563 y_real_pos = array([-sin(pi/12), cos(pi/12), 0], float64) 564 z_real_pos = array([0, 0, 1], float64) 565 566 # Rotated neg axes (real values). 567 x_real_neg = array([-cos(pi/12), -sin(pi/12), 0], float64) 568 y_real_neg = array([sin(pi/12), -cos(pi/12), 0], float64) 569 z_real_neg = array([0, 0, -1], float64) 570 571 # Check the rotation. 572 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
573 574
576 """Test the rotation matrix from zyz Euler angle conversion using a beta angle of pi/4.""" 577 578 # Generate the rotation matrix. 579 euler_to_R_zyz(pi/12, 0.0, pi/12, R) 580 581 # Rotated pos axes (real values). 582 x_real_pos = array([cos(pi/6), sin(pi/6), 0], float64) 583 y_real_pos = array([-sin(pi/6), cos(pi/6), 0], float64) 584 z_real_pos = array([0, 0, 1], float64) 585 586 # Rotated neg axes (real values). 587 x_real_neg = array([-cos(pi/6), -sin(pi/6), 0], float64) 588 y_real_neg = array([sin(pi/6), -cos(pi/6), 0], float64) 589 z_real_neg = array([0, 0, -1], float64) 590 591 # Check the rotation. 592 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
593 594
596 """Test the rotation matrix to axis-angle conversion.""" 597 598 # Generate the rotation matrix. 599 R = array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], float64) 600 601 # Get the axis and angle. 602 axis, angle = R_to_axis_angle(R) 603 604 # Test the angle. 605 self.assertEqual(angle, 0.0)
606 607
609 """Test the rotation matrix to axis-angle conversion.""" 610 611 # Generate the rotation matrix. 612 R = array([[0, 0, 1], [1, 0, 0], [0, 1, 0]], float64) 613 614 # Get the axis and angle. 615 axis, angle = R_to_axis_angle(R) 616 617 # Test the angle. 618 self.assertAlmostEqual(angle, 2 * pi / 3) 619 620 # Test the vector. 621 for i in range(3): 622 self.assertAlmostEqual(axis[i], 1.0/sqrt(3))
623 624
625 - def test_R_to_euler_to_R_xyx(self):
626 """Test the rotation matrix to xyx Euler angle conversion and back again.""" 627 628 # Random rotation matrix. 629 R_random_hypersphere(R) 630 R_orig = deepcopy(R) 631 632 # Convert. 633 a, b, g = R_to_euler_xyx(R) 634 euler_to_R_xyx(a, b, g, R2) 635 636 # Check the rotation matrix. 637 for i in range(3): 638 for j in range(3): 639 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
640 641
642 - def test_R_to_euler_to_R_xyz(self):
643 """Test the rotation matrix to xyz Euler angle conversion and back again.""" 644 645 # Random rotation matrix. 646 R_random_hypersphere(R) 647 R_orig = deepcopy(R) 648 649 # Convert. 650 a, b, g = R_to_euler_xyz(R) 651 euler_to_R_xyz(a, b, g, R2) 652 653 # Check the rotation matrix. 654 for i in range(3): 655 for j in range(3): 656 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
657 658
659 - def test_R_to_euler_to_R_xzx(self):
660 """Test the rotation matrix to xzx Euler angle conversion and back again.""" 661 662 # Random rotation matrix. 663 R_random_hypersphere(R) 664 R_orig = deepcopy(R) 665 666 # Convert. 667 a, b, g = R_to_euler_xzx(R) 668 euler_to_R_xzx(a, b, g, R2) 669 670 # Check the rotation matrix. 671 for i in range(3): 672 for j in range(3): 673 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
674 675
676 - def test_R_to_euler_to_R_xzy(self):
677 """Test the rotation matrix to xzy Euler angle conversion and back again.""" 678 679 # Random rotation matrix. 680 R_random_hypersphere(R) 681 R_orig = deepcopy(R) 682 683 # Convert. 684 a, b, g = R_to_euler_xzy(R) 685 euler_to_R_xzy(a, b, g, R2) 686 687 # Check the rotation matrix. 688 for i in range(3): 689 for j in range(3): 690 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
691 692
693 - def test_R_to_euler_to_R_yxy(self):
694 """Test the rotation matrix to yxy Euler angle conversion and back again.""" 695 696 # Random rotation matrix. 697 R_random_hypersphere(R) 698 R_orig = deepcopy(R) 699 700 # Convert. 701 a, b, g = R_to_euler_yxy(R) 702 euler_to_R_yxy(a, b, g, R2) 703 704 # Check the rotation matrix. 705 for i in range(3): 706 for j in range(3): 707 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
708 709
710 - def test_R_to_euler_to_R_yxz(self):
711 """Test the rotation matrix to yxz Euler angle conversion and back again.""" 712 713 # Random rotation matrix. 714 R_random_hypersphere(R) 715 R_orig = deepcopy(R) 716 717 # Convert. 718 a, b, g = R_to_euler_yxz(R) 719 euler_to_R_yxz(a, b, g, R2) 720 721 # Check the rotation matrix. 722 for i in range(3): 723 for j in range(3): 724 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
725 726
727 - def test_R_to_euler_to_R_yzx(self):
728 """Test the rotation matrix to yzx Euler angle conversion and back again.""" 729 730 # Random rotation matrix. 731 R_random_hypersphere(R) 732 R_orig = deepcopy(R) 733 734 # Convert. 735 a, b, g = R_to_euler_yzx(R) 736 euler_to_R_yzx(a, b, g, R2) 737 738 # Check the rotation matrix. 739 for i in range(3): 740 for j in range(3): 741 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
742 743
744 - def test_R_to_euler_to_R_yzy(self):
745 """Test the rotation matrix to yzy Euler angle conversion and back again.""" 746 747 # Random rotation matrix. 748 R_random_hypersphere(R) 749 R_orig = deepcopy(R) 750 751 # Convert. 752 a, b, g = R_to_euler_yzy(R) 753 euler_to_R_yzy(a, b, g, R2) 754 755 # Check the rotation matrix. 756 for i in range(3): 757 for j in range(3): 758 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
759 760
761 - def test_R_to_euler_to_R_zxy(self):
762 """Test the rotation matrix to zxy Euler angle conversion and back again.""" 763 764 # Random rotation matrix. 765 R_random_hypersphere(R) 766 R_orig = deepcopy(R) 767 768 # Convert. 769 a, b, g = R_to_euler_zxy(R) 770 euler_to_R_zxy(a, b, g, R2) 771 772 # Check the rotation matrix. 773 for i in range(3): 774 for j in range(3): 775 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
776 777
778 - def test_R_to_euler_to_R_zxz(self):
779 """Test the rotation matrix to zxz Euler angle conversion and back again.""" 780 781 # Random rotation matrix. 782 R_random_hypersphere(R) 783 R_orig = deepcopy(R) 784 785 # Convert. 786 a, b, g = R_to_euler_zxz(R) 787 euler_to_R_zxz(a, b, g, R2) 788 789 # Check the rotation matrix. 790 for i in range(3): 791 for j in range(3): 792 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
793 794
795 - def test_R_to_euler_to_R_zyx(self):
796 """Test the rotation matrix to zyx Euler angle conversion and back again.""" 797 798 # Random rotation matrix. 799 R_random_hypersphere(R) 800 R_orig = deepcopy(R) 801 802 # Convert. 803 a, b, g = R_to_euler_zyx(R) 804 euler_to_R_zyx(a, b, g, R2) 805 806 # Check the rotation matrix. 807 for i in range(3): 808 for j in range(3): 809 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
810 811
812 - def test_R_to_euler_to_R_zyz(self):
813 """Test the rotation matrix to zyz Euler angle conversion and back again.""" 814 815 # Random rotation matrix. 816 R_random_hypersphere(R) 817 R_orig = deepcopy(R) 818 819 # Convert. 820 a, b, g = R_to_euler_zyz(R) 821 euler_to_R_zyz(a, b, g, R2) 822 823 # Check the rotation matrix. 824 for i in range(3): 825 for j in range(3): 826 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
827 828
829 - def test_R_to_euler_xyx(self):
830 """Test the rotation matrix to xyx Euler angle conversion.""" 831 832 # Check random numbers, then the problematic angles. 833 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 834 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 0.0, 0.0, 0.0) 835 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 1.0, 0.0, 0.0) 836 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 0.0, 1.0, 0.0) 837 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 0.0, 0.0, 1.0, alpha_end=1.0, gamma_end=0.0) 838 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 1.0, 1.0, 0.0) 839 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 0.0, 1.0, 1.0) 840 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 1.0, 0.0, 1.0, alpha_end=2.0, gamma_end=0.0) 841 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 1.0, 1.0, 1.0) 842 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 1.0, pi/2, 0.5) 843 self.check_return_conversion(euler_to_R_xyx, R_to_euler_xyx, 1.0, pi, 0.5, alpha_end=0.5, gamma_end=0.0)
844 845
846 - def test_R_to_euler_xyz(self):
847 """Test the rotation matrix to xyz Euler angle conversion.""" 848 849 # Check random numbers, then the problematic angles. 850 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 851 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 0.0, 0.0, 0.0) 852 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 1.0, 0.0, 0.0) 853 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 0.0, 1.0, 0.0) 854 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 0.0, 0.0, 1.0) 855 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 1.0, 1.0, 0.0) 856 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 0.0, 1.0, 1.0) 857 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 1.0, 0.0, 1.0) 858 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 1.0, 1.0, 1.0) 859 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 1.0, pi/2, 0.5, alpha_end=0.5, gamma_end=0.0) 860 self.check_return_conversion(euler_to_R_xyz, R_to_euler_xyz, 1.0, pi, 0.5)
861 862
863 - def test_R_to_euler_xzx(self):
864 """Test the rotation matrix to xzx Euler angle conversion.""" 865 866 # Check random numbers, then the problematic angles. 867 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 868 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 0.0, 0.0, 0.0) 869 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 1.0, 0.0, 0.0) 870 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 0.0, 1.0, 0.0) 871 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 0.0, 0.0, 1.0, alpha_end=1.0, gamma_end=0.0) 872 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 1.0, 1.0, 0.0) 873 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 0.0, 1.0, 1.0) 874 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 1.0, 0.0, 1.0, alpha_end=2.0, gamma_end=0.0) 875 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 1.0, 1.0, 1.0) 876 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 1.0, pi/2, 0.5) 877 self.check_return_conversion(euler_to_R_xzx, R_to_euler_xzx, 1.0, pi, 0.5, alpha_end=0.5, gamma_end=0.0)
878 879
880 - def test_R_to_euler_xzy(self):
881 """Test the rotation matrix to xzy Euler angle conversion.""" 882 883 # Check random numbers, then the problematic angles. 884 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 885 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 0.0, 0.0, 0.0) 886 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 1.0, 0.0, 0.0) 887 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 0.0, 1.0, 0.0) 888 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 0.0, 0.0, 1.0) 889 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 1.0, 1.0, 0.0) 890 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 0.0, 1.0, 1.0) 891 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 1.0, 0.0, 1.0) 892 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 1.0, 1.0, 1.0) 893 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 1.0, pi/2, 0.5, alpha_end=1.5, gamma_end=0.0) 894 self.check_return_conversion(euler_to_R_xzy, R_to_euler_xzy, 1.0, pi, 0.5)
895 896
897 - def test_R_to_euler_yxy(self):
898 """Test the rotation matrix to yxy Euler angle conversion.""" 899 900 # Check random numbers, then the problematic angles. 901 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 902 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 0.0, 0.0, 0.0) 903 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 1.0, 0.0, 0.0) 904 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 0.0, 1.0, 0.0) 905 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 0.0, 0.0, 1.0, alpha_end=1.0, gamma_end=0.0) 906 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 1.0, 1.0, 0.0) 907 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 0.0, 1.0, 1.0) 908 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 1.0, 0.0, 1.0, alpha_end=2.0, gamma_end=0.0) 909 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 1.0, 1.0, 1.0) 910 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 1.0, pi/2, 0.5) 911 self.check_return_conversion(euler_to_R_yxy, R_to_euler_yxy, 1.0, pi, 0.5, alpha_end=0.5, gamma_end=0.0)
912 913
914 - def test_R_to_euler_yxz(self):
915 """Test the rotation matrix to yxz Euler angle conversion.""" 916 917 # Check random numbers, then the problematic angles. 918 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 919 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 0.0, 0.0, 0.0) 920 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 1.0, 0.0, 0.0) 921 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 0.0, 1.0, 0.0) 922 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 0.0, 0.0, 1.0) 923 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 1.0, 1.0, 0.0) 924 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 0.0, 1.0, 1.0) 925 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 1.0, 0.0, 1.0) 926 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 1.0, 1.0, 1.0) 927 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 1.0, pi/2, 0.5, alpha_end=1.5, gamma_end=0.0) 928 self.check_return_conversion(euler_to_R_yxz, R_to_euler_yxz, 1.0, pi, 0.5)
929 930
931 - def test_R_to_euler_yzx(self):
932 """Test the rotation matrix to yzx Euler angle conversion.""" 933 934 # Check random numbers, then the problematic angles. 935 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 936 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 0.0, 0.0, 0.0) 937 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 1.0, 0.0, 0.0) 938 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 0.0, 1.0, 0.0) 939 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 0.0, 0.0, 1.0) 940 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 1.0, 1.0, 0.0) 941 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 0.0, 1.0, 1.0) 942 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 1.0, 0.0, 1.0) 943 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 1.0, 1.0, 1.0) 944 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 1.0, pi/2, 0.5, alpha_end=0.5, gamma_end=0.0) 945 self.check_return_conversion(euler_to_R_yzx, R_to_euler_yzx, 1.0, pi, 0.5)
946 947
948 - def test_R_to_euler_yzy(self):
949 """Test the rotation matrix to yzy Euler angle conversion.""" 950 951 # Check random numbers, then the problematic angles. 952 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 953 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 0.0, 0.0, 0.0) 954 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 1.0, 0.0, 0.0) 955 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 0.0, 1.0, 0.0) 956 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 0.0, 0.0, 1.0, alpha_end=1.0, gamma_end=0.0) 957 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 1.0, 1.0, 0.0) 958 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 0.0, 1.0, 1.0) 959 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 1.0, 0.0, 1.0, alpha_end=2.0, gamma_end=0.0) 960 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 1.0, 1.0, 1.0) 961 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 1.0, pi/2, 0.5) 962 self.check_return_conversion(euler_to_R_yzy, R_to_euler_yzy, 1.0, pi, 0.5, alpha_end=0.5, gamma_end=0.0)
963 964
965 - def test_R_to_euler_zxy(self):
966 """Test the rotation matrix to zxy Euler angle conversion.""" 967 968 # Check random numbers, then the problematic angles. 969 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 970 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 0.0, 0.0, 0.0) 971 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 1.0, 0.0, 0.0) 972 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 0.0, 1.0, 0.0) 973 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 0.0, 0.0, 1.0) 974 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 1.0, 1.0, 0.0) 975 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 0.0, 1.0, 1.0) 976 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 1.0, 0.0, 1.0) 977 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 1.0, 1.0, 1.0) 978 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 1.0, pi/2, 0.5, alpha_end=0.5, gamma_end=0.0) 979 self.check_return_conversion(euler_to_R_zxy, R_to_euler_zxy, 1.0, pi, 0.5)
980 981
982 - def test_R_to_euler_zxz(self):
983 """Test the rotation matrix to zxz Euler angle conversion.""" 984 985 # Check random numbers, then the problematic angles. 986 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 987 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 0.0, 0.0, 0.0) 988 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 1.0, 0.0, 0.0) 989 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 0.0, 1.0, 0.0) 990 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 0.0, 0.0, 1.0, alpha_end=1.0, gamma_end=0.0) 991 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 1.0, 1.0, 0.0) 992 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 0.0, 1.0, 1.0) 993 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 1.0, 0.0, 1.0, alpha_end=2.0, gamma_end=0.0) 994 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 1.0, 1.0, 1.0) 995 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 1.0, pi/2, 0.5) 996 self.check_return_conversion(euler_to_R_zxz, R_to_euler_zxz, 1.0, pi, 0.5, alpha_end=0.5, gamma_end=0.0)
997 998
999 - def test_R_to_euler_zyx(self):
1000 """Test the rotation matrix to zyx Euler angle conversion.""" 1001 1002 # Check random numbers, then the problematic angles. 1003 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 5.0, 2.0, 1.0) 1004 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 1005 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 0.0, 0.0, 0.0) 1006 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 1.0, 0.0, 0.0) 1007 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 0.0, 1.0, 0.0) 1008 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 0.0, 0.0, 1.0) 1009 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 1.0, 1.0, 0.0) 1010 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 0.0, 1.0, 1.0) 1011 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 1.0, 0.0, 1.0) 1012 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 1.0, 1.0, 1.0) 1013 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 1.0, pi/2, 0.5, alpha_end=1.5, gamma_end=0.0) 1014 self.check_return_conversion(euler_to_R_zyx, R_to_euler_zyx, 1.0, pi, 0.5, alpha_end=1.0+pi, beta_end=0.0, gamma_end=0.5+pi)
1015 1016
1017 - def test_R_to_euler_zyz(self):
1018 """Test the rotation matrix to zyz Euler angle conversion.""" 1019 1020 # Check random numbers, then the problematic angles. 1021 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, uniform(0, 2*pi), uniform(0, pi), uniform(0, 2*pi)) 1022 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 0.0, 0.0, 0.0) 1023 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 1.0, 0.0, 0.0) 1024 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 0.0, 1.0, 0.0) 1025 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 0.0, 0.0, 1.0, alpha_end=1.0, gamma_end=0.0) 1026 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 1.0, 1.0, 0.0) 1027 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 0.0, 1.0, 1.0) 1028 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 1.0, 0.0, 1.0, alpha_end=2.0, gamma_end=0.0) 1029 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 1.0, 1.0, 1.0) 1030 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 1.0, pi/2, 0.5) 1031 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 1.0, pi, 0.5, alpha_end=0.5, gamma_end=0.0) 1032 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 1.0, -pi/2, 0.5, alpha_end=1.0+pi, beta_end=pi/2, gamma_end=0.5+pi) 1033 self.check_return_conversion(euler_to_R_zyz, R_to_euler_zyz, 1.0, 1.5*pi, 0.5, alpha_end=1.0+pi, beta_end=pi/2, gamma_end=0.5+pi)
1034 1035
1037 """Test the rotation matrix to quaternion conversion for a zero angle rotation.""" 1038 1039 # Generate the rotation matrix. 1040 R = array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], float64) 1041 1042 # The quaternion. 1043 quat = zeros(4, float64) 1044 R_to_quaternion(R, quat) 1045 print("Quaternion:\n%s" % quat) 1046 1047 # The correct result. 1048 quat_true = array([1, 0, 0, 0], float64) 1049 1050 # Checks. 1051 self.assertEqual(norm(quat), 1) 1052 for i in range(4): 1053 self.assertAlmostEqual(quat[i], quat_true[i])
1054 1055
1057 """Test the rotation matrix to quaternion conversion for a 180 degree rotation about [1, 1, 1].""" 1058 1059 # Generate the rotation matrix. 1060 R = array([[0, 0, 1], [1, 0, 0], [0, 1, 0]], float64) 1061 1062 # The quaternion. 1063 quat = zeros(4, float64) 1064 R_to_quaternion(R, quat) 1065 print("Quaternion:\n%s" % quat) 1066 1067 # The correct result. 1068 quat_true = array([1, 1, 1, 1], float64) / 2 1069 1070 # Checks. 1071 self.assertEqual(norm(quat), 1) 1072 for i in range(4): 1073 self.assertAlmostEqual(quat[i], quat_true[i])
1074 1075
1077 """Test the reverse Euler angle conversion for {0, 0, 0}.""" 1078 1079 # The forward angles. 1080 euler = [0.0, 0.0, 0.0] 1081 1082 # Convert twice. 1083 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1084 a, b, g = reverse_euler_zyz(a, b, g) 1085 1086 # Check the reversed, reverse angles. 1087 self.assertAlmostEqual(a, euler[0]) 1088 self.assertAlmostEqual(b, euler[1]) 1089 self.assertAlmostEqual(g, euler[2])
1090 1091
1093 """Test the reverse Euler angle conversion for {1, 0, 0}.""" 1094 1095 # The forward angles. 1096 euler = [1.0, 0.0, 0.0] 1097 1098 # Convert twice. 1099 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1100 a, b, g = reverse_euler_zyz(a, b, g) 1101 1102 # Check the reversed, reverse angles. 1103 self.assertAlmostEqual(a, euler[0]) 1104 self.assertAlmostEqual(b, euler[1]) 1105 self.assertAlmostEqual(g, euler[2])
1106 1107
1109 """Test the reverse Euler angle conversion for {0, 1, 0}.""" 1110 1111 # The forward angles. 1112 euler = [0.0, 1.0, 0.0] 1113 1114 # Convert twice. 1115 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1116 a, b, g = reverse_euler_zyz(a, b, g) 1117 1118 # Check the reversed, reverse angles. 1119 self.assertAlmostEqual(a, euler[0]) 1120 self.assertAlmostEqual(b, euler[1]) 1121 self.assertAlmostEqual(g, euler[2])
1122 1123
1125 """Test the reverse Euler angle conversion for {0, 0, 1}.""" 1126 1127 # The forward angles. 1128 euler = [0.0, 0.0, 1.0] 1129 1130 # Convert twice. 1131 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1132 a, b, g = reverse_euler_zyz(a, b, g) 1133 1134 # Check the reversed, reverse angles. 1135 self.assertAlmostEqual(a, euler[0]+euler[2]) 1136 self.assertAlmostEqual(b, euler[1]) 1137 self.assertAlmostEqual(g, 0.0)
1138 1139
1141 """Test the reverse Euler angle conversion for {1, 1, 0}.""" 1142 1143 # The forward angles. 1144 euler = [1.0, 1.0, 0.0] 1145 1146 # Convert twice. 1147 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1148 a, b, g = reverse_euler_zyz(a, b, g) 1149 1150 # Check the reversed, reverse angles. 1151 self.assertAlmostEqual(a, euler[0]) 1152 self.assertAlmostEqual(b, euler[1]) 1153 self.assertAlmostEqual(g, euler[2])
1154 1155
1157 """Test the reverse Euler angle conversion for {0, 1, 1}.""" 1158 1159 # The forward angles. 1160 euler = [0.0, 1.0, 1.0] 1161 1162 # Convert twice. 1163 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1164 a, b, g = reverse_euler_zyz(a, b, g) 1165 1166 # Check the reversed, reverse angles. 1167 self.assertAlmostEqual(a, euler[0]) 1168 self.assertAlmostEqual(b, euler[1]) 1169 self.assertAlmostEqual(g, euler[2])
1170 1171
1173 """Test the reverse Euler angle conversion for {1, 0, 1}.""" 1174 1175 # The forward angles. 1176 euler = [1.0, 0.0, 1.0] 1177 1178 # Convert twice. 1179 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1180 a, b, g = reverse_euler_zyz(a, b, g) 1181 1182 # Check the reversed, reverse angles. 1183 self.assertAlmostEqual(a, euler[0]+euler[2]) 1184 self.assertAlmostEqual(b, euler[1]) 1185 self.assertAlmostEqual(g, 0.0)
1186 1187
1189 """Test the reverse Euler angle conversion for {1, 1, 1}.""" 1190 1191 # The forward angles. 1192 euler = [1.0, 1.0, 1.0] 1193 1194 # Convert twice. 1195 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1196 a, b, g = reverse_euler_zyz(a, b, g) 1197 1198 # Check the reversed, reverse angles. 1199 self.assertAlmostEqual(a, euler[0]) 1200 self.assertAlmostEqual(b, euler[1]) 1201 self.assertAlmostEqual(g, euler[2])
1202 1203
1205 """Test the reverse Euler angle conversion for {1, 0.5, 3}.""" 1206 1207 # The forward angles. 1208 euler = [1.0, 0.5, 3.0] 1209 1210 # Convert twice. 1211 a, b, g = reverse_euler_zyz(euler[0], euler[1], euler[2]) 1212 a, b, g = reverse_euler_zyz(a, b, g) 1213 1214 # Check the reversed, reverse angles. 1215 self.assertAlmostEqual(a, euler[0]) 1216 self.assertAlmostEqual(b, euler[1]) 1217 self.assertAlmostEqual(g, euler[2])
1218 1219
1221 """Test the quaternion to rotation matrix conversion for a zero angle rotation.""" 1222 1223 # Quaternion of zero angle. 1224 quat = array([1, 0, 0, 0], float64) 1225 1226 # The axis and angle. 1227 axis, angle = quaternion_to_axis_angle(quat) 1228 print("Axis: %s" % axis) 1229 print("Angle: %s" % angle) 1230 1231 # The correct result. 1232 self.assertEqual(angle, 0.0) 1233 for i in range(3): 1234 self.assertEqual(axis[i], 0.0)
1235 1236
1238 """Test the quaternion to axis-angle conversion for a 180 degree rotation about [1, 1, 1].""" 1239 1240 # The quaternion. 1241 quat = array([0, 1, 1, 1], float64) / sqrt(3) 1242 1243 # The axis and angle. 1244 axis, angle = quaternion_to_axis_angle(quat) 1245 print("Axis: %s" % axis) 1246 print("Angle: %s" % angle) 1247 1248 # The correct result. 1249 self.assertEqual(angle, pi) 1250 for i in range(3): 1251 self.assertEqual(axis[i], 1.0 / sqrt(3))
1252 1253 1254
1256 """Test the quaternion to rotation matrix conversion for a zero angle rotation.""" 1257 1258 # Quaternion of zero angle. 1259 quat = array([1, 0, 0, 0], float64) 1260 1261 # The rotation matrix. 1262 quaternion_to_R(quat, R) 1263 print("Rotation matrix:\n%s" % R) 1264 1265 # The correct result. 1266 R_true = eye(3) 1267 1268 # Checks. 1269 for i in range(3): 1270 for j in range(3): 1271 self.assertEqual(R[i, j], R_true[i, j])
1272 1273
1274 - def test_quaternion_to_R_z_30(self):
1275 """Test the quaternion to rotation matrix conversion for a 30 degree rotation about z.""" 1276 1277 # Axis-angle values. 1278 axis = array([0, 0, 1], float64) 1279 angle = pi / 6 1280 1281 # First element. 1282 w = cos(angle / 2) 1283 1284 # Vector reduction (quaternion normalisation). 1285 factor = sqrt(1 - w**2) 1286 axis = axis * factor 1287 1288 # Quaternion. 1289 quat = zeros(4, float64) 1290 quat[0] = w 1291 quat[1:] = axis 1292 print("Quat: %s" % quat) 1293 print("Quat norm: %s" % norm(quat)) 1294 1295 # Quaternion check. 1296 w_check = cos(asin(sqrt(quat[1]**2 + quat[2]**2 + quat[3]**2))) 1297 self.assertEqual(w, w_check) 1298 self.assertEqual(norm(quat), 1) 1299 1300 # Generate the rotation matrix. 1301 quaternion_to_R(quat, R) 1302 print("Rotation matrix:\n%s" % R) 1303 1304 # Rotated pos axes (real values). 1305 x_real_pos = array([cos(pi/6), sin(pi/6), 0], float64) 1306 y_real_pos = array([-sin(pi/6), cos(pi/6), 0], float64) 1307 z_real_pos = array([0, 0, 1], float64) 1308 1309 # Rotated neg axes (real values). 1310 x_real_neg = array([-cos(pi/6), -sin(pi/6), 0], float64) 1311 y_real_neg = array([sin(pi/6), -cos(pi/6), 0], float64) 1312 z_real_neg = array([0, 0, -1], float64) 1313 1314 # Check the rotation. 1315 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
1316 1317
1319 """Test the quaternion to rotation matrix conversion for a 180 degree rotation about [1, 1, 1].""" 1320 1321 # Axis-angle values. 1322 axis = array([1, 1, 1], float64) / sqrt(3) 1323 angle = 2 * pi / 3 1324 1325 # First element. 1326 w = cos(angle / 2) 1327 1328 # Vector reduction (quaternion normalisation). 1329 factor = sqrt(1 - w**2) 1330 axis = axis * factor 1331 1332 # Quaternion. 1333 quat = zeros(4, float64) 1334 quat[0] = w 1335 quat[1:] = axis 1336 print("Quat: %s" % quat) 1337 print("Quat norm: %s" % norm(quat)) 1338 1339 # Quaternion check. 1340 w_check = cos(asin(sqrt(quat[1]**2 + quat[2]**2 + quat[3]**2))) 1341 self.assertAlmostEqual(w, w_check) 1342 self.assertEqual(norm(quat), 1) 1343 1344 # Generate the rotation matrix. 1345 quaternion_to_R(quat, R) 1346 print("Rotation matrix:\n%s" % R) 1347 1348 # Rotated pos axes (real values). 1349 x_real_pos = array([0, 1, 0], float64) 1350 y_real_pos = array([0, 0, 1], float64) 1351 z_real_pos = array([1, 0, 0], float64) 1352 1353 # Rotated neg axes (real values). 1354 x_real_neg = array([0, -1, 0], float64) 1355 y_real_neg = array([0, 0, -1], float64) 1356 z_real_neg = array([-1, 0, 0], float64) 1357 1358 # Check the rotation. 1359 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
1360