aminal/vendor/github.com/go-gl/mathgl/mgl32/vec_test.go

357 lines
8.9 KiB
Go

// Copyright 2014 The go-gl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mgl32
import (
"math/rand"
"testing"
"time"
)
/* Only floats are tested because the double versions are simply a find->replace on floats */
func Test2DVecAdd(t *testing.T) {
v1 := Vec2{1.0, 2.5}
v2 := Vec2{0.0, 1.0}
v3 := v1.Add(v2)
if !FloatEqual(v3[0], 1.0) || !FloatEqual(v3[1], 3.5) {
t.Errorf("Add not adding properly")
}
v4 := v2.Add(v1)
if !FloatEqual(v3[0], v4[0]) || !FloatEqual(v3[1], v4[1]) {
t.Errorf("Addition is somehow not commutative")
}
}
func Test3DVecAdd(t *testing.T) {
v1 := Vec3{1.0, 2.5, 1.1}
v2 := Vec3{0.0, 1.0, 9.9}
v3 := v1.Add(v2)
if !FloatEqual(v3[0], 1.0) || !FloatEqual(v3[1], 3.5) || !FloatEqual(v3[2], 11.0) {
t.Errorf("Add not adding properly")
}
v4 := v2.Add(v1)
if !FloatEqual(v3[0], v4[0]) || !FloatEqual(v3[1], v4[1]) || !FloatEqual(v3[2], v4[2]) {
t.Errorf("Addition is somehow not commutative")
}
}
func Test4DVecAdd(t *testing.T) {
v1 := Vec4{1.0, 2.5, 1.1, 2.0}
v2 := Vec4{0.0, 1.0, 9.9, 100.0}
v3 := v1.Add(v2)
if !FloatEqual(v3[0], 1.0) || !FloatEqual(v3[1], 3.5) || !FloatEqual(v3[2], 11.0) || !FloatEqual(v3[3], 102.0) {
t.Errorf("Add not adding properly")
}
v4 := v2.Add(v1)
if !FloatEqual(v3[0], v4[0]) || !FloatEqual(v3[1], v4[1]) || !FloatEqual(v3[2], v4[2]) || !FloatEqual(v3[3], v4[3]) {
t.Errorf("Addition is somehow not commutative")
}
}
func Test2DVecSub(t *testing.T) {
v1 := Vec2{1.0, 2.5}
v2 := Vec2{0.0, 1.0}
v3 := v1.Sub(v2)
if !FloatEqual(v3[0], 1.0) || !FloatEqual(v3[1], 1.5) {
t.Errorf("Sub not subtracting properly [%f, %f]", v3[0], v3[1])
}
}
func Test3DVecSub(t *testing.T) {
v1 := Vec3{1.0, 2.5, 1.1}
v2 := Vec3{0.0, 1.0, 9.9}
v3 := v1.Sub(v2)
// 1.1-9.9 does stupid things to floats, so we need threshold
if !FloatEqual(v3[0], 1.0) || !FloatEqual(v3[1], 1.5) || !FloatEqualThreshold(v3[2], -8.8, 1e-5) {
t.Errorf("Sub not subtracting properly [%f, %f, %f]", v3[0], v3[1], v3[2])
}
}
func Test4DVecSub(t *testing.T) {
v1 := Vec4{1.0, 2.5, 1.1, 2.0}
v2 := Vec4{0.0, 1.0, 9.9, 100.0}
v3 := v1.Sub(v2)
// 1.1-9.9 does stupid things to floats, so we need a more tolerant threshold
if !FloatEqual(v3[0], 1.0) || !FloatEqual(v3[1], 1.5) || !FloatEqualThreshold(v3[2], -8.8, 1e-5) || !FloatEqual(v3[3], -98.0) {
t.Errorf("Sub not subtracting properly [%f, %f, %f, %f]", v3[0], v3[1], v3[2], v3[3])
}
}
func TestVecMul(t *testing.T) {
v := Vec2{1.0, 0.0}
v = v.Mul(15.0)
if !FloatEqual(v[0], 15.0) || !FloatEqual(v[1], 0.0) {
t.Errorf("Vec mul does something weird [%f, %f]", v[0], v[1])
}
v2 := Vec3{1.0, 0.0, 100.1}
v2 = v2.Mul(15.0)
if !FloatEqual(v2[0], 15.0) || !FloatEqual(v2[1], 0.0) || !FloatEqual(v2[2], 1501.5) {
t.Errorf("Vec mul does something weird [%f, %f, %f]", v2[0], v2[1], v2[2])
}
v3 := Vec4{1.0, 0.0, 100.1, -1.0}
v3 = v3.Mul(15.0)
if !FloatEqual(v3[0], 15.0) || !FloatEqual(v3[1], 0.0) || !FloatEqual(v3[2], 1501.5) || !FloatEqual(v3[3], -15.0) {
t.Errorf("Vec mul does something weird [%f, %f, %f, %f]", v3[0], v3[1], v3[2], v3[3])
}
}
func TestVecOuterProd(t *testing.T) {
v1 := Vec3{1, 2, 3}
v2 := Vec2{10, 11}
correct := Mat3x2FromRows(
Vec2{10, 11},
Vec2{20, 22},
Vec2{30, 33},
)
result := v1.OuterProd2(v2)
if !correct.ApproxEqualThreshold(correct, 1e-4) {
t.Errorf("Vector outer product isn't working. Got: %v. Expected: %v", result, correct)
}
}
func TestVecCrossProduct(t *testing.T) {
v1 := Vec3{1, 2, 3}
v2 := Vec3{10, 11, 12}
expected := Vec3{-9, 18, -9}
result := v1.Cross(v2)
if !expected.ApproxEqual(result) {
t.Errorf("Vec3 cross product %v x %v Got: %v. Expected: %v.",
v1, v2, result, expected)
}
}
func TestVecDotProduct(t *testing.T) {
mustEqual := func(result float32, expected float32, name string) {
if !FloatEqual(result, expected) {
t.Errorf("%v.Dot(%v) failed. Got: %v. Expected %v.",
name, name, result, expected)
}
}
mustEqual(Vec2{1, 2}.Dot(Vec2{3, 4}), 11, "Vec2")
mustEqual(Vec3{-1, -5, -7}.Dot(Vec3{10, 20, 30}), -320, "Vec3")
mustEqual(Vec4{1, 3, 5, 7}.Dot(Vec4{10, 20, 30, 40}), 500, "Vec3")
}
func TestVecLen(t *testing.T) {
mustEqual := func(result float32, expected float32, name string) {
if !FloatEqual(result, expected) {
t.Errorf("%v failed. Got: %v. Expected %v.",
name, result, expected)
}
}
mustEqual(Vec2{3, 4}.Len(), 5, "Vec2.Len()")
mustEqual(Vec3{2, -5, 4}.Len(), 6.708203932499, "Vec3.Len()")
mustEqual(Vec4{2, 3, 5, 7}.Len(), 9.3273790530888, "Vec4.Len()")
}
func Test2DVecNormalize(t *testing.T) {
v := Vec2{3, 4}
norm := v.Normalize()
expected := Vec2{0.6, 0.8}
if !norm.ApproxEqual(expected) {
t.Errorf("%v.Normalize() failed. Got: %v. Expected: %v",
v, norm, expected)
}
}
func TestVecElemAccessors(t *testing.T) {
mustEqual := func(desc string, expected float32, results ...float32) {
for _, r := range results {
if !FloatEqual(expected, r) {
t.Errorf("%v failed. Got: %v. Expected %v...",
desc, results, expected)
}
}
}
const x, y, z, w = 1, 2, 3, 4
v2 := Vec2{x, y}
v3 := Vec3{x, y, z}
v4 := Vec4{x, y, z, w}
mustEqual("Vec.X()", x, v2.X(), v3.X(), v4.X())
mustEqual("Vec.Y()", y, v2.Y(), v3.Y(), v4.Y())
mustEqual("Vec.Z()", z, v3.Z(), v4.Z())
mustEqual("Vec.W()", w, v4.W())
x2, y2 := v2.Elem()
x3, y3, z3 := v3.Elem()
x4, y4, z4, w4 := v4.Elem()
mustEqual("Vec.Elem() -> x", x, x2, x3, x4)
mustEqual("Vec.Elem() -> y", y, y2, y3, y4)
mustEqual("Vec.Elem() -> z", z, z3, z4)
mustEqual("Vec.Elem() -> w", w, w4)
}
func TestVecEqual(t *testing.T) {
assert := func(res bool, desc string) {
if !res {
t.Errorf("%v failed.", desc)
}
}
v2, errV2 := Vec2{1, 2}, Vec2{1, 0}
v3, errV3 := Vec3{1, 2, 3}, Vec3{1, 2, 0}
v4, errV4 := Vec4{1, 2, 3, 4}, Vec4{1, 2, 0, 4}
assert(v2.ApproxEqual(v2), "Vec2.ApproxEqual")
assert(!v2.ApproxEqual(errV2), "Vec2.ApproxEqual")
assert(v2.ApproxEqualThreshold(v2, 0.1), "Vec2.ApproxEqualThreshold")
assert(!v2.ApproxEqualThreshold(errV2, 0.1), "Vec2.ApproxEqualThreshold")
assert(v2.ApproxFuncEqual(v2, FloatEqual), "Vec2.ApproxFuncEq")
assert(!v2.ApproxFuncEqual(errV2, FloatEqual), "Vec2.ApproxFuncEq")
assert(v3.ApproxEqual(v3), "Vec3.ApproxEqual")
assert(!v3.ApproxEqual(errV3), "Vec3.ApproxEqual")
assert(v3.ApproxEqualThreshold(v3, 0.1), "Vec3.ApproxEqualThreshold")
assert(!v3.ApproxEqualThreshold(errV3, 0.1), "Vec3.ApproxEqualThreshold")
assert(v3.ApproxFuncEqual(v3, FloatEqual), "Vec3.ApproxFuncEq")
assert(!v3.ApproxFuncEqual(errV3, FloatEqual), "Vec3.ApproxFuncEq")
assert(v4.ApproxEqual(v4), "Vec4.ApproxEqual")
assert(!v4.ApproxEqual(errV4), "Vec4.ApproxEqual")
assert(v4.ApproxEqualThreshold(v4, 0.1), "Vec4.ApproxEqualThreshold")
assert(!v4.ApproxEqualThreshold(errV4, 0.1), "Vec4.ApproxEqualThreshold")
assert(v4.ApproxFuncEqual(v4, FloatEqual), "Vec4.ApproxFuncEq")
assert(!v4.ApproxFuncEqual(errV4, FloatEqual), "Vec4.ApproxFuncEq")
}
func BenchmarkVec4Add(b *testing.B) {
b.StopTimer()
r := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
for i := 0; i < b.N; i++ {
b.StopTimer()
v1 := Vec4{r.Float32(), r.Float32(), r.Float32(), r.Float32()}
v2 := Vec4{r.Float32(), r.Float32(), r.Float32(), r.Float32()}
b.StartTimer()
v1.Add(v2)
}
}
func init() {
rand.Seed(time.Now().UnixNano())
}
var v1 = Vec4{rand.Float32(), rand.Float32(), rand.Float32(), rand.Float32()}
var v2 = Vec4{rand.Float32(), rand.Float32(), rand.Float32(), rand.Float32()}
func BenchmarkVec4Sub(b *testing.B) {
for i := 0; i < b.N; i++ {
v1.Sub(v2)
}
}
func BenchmarkVec4Scale(b *testing.B) {
b.StopTimer()
r := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
for i := 0; i < b.N; i++ {
b.StopTimer()
v1 := Vec4{r.Float32(), r.Float32(), r.Float32(), r.Float32()}
c := r.Float32()
b.StartTimer()
v1.Mul(c)
}
}
func BenchmarkVec4Dot(b *testing.B) {
b.StopTimer()
r := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
for i := 0; i < b.N; i++ {
b.StopTimer()
v1 := Vec4{r.Float32(), r.Float32(), r.Float32(), r.Float32()}
v2 := Vec4{r.Float32(), r.Float32(), r.Float32(), r.Float32()}
b.StartTimer()
v1.Dot(v2)
}
}
func BenchmarkVec4Len(b *testing.B) {
b.StopTimer()
r := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
for i := 0; i < b.N; i++ {
b.StopTimer()
v1 := Vec4{r.Float32(), r.Float32(), r.Float32(), r.Float32()}
b.StartTimer()
v1.Len()
}
}
func BenchmarkVec4Normalize(b *testing.B) {
b.StopTimer()
r := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
for i := 0; i < b.N; i++ {
b.StopTimer()
v1 := Vec4{r.Float32(), r.Float32(), r.Float32(), r.Float32()}
b.StartTimer()
v1.Normalize()
}
}
func BenchmarkVecCross(b *testing.B) {
b.StopTimer()
r := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
for i := 0; i < b.N; i++ {
b.StopTimer()
v1 := Vec3{r.Float32(), r.Float32(), r.Float32()}
v2 := Vec3{r.Float32(), r.Float32(), r.Float32()}
b.StartTimer()
v1.Cross(v2)
}
}