advmath/vec3.go
2022-08-23 21:12:45 +02:00

80 lines
1.7 KiB
Go

package advmath
import (
"fmt"
"math"
)
type Vec3[N Real] struct {
x N
y N
z N
}
func V3[N Real](x, y, z N) Vec3[N] {
return Vec3[N]{x, y, z}
}
func (v Vec3[N]) X() N {
return v.x
}
func (v Vec3[N]) Y() N {
return v.y
}
func (v Vec3[N]) Z() N {
return v.z
}
func (v Vec3[N]) W() N {
return 0
}
func (v Vec3[N]) Add(o Vec[N, Vec3[N]]) Vec[N, Vec3[N]] {
return Vec3[N]{v.X() + o.X(), v.Y() + o.Y(), v.Z() + o.Z()}
}
func (v Vec3[N]) Sub(o Vec[N, Vec3[N]]) Vec[N, Vec3[N]] {
return Vec3[N]{v.X() - o.X(), v.Y() - o.Y(), v.Z() - o.Z()}
}
func (v Vec3[N]) Mul(o Vec[N, Vec3[N]]) Vec[N, Vec3[N]] {
return Vec3[N]{v.X() * o.X(), v.Y() * o.Y(), v.Z() * o.Z()}
}
func (v Vec3[N]) Div(o Vec[N, Vec3[N]]) Vec[N, Vec3[N]] {
return Vec3[N]{v.X() / o.X(), v.Y() / o.Y(), v.Z() / o.Z()}
}
func (v Vec3[N]) Len() N {
return N(math.Sqrt(float64(v.X()*v.X() + v.Y()*v.Y() + v.Z()*v.Z())))
}
func (v Vec3[N]) Norm() Vec[N, Vec3[N]] {
l := v.Len()
return Vec3[N]{v.X() / l, v.Y() / l, v.Z() / l}
}
func (v Vec3[N]) Dot(o Vec[N, Vec3[N]]) N {
return N(v.X()*o.X() + v.Y()*o.Y() + v.Z()*o.Z())
}
func (v Vec3[N]) Cross(o Vec3[N]) Vec3[N] {
return Vec3[N]{v.Y()*o.Z() - v.Z()*o.Y(), v.Z()*o.X() - v.X()*o.Z(), v.X()*o.Y() - v.Y()*o.X()}
}
func (v Vec3[N]) Lerp(o Vec[N, Vec3[N]], t N) Vec[N, Vec3[N]] {
t1 := 1 - t
return v.Mul(V3(t1, t1, t1)).Add(o.Mul(V3(t, t, t)))
}
func (v Vec3[N]) String() string {
const decimals = 100000
return fmt.Sprintf("(%g | %g | %g)", math.Round(float64(v.X())*decimals)/decimals, math.Round(float64(v.Y())*decimals)/decimals, math.Round(float64(v.Z())*decimals)/decimals)
}
func (v Vec3[N]) StringPrecise() string {
return fmt.Sprintf("(%f | %f | %f)", float64(v.X()), float64(v.Y()), float64(v.Z()))
}