// Angle returns the angle between two vectors. func Angle(a, b *T) float32 { v := Dot(a, b) / (a.Length() * b.Length()) // prevent NaN if v > 1. { v = v - 2 } else if v < -1. { v = v + 2 } return math.Acos(v) }
// Slerp returns the spherical linear interpolation quaternion between a and b at t (0,1). // See http://en.wikipedia.org/wiki/Slerp func Slerp(a, b *T, t float32) T { d := math.Acos(a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]) ooSinD := 1 / math.Sin(d) t1 := math.Sin(d*(1-t)) * ooSinD t2 := math.Sin(d*t) * ooSinD q := T{ a[0]*t1 + b[0]*t2, a[1]*t1 + b[1]*t2, a[2]*t1 + b[2]*t2, a[3]*t1 + b[3]*t2, } return q.Normalized() }
// AxisAngle extracts the rotation in form of an axis and a rotation angle. func (quat *T) AxisAngle() (axis vec3.T, angle float32) { cos := quat[3] sin := math.Sqrt(1 - cos*cos) angle = math.Acos(cos) var ooSin float32 if math.Abs(sin) < 0.0005 { ooSin = 1 } else { ooSin = 1 / sin } axis[0] = quat[0] * ooSin axis[1] = quat[1] * ooSin axis[2] = quat[2] * ooSin return axis, angle }