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  }