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