1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2017 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
23 #include <tap/basic.h>
24 #include <tap/float.h>
25 #include <tap/hkl-tap.h>
27 #include "hkl-vector-private.h"
28 #include "hkl-quaternion-private.h"
30 static void assignment(void)
32 HklQuaternion q
= {{1, 0, 0, 0}};
33 HklQuaternion copy
= q
;
35 is_double(1., copy
.data
[0], HKL_EPSILON
, __func__
);
36 is_double(0., copy
.data
[1], HKL_EPSILON
, __func__
);
37 is_double(0., copy
.data
[2], HKL_EPSILON
, __func__
);
38 is_double(0., copy
.data
[3], HKL_EPSILON
, __func__
);
43 HklQuaternion q_ref
= {{1., 2., 3., 4.}};
44 HklQuaternion q
= {{1., 2., 3., 4.}};
45 HklQuaternion q1
= {{1., 1., 3., 4.}};
47 ok(TRUE
== hkl_quaternion_cmp(&q_ref
, &q
), __func__
);
48 ok(FALSE
== hkl_quaternion_cmp(&q_ref
, &q1
), __func__
);
50 /* test the assignation */
52 ok(TRUE
== hkl_quaternion_cmp(&q_ref
, &q1
), __func__
);
55 static void init_from_vector(void)
57 HklQuaternion q_ref
= {{0, 1, -1, .5}};
58 HklVector v
= {{1., -1., .5}};
61 hkl_quaternion_init_from_vector(&q
, &v
);
62 ok(TRUE
== hkl_quaternion_cmp(&q_ref
, &q
), __func__
);
65 static void init_from_angle_and_axe(void)
67 HklQuaternion q_ref1
= {{1, 0, 0, 0}};
68 HklQuaternion q_ref2
= {{sqrt(2.)/2., sqrt(2./9.), -sqrt(2./9.), sqrt(1./18.)}};
69 HklVector v_ref2
= {{1., -1., .5}};
72 hkl_quaternion_init_from_angle_and_axe(&q
, 0, &v_ref2
);
73 ok(TRUE
== hkl_quaternion_cmp(&q_ref1
, &q
), __func__
);
75 hkl_quaternion_init_from_angle_and_axe(&q
, 90. * HKL_DEGTORAD
, &v_ref2
);
76 ok(TRUE
== hkl_quaternion_cmp(&q_ref2
, &q
), __func__
);
79 static void times_quaternion(void)
81 HklQuaternion q_ref
= {{-28., 4., 6., 8.}};
82 HklQuaternion q
= {{1., 2., 3., 4.}};
84 hkl_quaternion_times_quaternion(&q
, &q
);
85 ok(TRUE
== hkl_quaternion_cmp(&q_ref
, &q
), __func__
);
88 static void norm2(void)
90 HklQuaternion q
= {{1., 2., 3., 4.}};
92 is_double(sqrt(30.), hkl_quaternion_norm2(&q
), HKL_EPSILON
, __func__
);
95 static void conjugate(void)
97 HklQuaternion q_ref
= {{1., -2., -3., -4.}};
98 HklQuaternion q
= {{1., 2., 3., 4.}};
100 hkl_quaternion_conjugate(&q
);
101 ok(TRUE
== hkl_quaternion_cmp(&q_ref
, &q
), __func__
);
104 static void to_matrix(void)
106 HklQuaternion q_ref
= {{1./sqrt(2), 0, 0, 1./sqrt(2)}};
107 HklMatrix
*m_ref
= hkl_matrix_new_full(0,-1, 0,
110 HklMatrix
*m
= hkl_matrix_new();
112 hkl_quaternion_to_matrix(&q_ref
, m
);
113 is_matrix(m_ref
, m
, __func__
);
115 hkl_matrix_free(m_ref
);
119 static void to_angle_and_axe(void)
121 HklVector v_ref
= {{0 ,0, 1}};
122 HklVector v_null
= {{0 ,0, 0}};
123 HklQuaternion q_I
= {{1, 0, 0, 0}};
132 /* test the q = (1, 0, 0, 0) solution axe == (0, 0, 0) and angle = 0. */
133 hkl_quaternion_to_angle_and_axe(&q_I
, &angle
, &v
);
134 ok(0 == hkl_vector_cmp(&v_null
, &v
), __func__
);
135 is_double(0., angle
, HKL_EPSILON
, __func__
);
137 /* test other cases */
138 for(i
=-180; i
<180; i
++) {
139 angle_ref
= i
* HKL_DEGTORAD
;
140 hkl_quaternion_init_from_angle_and_axe(&q
, angle_ref
, &v_ref
);
141 hkl_quaternion_to_angle_and_axe(&q
, &angle
, &v
);
143 if (!hkl_vector_cmp(&v_ref
, &v
))
144 is_double(angle_ref
, angle
, HKL_EPSILON
, __func__
);
145 else if (hkl_vector_is_opposite(&v
, &v_ref
))
146 is_double(angle_ref
, -angle
, HKL_EPSILON
, __func__
);
157 init_from_angle_and_axe();