1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
32 from generic_fns.angles import wrap_angles
33 from maths_fns.rotation_matrix import *
34
35
36
37 R = zeros((3, 3), float64)
38 R2 = zeros((3, 3), float64)
39
40
42 """Unit tests for the maths_fns.rotation_matrix relax module."""
43
45 """Set up data used by the unit tests."""
46
47
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
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
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
66 epsilon = 1e-15
67
68
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
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
83 alpha_new, beta_new, gamma_new = R_to_euler(R)
84
85
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
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
96 print_out = print_out + "New angles (wrapped) (%8.5f, %8.5f, %8.5f)\n" % (alpha_new, beta_new, gamma_new)
97
98
99 if abs(beta_end - beta_new) > 1e-7:
100
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
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
116 print_out = print_out + "New angles (2nd sol) (%8.5f, %8.5f, %8.5f)\n" % (alpha_new, beta_new, gamma_new)
117
118
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
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
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
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
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
172 axis = array([-1, 1, 1], float64) / sqrt(3)
173 angle = 0.0
174
175
176 axis_angle_to_R(axis, angle, R)
177 print("Rotation matrix:\n%s" % R)
178
179
180 R_true = eye(3)
181
182
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
192 axis = array([-1, 1, 1], float64) / sqrt(3)
193 angle = 0.0
194
195
196 quat = zeros(4, float64)
197 axis_angle_to_quaternion(axis, angle, quat)
198 print("Quaternion:\n%s" % quat)
199
200
201 quat_true = array([1, 0, 0, 0], float64)
202
203
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
212 axis = array([1, 1, 1], float64) / sqrt(3)
213 angle = pi
214
215
216 quat = zeros(4, float64)
217 axis_angle_to_quaternion(axis, angle, quat)
218 print("Quaternion:\n%s" % quat)
219
220
221 quat_true = array([0, 1, 1, 1], float64) / sqrt(3)
222
223
224 for i in range(4):
225 self.assertAlmostEqual(quat[i], quat_true[i])
226
227
229 """Test the quaternion to rotation matrix conversion for a 30 degree rotation about z."""
230
231
232 axis = array([0, 0, 1], float64)
233 angle = pi / 6
234
235
236 axis_angle_to_R(axis, angle, R)
237 print("Rotation matrix:\n%s" % R)
238
239
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
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
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
257 axis = array([1, 1, 1], float64) / sqrt(3)
258 angle = 2 * pi / 3
259
260
261 axis_angle_to_R(axis, angle, R)
262 print("Rotation matrix:\n%s" % R)
263
264
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
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
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
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
372 alpha_init = uniform(0, 2*pi)
373 beta_init = uniform(0, pi)
374 gamma_init = uniform(0, 2*pi)
375
376
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
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
388 sets = ['xyx', 'xyz', 'xzx', 'xzy', 'yxy', 'yxz', 'yzx', 'yzy', 'zxy', 'zxz', 'zyx', 'zyz']
389 shuffle(sets)
390
391
392 for set in sets:
393
394 print("\n\n# %s cycle.\n" % set)
395
396
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
403 a, b, g = R_to_euler(R)
404 print("R -> Euler: [%-8.5f, %-8.5f, %-8.5f]\n" % (a, b, g))
405
406
407 euler_to_R(a, b, g, R)
408 print(("Euler -> R:\n%s\n" % R))
409
410
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
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
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
423 axis_angle_to_R(axis, angle, R)
424 print(("axis, angle -> R:\n%s\n" % R))
425
426
427 print("Rotation matrix difference:\n%s\n" % (R2-R))
428
429
430 for i in range(3):
431 for j in range(3):
432 self.assertAlmostEqual(R[i, j], R2[i, j])
433
434
435 alpha_end, beta_end, gamma_end = R_to_euler_xyx(R)
436
437
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
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
454 alpha = uniform(0, 2*pi)
455 beta = uniform(0, pi)
456 gamma = uniform(0, 2*pi)
457
458
459 print("Original angles:")
460 print(("alpha: %s" % alpha))
461 print(("beta: %s" % beta))
462 print(("gamma: %s\n" % gamma))
463
464
465 axis = zeros(3, float64)
466 quat = zeros(4, float64)
467
468
469 euler_to_R_zyz(alpha, beta, gamma, R)
470
471
472 axis, angle = R_to_axis_angle(R)
473
474
475 axis_angle_to_quaternion(axis, angle, quat)
476
477
478 axis, angle = quaternion_to_axis_angle(quat)
479
480
481 axis_angle_to_R(axis, angle, R)
482
483
484 R_to_quaternion(R, quat)
485
486
487 quaternion_to_R(quat, R)
488
489
490 alpha_new, beta_new, gamma_new = R_to_euler_zyz(R)
491
492
493 axis, angle = euler_to_axis_angle_zyz(alpha_new, beta_new, gamma_new)
494
495
496 alpha_new, beta_new, gamma_new = axis_angle_to_euler_zyz(axis, angle)
497
498
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
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
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
519 euler_to_R_zyz(pi/6, 0.0, 0.0, R)
520
521
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
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
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
539 euler_to_R_zyz(0.0, pi/4, 0.0, R)
540
541
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
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
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
559 euler_to_R_zyz(0.0, 0.0, pi/12, R)
560
561
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
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
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
579 euler_to_R_zyz(pi/12, 0.0, pi/12, R)
580
581
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
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
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
599 R = array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], float64)
600
601
602 axis, angle = R_to_axis_angle(R)
603
604
605 self.assertEqual(angle, 0.0)
606
607
609 """Test the rotation matrix to axis-angle conversion."""
610
611
612 R = array([[0, 0, 1], [1, 0, 0], [0, 1, 0]], float64)
613
614
615 axis, angle = R_to_axis_angle(R)
616
617
618 self.assertAlmostEqual(angle, 2 * pi / 3)
619
620
621 for i in range(3):
622 self.assertAlmostEqual(axis[i], 1.0/sqrt(3))
623
624
626 """Test the rotation matrix to xyx Euler angle conversion and back again."""
627
628
629 R_random_hypersphere(R)
630 R_orig = deepcopy(R)
631
632
633 a, b, g = R_to_euler_xyx(R)
634 euler_to_R_xyx(a, b, g, R2)
635
636
637 for i in range(3):
638 for j in range(3):
639 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
640
641
643 """Test the rotation matrix to xyz Euler angle conversion and back again."""
644
645
646 R_random_hypersphere(R)
647 R_orig = deepcopy(R)
648
649
650 a, b, g = R_to_euler_xyz(R)
651 euler_to_R_xyz(a, b, g, R2)
652
653
654 for i in range(3):
655 for j in range(3):
656 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
657
658
660 """Test the rotation matrix to xzx Euler angle conversion and back again."""
661
662
663 R_random_hypersphere(R)
664 R_orig = deepcopy(R)
665
666
667 a, b, g = R_to_euler_xzx(R)
668 euler_to_R_xzx(a, b, g, R2)
669
670
671 for i in range(3):
672 for j in range(3):
673 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
674
675
677 """Test the rotation matrix to xzy Euler angle conversion and back again."""
678
679
680 R_random_hypersphere(R)
681 R_orig = deepcopy(R)
682
683
684 a, b, g = R_to_euler_xzy(R)
685 euler_to_R_xzy(a, b, g, R2)
686
687
688 for i in range(3):
689 for j in range(3):
690 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
691
692
694 """Test the rotation matrix to yxy Euler angle conversion and back again."""
695
696
697 R_random_hypersphere(R)
698 R_orig = deepcopy(R)
699
700
701 a, b, g = R_to_euler_yxy(R)
702 euler_to_R_yxy(a, b, g, R2)
703
704
705 for i in range(3):
706 for j in range(3):
707 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
708
709
711 """Test the rotation matrix to yxz Euler angle conversion and back again."""
712
713
714 R_random_hypersphere(R)
715 R_orig = deepcopy(R)
716
717
718 a, b, g = R_to_euler_yxz(R)
719 euler_to_R_yxz(a, b, g, R2)
720
721
722 for i in range(3):
723 for j in range(3):
724 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
725
726
728 """Test the rotation matrix to yzx Euler angle conversion and back again."""
729
730
731 R_random_hypersphere(R)
732 R_orig = deepcopy(R)
733
734
735 a, b, g = R_to_euler_yzx(R)
736 euler_to_R_yzx(a, b, g, R2)
737
738
739 for i in range(3):
740 for j in range(3):
741 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
742
743
745 """Test the rotation matrix to yzy Euler angle conversion and back again."""
746
747
748 R_random_hypersphere(R)
749 R_orig = deepcopy(R)
750
751
752 a, b, g = R_to_euler_yzy(R)
753 euler_to_R_yzy(a, b, g, R2)
754
755
756 for i in range(3):
757 for j in range(3):
758 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
759
760
762 """Test the rotation matrix to zxy Euler angle conversion and back again."""
763
764
765 R_random_hypersphere(R)
766 R_orig = deepcopy(R)
767
768
769 a, b, g = R_to_euler_zxy(R)
770 euler_to_R_zxy(a, b, g, R2)
771
772
773 for i in range(3):
774 for j in range(3):
775 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
776
777
779 """Test the rotation matrix to zxz Euler angle conversion and back again."""
780
781
782 R_random_hypersphere(R)
783 R_orig = deepcopy(R)
784
785
786 a, b, g = R_to_euler_zxz(R)
787 euler_to_R_zxz(a, b, g, R2)
788
789
790 for i in range(3):
791 for j in range(3):
792 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
793
794
796 """Test the rotation matrix to zyx Euler angle conversion and back again."""
797
798
799 R_random_hypersphere(R)
800 R_orig = deepcopy(R)
801
802
803 a, b, g = R_to_euler_zyx(R)
804 euler_to_R_zyx(a, b, g, R2)
805
806
807 for i in range(3):
808 for j in range(3):
809 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
810
811
813 """Test the rotation matrix to zyz Euler angle conversion and back again."""
814
815
816 R_random_hypersphere(R)
817 R_orig = deepcopy(R)
818
819
820 a, b, g = R_to_euler_zyz(R)
821 euler_to_R_zyz(a, b, g, R2)
822
823
824 for i in range(3):
825 for j in range(3):
826 self.assertAlmostEqual(R_orig[i, j], R2[i, j])
827
828
830 """Test the rotation matrix to xyx Euler angle conversion."""
831
832
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
847 """Test the rotation matrix to xyz Euler angle conversion."""
848
849
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
864 """Test the rotation matrix to xzx Euler angle conversion."""
865
866
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
881 """Test the rotation matrix to xzy Euler angle conversion."""
882
883
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
898 """Test the rotation matrix to yxy Euler angle conversion."""
899
900
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
915 """Test the rotation matrix to yxz Euler angle conversion."""
916
917
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
932 """Test the rotation matrix to yzx Euler angle conversion."""
933
934
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
949 """Test the rotation matrix to yzy Euler angle conversion."""
950
951
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
966 """Test the rotation matrix to zxy Euler angle conversion."""
967
968
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
983 """Test the rotation matrix to zxz Euler angle conversion."""
984
985
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
1000 """Test the rotation matrix to zyx Euler angle conversion."""
1001
1002
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
1018 """Test the rotation matrix to zyz Euler angle conversion."""
1019
1020
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
1040 R = array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], float64)
1041
1042
1043 quat = zeros(4, float64)
1044 R_to_quaternion(R, quat)
1045 print("Quaternion:\n%s" % quat)
1046
1047
1048 quat_true = array([1, 0, 0, 0], float64)
1049
1050
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
1060 R = array([[0, 0, 1], [1, 0, 0], [0, 1, 0]], float64)
1061
1062
1063 quat = zeros(4, float64)
1064 R_to_quaternion(R, quat)
1065 print("Quaternion:\n%s" % quat)
1066
1067
1068 quat_true = array([1, 1, 1, 1], float64) / 2
1069
1070
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
1080 euler = [0.0, 0.0, 0.0]
1081
1082
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
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
1096 euler = [1.0, 0.0, 0.0]
1097
1098
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
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
1112 euler = [0.0, 1.0, 0.0]
1113
1114
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
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
1128 euler = [0.0, 0.0, 1.0]
1129
1130
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
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
1144 euler = [1.0, 1.0, 0.0]
1145
1146
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
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
1160 euler = [0.0, 1.0, 1.0]
1161
1162
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
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
1176 euler = [1.0, 0.0, 1.0]
1177
1178
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
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
1192 euler = [1.0, 1.0, 1.0]
1193
1194
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
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
1208 euler = [1.0, 0.5, 3.0]
1209
1210
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
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
1224 quat = array([1, 0, 0, 0], float64)
1225
1226
1227 axis, angle = quaternion_to_axis_angle(quat)
1228 print("Axis: %s" % axis)
1229 print("Angle: %s" % angle)
1230
1231
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
1241 quat = array([0, 1, 1, 1], float64) / sqrt(3)
1242
1243
1244 axis, angle = quaternion_to_axis_angle(quat)
1245 print("Axis: %s" % axis)
1246 print("Angle: %s" % angle)
1247
1248
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
1259 quat = array([1, 0, 0, 0], float64)
1260
1261
1262 quaternion_to_R(quat, R)
1263 print("Rotation matrix:\n%s" % R)
1264
1265
1266 R_true = eye(3)
1267
1268
1269 for i in range(3):
1270 for j in range(3):
1271 self.assertEqual(R[i, j], R_true[i, j])
1272
1273
1275 """Test the quaternion to rotation matrix conversion for a 30 degree rotation about z."""
1276
1277
1278 axis = array([0, 0, 1], float64)
1279 angle = pi / 6
1280
1281
1282 w = cos(angle / 2)
1283
1284
1285 factor = sqrt(1 - w**2)
1286 axis = axis * factor
1287
1288
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
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
1301 quaternion_to_R(quat, R)
1302 print("Rotation matrix:\n%s" % R)
1303
1304
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
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
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
1322 axis = array([1, 1, 1], float64) / sqrt(3)
1323 angle = 2 * pi / 3
1324
1325
1326 w = cos(angle / 2)
1327
1328
1329 factor = sqrt(1 - w**2)
1330 axis = axis * factor
1331
1332
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
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
1345 quaternion_to_R(quat, R)
1346 print("Rotation matrix:\n%s" % R)
1347
1348
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
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
1359 self.check_rotation(R, x_real_pos, y_real_pos, z_real_pos, x_real_neg, y_real_neg, z_real_neg)
1360