func (a XYZ) XYproj() XY {
	return XY{a.X / a.Z, a.Y / a.Z}
}
//////////////////////////////////////////////////////////////////////////////
XYproj returns the cartesian representation of the vector (i.e. the perspective
divide of the homogeneous coordinates). Z must be non-zero.
package coord
import (
	"math"
	"github.com/cozely/cozely/x/math32"
)
type XYZ struct {
	X float32
	Y float32
	Z float32
}
func (a XYZ) Cartesian() (x, y, z float32) {
	return a.X, a.Y, a.Z
}
func (a XYZ) XYZW(w float32) XYZW {
	return XYZW{a.X, a.Y, a.Z, w}
}
func (a XYZ) Plus(b XYZ) XYZ {
	return XYZ{a.X + b.X, a.Y + b.Y, a.Z + b.Z}
}
func (a XYZ) Minus(b XYZ) XYZ {
	return XYZ{a.X - b.X, a.Y - b.Y, a.Z - b.Z}
}
func (a XYZ) Opposite() XYZ {
	return XYZ{-a.X, -a.Y, -a.Z}
}
func (a XYZ) Times(s float32) XYZ {
	return XYZ{a.X * s, a.Y * s, a.Z * s}
}
func (a XYZ) TimesCW(b XYZ) XYZ {
	return XYZ{a.X * b.X, a.Y * b.Y, a.Z * b.Z}
}
func (a XYZ) Slash(s float32) XYZ {
	return XYZ{a.X / s, a.Y / s, a.Z / s}
}
func (a XYZ) SlashCW(b XYZ) XYZ {
	return XYZ{a.X / b.X, a.Y / b.Y, a.Z / b.Z}
}
func (a XYZ) Mod(s float32) XYZ {
	return XYZ{math32.Mod(a.X, s), math32.Mod(a.Y, s), math32.Mod(a.Z, s)}
}
func (a XYZ) ModCW(b XYZ) XYZ {
	return XYZ{math32.Mod(a.X, b.X), math32.Mod(a.Y, b.Y), math32.Mod(a.Z, b.Z)}
}
func (a XYZ) Modf() (intg, frac XYZ) {
	xintg, xfrac := math32.Modf(a.X)
	yintg, yfrac := math32.Modf(a.Y)
	zintg, zfrac := math32.Modf(a.Z)
	return XYZ{xintg, yintg, zintg}, XYZ{xfrac, yfrac, zfrac}
}
func (a XYZ) Dot(b XYZ) float32 {
	return a.X*b.X + a.Y*b.Y + a.Z*b.Z
}
func (a XYZ) Cross(b XYZ) XYZ {
	return XYZ{
		a.Y*b.Z - a.Z*b.Y,
		a.Z*b.X - a.X*b.Z,
		a.X*b.Y - a.Y*b.X,
	}
}
func (a XYZ) Length() float32 {
	return float32(math.Sqrt(float64(a.X*a.X + a.Y*a.Y + a.Z*a.Z)))
}
func (a XYZ) Length2() float32 {
	return a.X*a.X + a.Y*a.Y + a.Z*a.Z
}
func (a XYZ) Distance(b XYZ) float32 {
	d := XYZ{a.X - b.X, a.Y - b.Y, a.Z - b.Z}
	return float32(math.Sqrt(float64(d.X*d.X + d.Y*d.Y + d.Z*d.Z)))
}
func (a XYZ) Distance2(b XYZ) float32 {
	d := XYZ{a.X - b.X, a.Y - b.Y, a.Z - b.Z}
	return d.X*d.X + d.Y*d.Y + d.Z*d.Z
}
func (a XYZ) Normalized() XYZ {
	l := float32(math.Sqrt(float64(a.X*a.X + a.Y*a.Y + a.Z*a.Z)))
	return XYZ{a.X / l, a.Y / l, a.Z / l}
}
func (a XYZ) IsAlmostEqual(b XYZ, ulps uint32) bool {
	return math32.IsAlmostEqual(a.X, b.X, ulps) &&
		math32.IsAlmostEqual(a.Y, b.Y, ulps) &&
		math32.IsAlmostEqual(a.Z, b.Z, ulps)
}
func (a XYZ) IsNearlyEqual(b XYZ, epsilon float32) bool {
	return math32.IsNearlyEqual(a.X, b.X, epsilon) &&
		math32.IsNearlyEqual(a.Y, b.Y, epsilon) &&
		math32.IsNearlyEqual(a.Z, b.Z, epsilon)
}
func (a XYZ) IsRoughlyEqual(b XYZ, epsilon float32) bool {
	return math32.IsRoughlyEqual(a.X, b.X, epsilon) &&
		math32.IsRoughlyEqual(a.Y, b.Y, epsilon) &&
		math32.IsRoughlyEqual(a.Z, b.Z, epsilon)
}