func (vn *VecN) Vec4() Vec4 {
	raw := vn.Raw()
	return Vec4{raw[0], raw[1], raw[2], raw[3]}
}
Vec4 constructs a 4-dimensional vector by discarding coordinates.
package mgl32
import (
	"math"
)
type VecN struct {
	vec []float32
}
func NewVecNFromData(initial []float32) *VecN {
	if initial == nil {
		return &VecN{}
	}
	var internal []float32
	if shouldPool {
		internal = grabFromPool(len(initial))
	} else {
		internal = make([]float32, len(initial))
	}
	copy(internal, initial)
	return &VecN{vec: internal}
}
func NewVecN(n int) *VecN {
	if shouldPool {
		return &VecN{vec: grabFromPool(n)}
	} else {
		return &VecN{vec: make([]float32, n)}
	}
}
func (vn VecN) Raw() []float32 {
	return vn.vec
}
func (vn VecN) Get(i int) float32 {
	return vn.vec[i]
}
func (vn *VecN) Set(i int, val float32) {
	vn.vec[i] = val
}
func (vn *VecN) destroy() {
	if vn == nil || vn.vec == nil {
		return
	}
	if shouldPool {
		returnToPool(vn.vec)
	}
	vn.vec = nil
}
func (vn *VecN) Resize(n int) *VecN {
	if vn == nil {
		return NewVecN(n)
	}
	if n <= cap(vn.vec) {
		if vn.vec != nil {
			vn.vec = vn.vec[:n]
		} else {
			vn.vec = []float32{}
		}
		return vn
	}
	if shouldPool && vn.vec != nil {
		returnToPool(vn.vec)
	}
	*vn = (*NewVecN(n))
	return vn
}
func (vn *VecN) SetBackingSlice(newSlice []float32) {
	vn.vec = newSlice
}
func (vn *VecN) Size() int {
	return len(vn.vec)
}
func (vn *VecN) Cap() int {
	return cap(vn.vec)
}
func (vn *VecN) Zero(n int) {
	vn.Resize(n)
	for i := range vn.vec {
		vn.vec[i] = 0
	}
}
func (vn *VecN) Add(dst *VecN, subtrahend *VecN) *VecN {
	if vn == nil || subtrahend == nil {
		return nil
	}
	size := intMin(len(vn.vec), len(subtrahend.vec))
	dst = dst.Resize(size)
	for i := 0; i < size; i++ {
		dst.vec[i] = vn.vec[i] + subtrahend.vec[i]
	}
	return dst
}
func (vn *VecN) Sub(dst *VecN, addend *VecN) *VecN {
	if vn == nil || addend == nil {
		return nil
	}
	size := intMin(len(vn.vec), len(addend.vec))
	dst = dst.Resize(size)
	for i := 0; i < size; i++ {
		dst.vec[i] = vn.vec[i] - addend.vec[i]
	}
	return dst
}
func (vn *VecN) Cross(dst *VecN, other *VecN) *VecN {
	if vn == nil || other == nil {
		return nil
	}
	if len(vn.vec) != 3 || len(other.vec) != 3 {
		panic("Cannot take binary cross product of non-3D elements (7D cross product not implemented)")
	}
	dst = dst.Resize(3)
	dst.vec[0], dst.vec[1], dst.vec[2] = vn.vec[1]*other.vec[2]-vn.vec[2]*other.vec[1], vn.vec[2]*other.vec[0]-vn.vec[0]*other.vec[2], vn.vec[0]*other.vec[1]-vn.vec[1]*other.vec[0]
	return dst
}
func intMin(a, b int) int {
	if a < b {
		return a
	}
	return b
}
func (vn *VecN) Dot(other *VecN) float32 {
	if vn == nil || other == nil || len(vn.vec) != len(other.vec) {
		return float32(math.NaN())
	}
	var result float32 = 0.0
	for i, el := range vn.vec {
		result += el * other.vec[i]
	}
	return result
}
func (vn *VecN) Len() float32 {
	if vn == nil {
		return float32(math.NaN())
	}
	if len(vn.vec) == 0 {
		return 0
	}
	return float32(math.Sqrt(float64(vn.Dot(vn))))
}
func (vn *VecN) LenSqr() float32 {
	if vn == nil {
		return float32(math.NaN())
	}
	if len(vn.vec) == 0 {
		return 0
	}
	return vn.Dot(vn)
}
func (vn *VecN) Normalize(dst *VecN) *VecN {
	if vn == nil {
		return nil
	}
	return vn.Mul(dst, 1/vn.Len())
}
func (vn *VecN) Mul(dst *VecN, c float32) *VecN {
	if vn == nil {
		return nil
	}
	dst = dst.Resize(len(vn.vec))
	for i, el := range vn.vec {
		dst.vec[i] = el * c
	}
	return dst
}
func (vn *VecN) OuterProd(dst *MatMxN, v2 *VecN) *MatMxN {
	if vn == nil || v2 == nil {
		return nil
	}
	dst = dst.Reshape(len(vn.vec), len(v2.vec))
	for c, el1 := range v2.vec {
		for r, el2 := range vn.vec {
			dst.Set(r, c, el1*el2)
		}
	}
	return dst
}
func (vn *VecN) ApproxEqual(vn2 *VecN) bool {
	if vn == nil || vn2 == nil || len(vn.vec) != len(vn2.vec) {
		return false
	}
	for i, el := range vn.vec {
		if !FloatEqual(el, vn2.vec[i]) {
			return false
		}
	}
	return true
}
func (vn *VecN) ApproxEqualThreshold(vn2 *VecN, epsilon float32) bool {
	if vn == nil || vn2 == nil || len(vn.vec) != len(vn2.vec) {
		return false
	}
	for i, el := range vn.vec {
		if !FloatEqualThreshold(el, vn2.vec[i], epsilon) {
			return false
		}
	}
	return true
}
func (vn *VecN) ApproxEqualFunc(vn2 *VecN, comp func(float32, float32) bool) bool {
	if vn == nil || vn2 == nil || len(vn.vec) != len(vn2.vec) {
		return false
	}
	for i, el := range vn.vec {
		if !comp(el, vn2.vec[i]) {
			return false
		}
	}
	return true
}
func (vn *VecN) Vec2() Vec2 {
	raw := vn.Raw()
	return Vec2{raw[0], raw[1]}
}
func (vn *VecN) Vec3() Vec3 {
	raw := vn.Raw()
	return Vec3{raw[0], raw[1], raw[2]}
}