Quat angle and tests

This commit is contained in:
bloeys
2021-11-06 09:42:28 +04:00
parent 2de2e9696a
commit 8889482bd5
7 changed files with 143 additions and 2 deletions

View File

@ -14,6 +14,10 @@ func DotVec4(v1, v2 *Vec4) float32 {
return v1.X()*v2.X() + v1.Y()*v2.Y() + v1.Z()*v2.Z() + v1.W()*v2.W()
}
func DotQuat(q1, q2 *Quat) float32 {
return q1.X()*q2.X() + q1.Y()*q2.Y() + q1.Z()*q2.Z() + q1.W()*q2.W()
}
func Cross(v1, v2 *Vec3) *Vec3 {
return &Vec3{
Data: [3]float32{
@ -106,3 +110,8 @@ func ReflectVec3(v, n *Vec3) *Vec3 {
},
}
}
//AngleQuat returns the angle between the two quaternions in radians
func AngleQuat(q1, q2 *Quat) float32 {
return Acos32(DotQuat(q1, q2))
}

View File

@ -11,6 +11,11 @@ type Quat struct {
Vec4
}
//Eq checks for exact equality
func (q *Quat) Eq(q2 *Quat) bool {
return q.Data == q2.Data
}
//Euler takes rotations in radians and produces a rotation that
//rotates around the z-axis, y-axis and lastly x-axis.
func NewQuatEuler(v *Vec3) *Quat {

27
gglm/quat_test.go Executable file
View File

@ -0,0 +1,27 @@
package gglm_test
import (
"testing"
"github.com/bloeys/gglm/gglm"
)
func TestNewQuatEuler(t *testing.T) {
q := gglm.NewQuatEuler(gglm.NewVec3(180, 180, 180).AsRad())
ans := &gglm.Quat{Vec4: *gglm.NewVec4(0, 0, 0, 1)}
if !gglm.EqF32(q.X(), ans.X()) || !gglm.EqF32(q.Y(), ans.Y()) || !gglm.EqF32(q.Z(), ans.Z()) || !gglm.EqF32(q.W(), ans.W()) {
t.Errorf("Got: %v; Expected: %v", q.String(), ans.String())
}
}
func TestNewQuatAngleAxis(t *testing.T) {
q := gglm.NewQuatAngleAxis(180*gglm.Deg2Rad, gglm.NewVec3(0, 1, 0))
ans := &gglm.Quat{Vec4: *gglm.NewVec4(0, 1, 0, 0)}
if !gglm.EqF32(q.X(), ans.X()) || !gglm.EqF32(q.Y(), ans.Y()) || !gglm.EqF32(q.Z(), ans.Z()) || !gglm.EqF32(q.W(), ans.W()) {
t.Errorf("Got: %v; Expected: %v", q.String(), ans.String())
}
}

View File

@ -19,10 +19,18 @@ func Sin32(x float32) float32 {
return float32(math.Sin(float64(x)))
}
func Asin32(x float32) float32 {
return float32(math.Asin(float64(x)))
}
func Cos32(x float32) float32 {
return float32(math.Cos(float64(x)))
}
func Acos32(x float32) float32 {
return float32(math.Acos(float64(x)))
}
func Sincos32(x float32) (sinx, cosx float32) {
a, b := math.Sincos(float64(x))
return float32(a), float32(b)

View File

@ -29,6 +29,10 @@ func (t *TrMat) Mul(m *TrMat) *TrMat {
return t
}
func (t *TrMat) Eq(m *TrMat) bool {
return t.Data == m.Data
}
func (t *TrMat) Clone() *TrMat {
return &TrMat{
Mat4: *t.Mat4.Clone(),
@ -92,7 +96,7 @@ func NewRotMat(q *Quat) *TrMat {
}
}
func NewTransformMatId() *TrMat {
func NewTrMatId() *TrMat {
return &TrMat{
Mat4: *NewMat4Id(),
}

83
gglm/transform_test.go Executable file
View File

@ -0,0 +1,83 @@
package gglm_test
import (
"testing"
"github.com/bloeys/gglm/gglm"
)
func TestNewTrMatId(t *testing.T) {
m := gglm.NewTrMatId()
ans := &gglm.TrMat{
Mat4: gglm.Mat4{
Data: [16]float32{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
},
},
}
if !m.Eq(ans) {
t.Errorf("Got: %v; Expected: %v", m.String(), ans.String())
}
}
func TestNewTranslationMat(t *testing.T) {
m := gglm.NewTranslationMat(gglm.NewVec3(1, 2, 3))
ans := &gglm.TrMat{
Mat4: gglm.Mat4{
Data: [16]float32{
1, 0, 0, 1,
0, 1, 0, 2,
0, 0, 1, 3,
0, 0, 0, 1,
},
},
}
if !m.Eq(ans) {
t.Errorf("Got: %v; Expected: %v", m.String(), ans.String())
}
}
func TestNewScaleMat(t *testing.T) {
m := gglm.NewScaleMat(gglm.NewVec3(1, 2, 3))
ans := &gglm.TrMat{
Mat4: gglm.Mat4{
Data: [16]float32{
1, 0, 0, 0,
0, 2, 0, 0,
0, 0, 3, 0,
0, 0, 0, 1,
},
},
}
if !m.Eq(ans) {
t.Errorf("Got: %v; Expected: %v", m.String(), ans.String())
}
}
func TestNewRotMat(t *testing.T) {
m := gglm.NewRotMat(gglm.NewQuatId())
ans := &gglm.TrMat{
Mat4: gglm.Mat4{
Data: [16]float32{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
},
},
}
if !m.Eq(ans) {
t.Errorf("Got: %v; Expected: %v", m.String(), ans.String())
}
}

View File

@ -142,7 +142,7 @@ func main() {
rotMat := gglm.NewRotMat(gglm.NewQuatEuler(gglm.NewVec3(60, 30, 20).AsRad()))
scaleMat := gglm.NewScaleMat(gglm.NewVec3(1, 1, 1))
modelMat := gglm.NewTransformMatId()
modelMat := gglm.NewTrMatId()
modelMat.Mul(translationMat.Mul(rotMat.Mul(scaleMat)))
println("\n\n\n", modelMat.String())
@ -159,4 +159,9 @@ func main() {
trMatClone.Scale(gglm.NewVec3(2, 2, 2))
trMatClone.Translate(gglm.NewVec3(9, 0, 0))
println("\n\n", trMatOrig.String(), "; ", trMatClone.String())
//Quat geo
q1 := gglm.NewQuatEuler(gglm.NewVec3(180, 0, 0).AsRad())
q2 := gglm.NewQuatEuler(gglm.NewVec3(0, 180, 0).AsRad())
println(gglm.AngleQuat(q1, q2) * gglm.Rad2Deg)
}