f32_test.go 6.9 KB

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