1 #![cfg(feature = "arbitrary")]
2 use alga::linear::Transformation;
3 use na::{
4     self, Affine3, Isometry3, Matrix2, Matrix2x3, Matrix2x4, Matrix2x5, Matrix2x6, Matrix3,
5     Matrix3x2, Matrix3x4, Matrix3x5, Matrix3x6, Matrix4, Matrix4x2, Matrix4x3, Matrix4x5,
6     Matrix4x6, Matrix5, Matrix5x2, Matrix5x3, Matrix5x4, Matrix5x6, Matrix6, Matrix6x2, Matrix6x3,
7     Matrix6x4, Matrix6x5, Point3, Projective3, Rotation3, RowVector1, RowVector2, RowVector3,
8     RowVector4, RowVector5, RowVector6, Similarity3, Transform3, Translation3, UnitQuaternion,
9     Vector1, Vector2, Vector3, Vector4, Vector5, Vector6,
10 };
11 
12 quickcheck!{
13     fn translation_conversion(t: Translation3<f64>, v: Vector3<f64>, p: Point3<f64>) -> bool {
14         let iso: Isometry3<f64>   = na::convert(t);
15         let sim: Similarity3<f64> = na::convert(t);
16         let aff: Affine3<f64>     = na::convert(t);
17         let prj: Projective3<f64> = na::convert(t);
18         let tr:  Transform3<f64>  = na::convert(t);
19 
20         t == na::try_convert(iso).unwrap() &&
21         t == na::try_convert(sim).unwrap() &&
22         t == na::try_convert(aff).unwrap() &&
23         t == na::try_convert(prj).unwrap() &&
24         t == na::try_convert(tr).unwrap()  &&
25 
26         t.transform_vector(&v) == iso * v &&
27         t.transform_vector(&v) == sim * v &&
28         t.transform_vector(&v) == aff * v &&
29         t.transform_vector(&v) == prj * v &&
30         t.transform_vector(&v) == tr  * v &&
31 
32         t * p == iso * p &&
33         t * p == sim * p &&
34         t * p == aff * p &&
35         t * p == prj * p &&
36         t * p == tr  * p
37     }
38 
39     fn rotation_conversion(r: Rotation3<f64>, v: Vector3<f64>, p: Point3<f64>) -> bool {
40         let uq:  UnitQuaternion<f64> = na::convert(r);
41         let iso: Isometry3<f64>      = na::convert(r);
42         let sim: Similarity3<f64>    = na::convert(r);
43         let aff: Affine3<f64>        = na::convert(r);
44         let prj: Projective3<f64>    = na::convert(r);
45         let tr:  Transform3<f64>     = na::convert(r);
46 
47         relative_eq!(r, na::try_convert(uq).unwrap(),  epsilon = 1.0e-7) &&
48         relative_eq!(r, na::try_convert(iso).unwrap(), epsilon = 1.0e-7) &&
49         relative_eq!(r, na::try_convert(sim).unwrap(), epsilon = 1.0e-7) &&
50         r == na::try_convert(aff).unwrap() &&
51         r == na::try_convert(prj).unwrap() &&
52         r == na::try_convert(tr).unwrap()  &&
53 
54         // NOTE: we need relative_eq because Isometry and Similarity use quaternions.
55         relative_eq!(r * v, uq  * v, epsilon = 1.0e-7) &&
56         relative_eq!(r * v, iso * v, epsilon = 1.0e-7) &&
57         relative_eq!(r * v, sim * v, epsilon = 1.0e-7) &&
58         r * v == aff * v &&
59         r * v == prj * v &&
60         r * v == tr  * v &&
61 
62         relative_eq!(r * p, uq  * p, epsilon = 1.0e-7) &&
63         relative_eq!(r * p, iso * p, epsilon = 1.0e-7) &&
64         relative_eq!(r * p, sim * p, epsilon = 1.0e-7) &&
65         r * p == aff * p &&
66         r * p == prj * p &&
67         r * p == tr  * p
68     }
69 
70     fn unit_quaternion_conversion(uq: UnitQuaternion<f64>, v: Vector3<f64>, p: Point3<f64>) -> bool {
71         let rot: Rotation3<f64>   = na::convert(uq);
72         let iso: Isometry3<f64>   = na::convert(uq);
73         let sim: Similarity3<f64> = na::convert(uq);
74         let aff: Affine3<f64>     = na::convert(uq);
75         let prj: Projective3<f64> = na::convert(uq);
76         let tr:  Transform3<f64>  = na::convert(uq);
77 
78         uq == na::try_convert(iso).unwrap() &&
79         uq == na::try_convert(sim).unwrap() &&
80         relative_eq!(uq, na::try_convert(rot).unwrap(), epsilon = 1.0e-7) &&
81         relative_eq!(uq, na::try_convert(aff).unwrap(), epsilon = 1.0e-7) &&
82         relative_eq!(uq, na::try_convert(prj).unwrap(), epsilon = 1.0e-7) &&
83         relative_eq!(uq, na::try_convert(tr).unwrap(), epsilon = 1.0e-7)  &&
84 
85         // NOTE: iso and sim use unit quaternions for the rotation so conversions to them are exact.
86         relative_eq!(uq * v, rot * v, epsilon = 1.0e-7) &&
87         uq * v == iso * v &&
88         uq * v == sim * v &&
89         relative_eq!(uq * v, aff * v, epsilon = 1.0e-7) &&
90         relative_eq!(uq * v, prj * v, epsilon = 1.0e-7) &&
91         relative_eq!(uq * v, tr  * v, epsilon = 1.0e-7) &&
92 
93         relative_eq!(uq * p, rot * p, epsilon = 1.0e-7) &&
94         uq * p == iso * p &&
95         uq * p == sim * p &&
96         relative_eq!(uq * p, aff * p, epsilon = 1.0e-7) &&
97         relative_eq!(uq * p, prj * p, epsilon = 1.0e-7) &&
98         relative_eq!(uq * p, tr  * p, epsilon = 1.0e-7)
99     }
100 
101     fn isometry_conversion(iso: Isometry3<f64>, v: Vector3<f64>, p: Point3<f64>) -> bool {
102         let sim: Similarity3<f64> = na::convert(iso);
103         let aff: Affine3<f64>     = na::convert(iso);
104         let prj: Projective3<f64> = na::convert(iso);
105         let tr:  Transform3<f64>  = na::convert(iso);
106 
107 
108         iso == na::try_convert(sim).unwrap() &&
109         relative_eq!(iso, na::try_convert(aff).unwrap(), epsilon = 1.0e-7) &&
110         relative_eq!(iso, na::try_convert(prj).unwrap(), epsilon = 1.0e-7) &&
111         relative_eq!(iso, na::try_convert(tr).unwrap(), epsilon = 1.0e-7)  &&
112 
113         iso * v == sim * v &&
114         relative_eq!(iso * v, aff * v, epsilon = 1.0e-7) &&
115         relative_eq!(iso * v, prj * v, epsilon = 1.0e-7) &&
116         relative_eq!(iso * v, tr  * v, epsilon = 1.0e-7) &&
117 
118         iso * p == sim * p &&
119         relative_eq!(iso * p, aff * p, epsilon = 1.0e-7) &&
120         relative_eq!(iso * p, prj * p, epsilon = 1.0e-7) &&
121         relative_eq!(iso * p, tr  * p, epsilon = 1.0e-7)
122     }
123 
124     fn similarity_conversion(sim: Similarity3<f64>, v: Vector3<f64>, p: Point3<f64>) -> bool {
125         let aff: Affine3<f64>     = na::convert(sim);
126         let prj: Projective3<f64> = na::convert(sim);
127         let tr:  Transform3<f64>  = na::convert(sim);
128 
129         relative_eq!(sim, na::try_convert(aff).unwrap(), epsilon = 1.0e-7) &&
130         relative_eq!(sim, na::try_convert(prj).unwrap(), epsilon = 1.0e-7) &&
131         relative_eq!(sim, na::try_convert(tr).unwrap(),  epsilon = 1.0e-7) &&
132 
133         relative_eq!(sim * v, aff * v, epsilon = 1.0e-7) &&
134         relative_eq!(sim * v, prj * v, epsilon = 1.0e-7) &&
135         relative_eq!(sim * v, tr  * v, epsilon = 1.0e-7) &&
136 
137         relative_eq!(sim * p, aff * p, epsilon = 1.0e-7) &&
138         relative_eq!(sim * p, prj * p, epsilon = 1.0e-7) &&
139         relative_eq!(sim * p, tr  * p, epsilon = 1.0e-7)
140     }
141 
142     // XXX test Transform
143 }
144 
145 macro_rules! array_vector_conversion(
146     ($($array_vector_conversion_i: ident, $Vector: ident, $SZ: expr);* $(;)*) => {$(
147         #[test]
148         fn $array_vector_conversion_i() {
149             let v       = $Vector::from_fn(|i, _| i);
150             let arr: [usize; $SZ] = v.into();
151             let arr_ref: &[usize; $SZ] = v.as_ref();
152             let v2      = $Vector::from(arr);
153 
154             for i in 0 .. $SZ {
155                 assert_eq!(arr[i], i);
156                 assert_eq!(arr_ref[i], i);
157             }
158 
159             assert_eq!(v, v2);
160         }
161     )*}
162 );
163 
164 array_vector_conversion!(
165     array_vector_conversion_1,  Vector1,  1;
166     array_vector_conversion_2,  Vector2,  2;
167     array_vector_conversion_3,  Vector3,  3;
168     array_vector_conversion_4,  Vector4,  4;
169     array_vector_conversion_5,  Vector5,  5;
170     array_vector_conversion_6,  Vector6,  6;
171 );
172 
173 macro_rules! array_row_vector_conversion(
174     ($($array_vector_conversion_i: ident, $Vector: ident, $SZ: expr);* $(;)*) => {$(
175         #[test]
176         fn $array_vector_conversion_i() {
177             let v       = $Vector::from_fn(|_, i| i);
178             let arr: [usize; $SZ] = v.into();
179             let arr_ref = v.as_ref();
180             let v2      = $Vector::from(arr);
181 
182             for i in 0 .. $SZ {
183                 assert_eq!(arr[i], i);
184                 assert_eq!(arr_ref[i], i);
185             }
186 
187             assert_eq!(v, v2);
188         }
189     )*}
190 );
191 
192 array_row_vector_conversion!(
193     array_row_vector_conversion_1,  RowVector1,  1;
194     array_row_vector_conversion_2,  RowVector2,  2;
195     array_row_vector_conversion_3,  RowVector3,  3;
196     array_row_vector_conversion_4,  RowVector4,  4;
197     array_row_vector_conversion_5,  RowVector5,  5;
198     array_row_vector_conversion_6,  RowVector6,  6;
199 );
200 
201 macro_rules! array_matrix_conversion(
202     ($($array_matrix_conversion_i_j: ident, $Matrix: ident, ($NRows: expr, $NCols: expr));* $(;)*) => {$(
203         #[test]
204         fn $array_matrix_conversion_i_j() {
205             let m       = $Matrix::from_fn(|i, j| i * 10 + j);
206             let arr: [[usize; $NRows]; $NCols] = m.into();
207             let arr_ref = m.as_ref();
208             let m2      = $Matrix::from(arr);
209 
210             for i in 0 .. $NRows {
211                 for j in 0 .. $NCols {
212                     assert_eq!(arr[j][i], i * 10 + j);
213                     assert_eq!(arr_ref[j][i], i * 10 + j);
214                 }
215             }
216 
217             assert_eq!(m, m2);
218         }
219     )*}
220 );
221 
222 array_matrix_conversion!(
223     array_matrix_conversion_2_2, Matrix2,   (2, 2);
224     array_matrix_conversion_2_3, Matrix2x3, (2, 3);
225     array_matrix_conversion_2_4, Matrix2x4, (2, 4);
226     array_matrix_conversion_2_5, Matrix2x5, (2, 5);
227     array_matrix_conversion_2_6, Matrix2x6, (2, 6);
228 
229     array_matrix_conversion_3_2, Matrix3x2, (3, 2);
230     array_matrix_conversion_3_3, Matrix3,   (3, 3);
231     array_matrix_conversion_3_4, Matrix3x4, (3, 4);
232     array_matrix_conversion_3_5, Matrix3x5, (3, 5);
233     array_matrix_conversion_3_6, Matrix3x6, (3, 6);
234 
235     array_matrix_conversion_4_2, Matrix4x2, (4, 2);
236     array_matrix_conversion_4_3, Matrix4x3, (4, 3);
237     array_matrix_conversion_4_4, Matrix4,   (4, 4);
238     array_matrix_conversion_4_5, Matrix4x5, (4, 5);
239     array_matrix_conversion_4_6, Matrix4x6, (4, 6);
240 
241     array_matrix_conversion_5_2, Matrix5x2, (5, 2);
242     array_matrix_conversion_5_3, Matrix5x3, (5, 3);
243     array_matrix_conversion_5_4, Matrix5x4, (5, 4);
244     array_matrix_conversion_5_5, Matrix5,   (5, 5);
245     array_matrix_conversion_5_6, Matrix5x6, (5, 6);
246 
247     array_matrix_conversion_6_2, Matrix6x2, (6, 2);
248     array_matrix_conversion_6_3, Matrix6x3, (6, 3);
249     array_matrix_conversion_6_4, Matrix6x4, (6, 4);
250     array_matrix_conversion_6_5, Matrix6x5, (6, 5);
251     array_matrix_conversion_6_6, Matrix6,   (6, 6);
252 );
253