1
0
Fork 0
tetris-go/engine/core/vec2.go

125 lines
2.3 KiB
Go

// 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]
)