// Vec2 is a generic 2D integer vector. // // It supports different underlying integer types (e.g., int, uint8) via type // parameters. // // For float-based positions, use rl.Vector2 instead. package core import ( "math" rl "github.com/gen2brain/raylib-go/raylib" "golang.org/x/exp/constraints" ) type Vec2[T constraints.Integer] struct { X, Y T } func NewVec2[T constraints.Integer](x, y T) Vec2[T] { return Vec2[T]{ X: x, Y: y, } } func Vec2From[T constraints.Integer, Y constraints.Integer](v Vec2[T]) Vec2[Y] { return Vec2[Y]{ X: Y(v.X), Y: Y(v.Y), } } func Vec2FromRL[T constraints.Integer](v rl.Vector2) Vec2[T] { return Vec2[T]{ X: T(v.X), Y: T(v.Y), } } func (v1 Vec2[T]) Add(v2 Vec2[T]) Vec2[T] { return Vec2[T]{ X: v1.X + v2.X, Y: v1.Y + v2.Y, } } func (v1 Vec2[T]) Subtract(v2 Vec2[T]) Vec2[T] { return Vec2[T]{ X: v1.X - v2.X, Y: v1.Y - v2.Y, } } func AbsDist[T constraints.Integer](a T, b T) T { if a > b { return a - b } return b - a } func Abs[T constraints.Integer](value T) T { if value < T(0) { return -value } return value } func (v1 Vec2[T]) Abs() Vec2[T] { return Vec2[T]{ X: Abs(v1.X), Y: Abs(v1.Y), } } func (v1 Vec2[T]) SubtractABS(v2 Vec2[T]) Vec2[T] { return Vec2[T]{ X: AbsDist(v1.X, v2.X), Y: AbsDist(v1.Y, v2.Y), } } func (v Vec2[T]) Scale(value float32) Vec2[T] { return Vec2[T]{ X: T(float32(v.X) * value), Y: T(float32(v.Y) * value), } } func (v1 Vec2[T]) Distance(v2 Vec2[T]) float64 { abs := v1.SubtractABS(v2) dx := float64(abs.X) dy := float64(abs.Y) return math.Sqrt((dx * dx) + (dy * dy)) } // ToRL converts the Vec2 to a rl.Vector2 (float32), which is compatible // with rendering and physics systems. func (v Vec2[T]) ToRL() rl.Vector2 { return rl.NewVector2(float32(v.X), float32(v.Y)) } // AddRL adds a float-based rl.Vector2 to the current Vec2, // returning a new Vec2 after converting the result back to type T. // Fractional parts are truncated. func (v1 Vec2[T]) AddRL(v2 rl.Vector2) Vec2[T] { v1.X += T(v2.X) v1.Y += T(v2.Y) return v1 } // Common Vec2 type aliases for convenience. type ( Vec2i = Vec2[int] Vec2i8 = Vec2[int8] Vec2i16 = Vec2[int16] Vec2i32 = Vec2[int32] Vec2i64 = Vec2[int64] Vec2u = Vec2[uint] Vec2u8 = Vec2[uint8] Vec2u16 = Vec2[uint16] Vec2u32 = Vec2[uint32] Vec2u64 = Vec2[uint64] )