package f32 import ( "math" "testing" ) var xyTests = []struct { x, y float32 }{ {0, 0}, {1, 1}, {2, 3}, {6.5, 4.3}, } var a = Affine{ {3, 4, 5}, {6, 7, 8}, } func TestInverse(t *testing.T) { wantInv := Affine{ {-2.33333, 1.33333, 1}, {2, -1, -2}, } var gotInv Affine gotInv.Inverse(&a) if !gotInv.Eq(&wantInv, 0.01) { t.Errorf("Inverse: got %s want %s", gotInv, wantInv) } var wantId, gotId Affine wantId.Identity() gotId.Mul(&a, &wantInv) if !gotId.Eq(&wantId, 0.01) { t.Errorf("Identity #0: got %s want %s", gotId, wantId) } gotId.Mul(&wantInv, &a) if !gotId.Eq(&wantId, 0.01) { t.Errorf("Identity #1: got %s want %s", gotId, wantId) } } func TestAffineScale(t *testing.T) { for _, test := range xyTests { want := a want.Mul(&want, &Affine{{test.x, 0, 0}, {0, test.y, 0}}) got := a got.Scale(&got, test.x, test.y) if !got.Eq(&want, 0.01) { t.Errorf("(%.2f, %.2f): got %s want %s", test.x, test.y, got, want) } } } func TestAffineTranslate(t *testing.T) { for _, test := range xyTests { want := a want.Mul(&want, &Affine{{1, 0, test.x}, {0, 1, test.y}}) got := a got.Translate(&got, test.x, test.y) if !got.Eq(&want, 0.01) { t.Errorf("(%.2f, %.2f): got %s want %s", test.x, test.y, got, want) } } } func TestAffineRotate(t *testing.T) { want := Affine{ {-4.000, 3.000, 5.000}, {-7.000, 6.000, 8.000}, } got := a got.Rotate(&got, math.Pi/2) if !got.Eq(&want, 0.01) { t.Errorf("rotate π: got %s want %s", got, want) } want = a got = a got.Rotate(&got, 2*math.Pi) if !got.Eq(&want, 0.01) { t.Errorf("rotate 2π: got %s want %s", got, want) } got = a got.Rotate(&got, math.Pi) got.Rotate(&got, math.Pi) if !got.Eq(&want, 0.01) { t.Errorf("rotate π then π: got %s want %s", got, want) } got = a got.Rotate(&got, math.Pi/3) got.Rotate(&got, -math.Pi/3) if !got.Eq(&want, 0.01) { t.Errorf("rotate π/3 then -π/3: got %s want %s", got, want) } } func TestAffineScaleTranslate(t *testing.T) { mulVec := func(m *Affine, v [2]float32) (mv [2]float32) { mv[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2] mv[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2] return mv } v := [2]float32{1, 10} var sThenT Affine sThenT.Identity() sThenT.Scale(&sThenT, 13, 17) sThenT.Translate(&sThenT, 101, 151) wantSTT := [2]float32{ 13 * (101 + 1), 17 * (151 + 10), } if got := mulVec(&sThenT, v); got != wantSTT { t.Errorf("S then T: got %v, want %v", got, wantSTT) } var tThenS Affine tThenS.Identity() tThenS.Translate(&tThenS, 101, 151) tThenS.Scale(&tThenS, 13, 17) wantTTS := [2]float32{ 101 + (13 * 1), 151 + (17 * 10), } if got := mulVec(&tThenS, v); got != wantTTS { t.Errorf("T then S: got %v, want %v", got, wantTTS) } }