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