func (qin Quaternion) RotateVec3(vec Vec3) Vec3 {
	conj := qin.Conj()
	aug := Quaternion{0, vec.X, vec.Y, vec.Z}
	rot := Prod(qin, aug, conj)
	return Vec3{rot.X, rot.Y, rot.Z}
}
RotateVec3 returns the vector rotated by the quaternion.
package quaternion
import (
	"math"
)
func New(w, x, y, z float64) Quaternion {
	return Quaternion{W: w, X: x, Y: y, Z: z}
}
func Pure(x, y, z float64) Quaternion {
	return Quaternion{X: x, Y: y, Z: z}
}
type Vec3 struct {
	X float64
	Y float64
	Z float64
}
type Quaternion struct {
	W float64  
	X float64  
	Y float64  
	Z float64  
}
func (qin Quaternion) Conj() Quaternion {
	qin.X = -qin.X
	qin.Y = -qin.Y
	qin.Z = -qin.Z
	return qin
}
func (qin Quaternion) Norm2() float64 {
	return qin.W*qin.W + qin.X*qin.X + qin.Y*qin.Y + qin.Z*qin.Z
}
func (qin Quaternion) Neg() Quaternion {
	qin.W = -qin.W
	qin.X = -qin.X
	qin.Y = -qin.Y
	qin.Z = -qin.Z
	return qin
}
func (qin Quaternion) Norm() float64 {
	return math.Sqrt(qin.Norm2())
}
func Scalar(w float64) Quaternion {
	return Quaternion{W: w}
}
func Sum(qin ...Quaternion) Quaternion {
	qout := Quaternion{}
	for _, q := range qin {
		qout.W += q.W
		qout.X += q.X
		qout.Y += q.Y
		qout.Z += q.Z
	}
	return qout
}
func Prod(qin ...Quaternion) Quaternion {
	qout := Quaternion{1, 0, 0, 0}
	var w, x, y, z float64
	for _, q := range qin {
		w = qout.W*q.W - qout.X*q.X - qout.Y*q.Y - qout.Z*q.Z
		x = qout.W*q.X + qout.X*q.W + qout.Y*q.Z - qout.Z*q.Y
		y = qout.W*q.Y + qout.Y*q.W + qout.Z*q.X - qout.X*q.Z
		z = qout.W*q.Z + qout.Z*q.W + qout.X*q.Y - qout.Y*q.X
		qout = Quaternion{w, x, y, z}
	}
	return qout
}
func (qin Quaternion) Unit() Quaternion {
	k := qin.Norm()
	return Quaternion{qin.W / k, qin.X / k, qin.Y / k, qin.Z / k}
}
func (qin Quaternion) Inv() Quaternion {
	k2 := qin.Norm2()
	q := qin.Conj()
	return Quaternion{q.W / k2, q.X / k2, q.Y / k2, q.Z / k2}
}