github.com/acrespo/mobile@v0.0.0-20190107162257-dc0771356504/exp/f32/f32_test.go (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package f32 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 "math" 11 "testing" 12 ) 13 14 func TestAffineTranslationsCommute(t *testing.T) { 15 a := &Affine{ 16 {1, 0, 3}, 17 {0, 1, 4}, 18 } 19 b := &Affine{ 20 {1, 0, 20}, 21 {0, 1, 30}, 22 } 23 24 var m0, m1 Affine 25 m0.Mul(a, b) 26 m1.Mul(b, a) 27 if !m0.Eq(&m1, 0) { 28 t.Errorf("m0, m1 differ.\nm0: %v\nm1: %v", m0, m1) 29 } 30 } 31 32 func TestAffineMat3Equivalence(t *testing.T) { 33 a0 := Affine{ 34 {13, 19, 37}, 35 {101, 149, 311}, 36 } 37 m0 := Mat3{ 38 a0[0], 39 a0[1], 40 {0, 0, 1}, 41 } 42 43 a1 := Affine{ 44 {1009, 1051, 1087}, 45 {563, 569, 571}, 46 } 47 m1 := Mat3{ 48 a1[0], 49 a1[1], 50 {0, 0, 1}, 51 } 52 53 a2 := Affine{} 54 a2.Mul(&a0, &a1) 55 m2 := Mat3{ 56 a2[0], 57 a2[1], 58 {0, 0, 1}, 59 } 60 61 mm := Mat3{} 62 mm.Mul(&m0, &m1) 63 64 if !m2.Eq(&mm, 0) { 65 t.Errorf("m2, mm differ.\nm2: %v\nmm: %v", m2, mm) 66 } 67 } 68 69 var x3 = Mat3{ 70 {0, 1, 2}, 71 {3, 4, 5}, 72 {6, 7, 8}, 73 } 74 75 var x3sq = Mat3{ 76 {15, 18, 21}, 77 {42, 54, 66}, 78 {69, 90, 111}, 79 } 80 81 var id3 = Mat3{ 82 {1, 0, 0}, 83 {0, 1, 0}, 84 {0, 0, 1}, 85 } 86 87 func TestMat3Mul(t *testing.T) { 88 tests := []struct{ m0, m1, want Mat3 }{ 89 {x3, id3, x3}, 90 {id3, x3, x3}, 91 {x3, x3, x3sq}, 92 { 93 Mat3{ 94 {+1.811, +0.000, +0.000}, 95 {+0.000, +2.414, +0.000}, 96 {+0.000, +0.000, -1.010}, 97 }, 98 Mat3{ 99 {+0.992, -0.015, +0.123}, 100 {+0.000, +0.992, +0.123}, 101 {-0.124, -0.122, +0.985}, 102 }, 103 Mat3{ 104 {+1.797, -0.027, +0.223}, 105 {+0.000, +2.395, +0.297}, 106 {+0.125, +0.123, -0.995}, 107 }, 108 }, 109 } 110 111 for i, test := range tests { 112 got := Mat3{} 113 got.Mul(&test.m0, &test.m1) 114 if !got.Eq(&test.want, 0.01) { 115 t.Errorf("test #%d:\n%s *\n%s =\n%s, want\n%s", i, test.m0, test.m1, got, test.want) 116 } 117 } 118 } 119 120 func TestMat3SelfMul(t *testing.T) { 121 m := x3 122 m.Mul(&m, &m) 123 if !m.Eq(&x3sq, 0) { 124 t.Errorf("m, x3sq differ.\nm: %v\nx3sq: %v", m, x3sq) 125 } 126 } 127 128 var x4 = Mat4{ 129 {0, 1, 2, 3}, 130 {4, 5, 6, 7}, 131 {8, 9, 10, 11}, 132 {12, 13, 14, 15}, 133 } 134 135 var x4sq = Mat4{ 136 {56, 62, 68, 74}, 137 {152, 174, 196, 218}, 138 {248, 286, 324, 362}, 139 {344, 398, 452, 506}, 140 } 141 142 var id4 = Mat4{ 143 {1, 0, 0, 0}, 144 {0, 1, 0, 0}, 145 {0, 0, 1, 0}, 146 {0, 0, 0, 1}, 147 } 148 149 func TestMat4Eq(t *testing.T) { 150 tests := []struct { 151 m0, m1 Mat4 152 eq bool 153 }{ 154 {x4, x4, true}, 155 {id4, id4, true}, 156 {x4, id4, false}, 157 } 158 159 for _, test := range tests { 160 got := test.m0.Eq(&test.m1, 0.01) 161 if got != test.eq { 162 t.Errorf("Eq=%v, want %v for\n%s\n%s", got, test.eq, test.m0, test.m1) 163 } 164 } 165 } 166 167 func TestMat4Mul(t *testing.T) { 168 tests := []struct{ m0, m1, want Mat4 }{ 169 {x4, id4, x4}, 170 {id4, x4, x4}, 171 {x4, x4, x4sq}, 172 { 173 Mat4{ 174 {+1.811, +0.000, +0.000, +0.000}, 175 {+0.000, +2.414, +0.000, +0.000}, 176 {+0.000, +0.000, -1.010, -1.000}, 177 {+0.000, +0.000, -2.010, +0.000}, 178 }, 179 Mat4{ 180 {+0.992, -0.015, +0.123, +0.000}, 181 {+0.000, +0.992, +0.123, +0.000}, 182 {-0.124, -0.122, +0.985, +0.000}, 183 {-0.000, -0.000, -8.124, +1.000}, 184 }, 185 Mat4{ 186 {+1.797, -0.027, +0.223, +0.000}, 187 {+0.000, +2.395, +0.297, +0.000}, 188 {+0.125, +0.123, +7.129, -1.000}, 189 {+0.249, +0.245, -1.980, +0.000}, 190 }, 191 }, 192 } 193 194 for i, test := range tests { 195 got := Mat4{} 196 got.Mul(&test.m0, &test.m1) 197 if !got.Eq(&test.want, 0.01) { 198 t.Errorf("test #%d:\n%s *\n%s =\n%s, want\n%s", i, test.m0, test.m1, got, test.want) 199 } 200 } 201 } 202 203 func TestMat4LookAt(t *testing.T) { 204 tests := []struct { 205 eye, center, up Vec3 206 want Mat4 207 }{ 208 { 209 Vec3{1, 1, 8}, Vec3{0, 0, 0}, Vec3{0, 1, 0}, 210 Mat4{ 211 {0.992, -0.015, 0.123, 0.000}, 212 {0.000, 0.992, 0.123, 0.000}, 213 {-0.124, -0.122, 0.985, 0.000}, 214 {-0.000, -0.000, -8.124, 1.000}, 215 }, 216 }, 217 { 218 Vec3{4, 5, 7}, Vec3{0.1, 0.2, 0.3}, Vec3{0, -1, 0}, 219 Mat4{ 220 {-0.864, 0.265, 0.428, 0.000}, 221 {0.000, -0.850, 0.526, 0.000}, 222 {0.503, 0.455, 0.735, 0.000}, 223 {-0.064, 0.007, -9.487, 1.000}, 224 }, 225 }, 226 } 227 228 for _, test := range tests { 229 got := Mat4{} 230 got.LookAt(&test.eye, &test.center, &test.up) 231 if !got.Eq(&test.want, 0.01) { 232 t.Errorf("LookAt(%s,%s%s) =\n%s\nwant\n%s", test.eye, test.center, test.up, got, test.want) 233 } 234 } 235 236 } 237 238 func TestMat4Perspective(t *testing.T) { 239 want := Mat4{ 240 {1.811, 0.000, 0.000, 0.000}, 241 {0.000, 2.414, 0.000, 0.000}, 242 {0.000, 0.000, -1.010, -1.000}, 243 {0.000, 0.000, -2.010, 0.000}, 244 } 245 got := Mat4{} 246 247 got.Perspective(Radian(math.Pi/4), 4.0/3, 1, 200) 248 249 if !got.Eq(&want, 0.01) { 250 t.Errorf("got\n%s\nwant\n%s", got, want) 251 } 252 253 } 254 255 func TestMat4Rotate(t *testing.T) { 256 want := &Mat4{ 257 {2.000, 1.000, -0.000, 3.000}, 258 {6.000, 5.000, -4.000, 7.000}, 259 {10.000, 9.000, -8.000, 11.000}, 260 {14.000, 13.000, -12.000, 15.000}, 261 } 262 263 got := new(Mat4) 264 got.Rotate(&x4, Radian(math.Pi/2), &Vec3{0, 1, 0}) 265 266 if !got.Eq(want, 0.01) { 267 t.Errorf("got\n%s\nwant\n%s", got, want) 268 } 269 } 270 271 func TestMat4Scale(t *testing.T) { 272 want := &Mat4{ 273 {0 * 2, 1 * 3, 2 * 4, 3 * 1}, 274 {4 * 2, 5 * 3, 6 * 4, 7 * 1}, 275 {8 * 2, 9 * 3, 10 * 4, 11 * 1}, 276 {12 * 2, 13 * 3, 14 * 4, 15 * 1}, 277 } 278 279 got := new(Mat4) 280 got.Scale(&x4, 2, 3, 4) 281 282 if !got.Eq(want, 0.01) { 283 t.Errorf("got\n%s\nwant\n%s", got, want) 284 } 285 } 286 287 func TestMat4Translate(t *testing.T) { 288 want := &Mat4{ 289 {0, 1, 2, 0*0.1 + 1*0.2 + 2*0.3 + 3*1}, 290 {4, 5, 6, 4*0.1 + 5*0.2 + 6*0.3 + 7*1}, 291 {8, 9, 10, 8*0.1 + 9*0.2 + 10*0.3 + 11*1}, 292 {12, 13, 14, 12*0.1 + 13*0.2 + 14*0.3 + 15*1}, 293 } 294 295 got := new(Mat4) 296 got.Translate(&x4, 0.1, 0.2, 0.3) 297 298 if !got.Eq(want, 0.01) { 299 t.Errorf("got\n%s\nwant\n%s", got, want) 300 } 301 } 302 303 func testTrig(t *testing.T, gotFunc func(float32) float32, wantFunc func(float64) float64) { 304 nBad := 0 305 for a := float32(-9); a < +9; a += .01 { 306 got := gotFunc(a) 307 want := float32(wantFunc(float64(a))) 308 diff := got - want 309 if diff < 0 { 310 diff = -diff 311 } 312 if diff > 0.001 { 313 if nBad++; nBad == 10 { 314 t.Errorf("too many failures") 315 break 316 } 317 t.Errorf("a=%+.2f: got %+.4f, want %+.4f, diff=%.4f", a, got, want, diff) 318 } 319 } 320 } 321 322 func TestCos(t *testing.T) { testTrig(t, Cos, math.Cos) } 323 func TestSin(t *testing.T) { testTrig(t, Sin, math.Sin) } 324 func TestTan(t *testing.T) { testTrig(t, Tan, math.Tan) } 325 326 func BenchmarkSin(b *testing.B) { 327 for i := 0; i < b.N; i++ { 328 for a := 0; a < 3141; a++ { 329 Sin(float32(a) / 1000) 330 } 331 } 332 } 333 334 func TestBytes(t *testing.T) { 335 testCases := []struct { 336 byteOrder binary.ByteOrder 337 want []byte 338 }{{ 339 binary.BigEndian, 340 []byte{ 341 // The IEEE 754 binary32 format is 1 sign bit, 8 exponent bits and 23 fraction bits. 342 0x00, 0x00, 0x00, 0x00, // float32(+0.00) is 0 0000000_0 0000000_00000000_00000000 343 0x3f, 0xa0, 0x00, 0x00, // float32(+1.25) is 0 0111111_1 0100000_00000000_00000000 344 0xc0, 0x00, 0x00, 0x00, // float32(-2.00) is 1 1000000_0 0000000_00000000_00000000 345 }, 346 }, { 347 binary.LittleEndian, 348 []byte{ 349 0x00, 0x00, 0x00, 0x00, 350 0x00, 0x00, 0xa0, 0x3f, 351 0x00, 0x00, 0x00, 0xc0, 352 }, 353 }} 354 355 for _, tc := range testCases { 356 got := Bytes(tc.byteOrder, +0.00, +1.25, -2.00) 357 if !bytes.Equal(got, tc.want) { 358 t.Errorf("%v:\ngot % x\nwant % x", tc.byteOrder, got, tc.want) 359 } 360 } 361 }