Files
galaxy-game/pkg/util/map.go
T
Ilia Denisov 73a4b0d3ec circle radius
2026-03-22 19:43:09 +02:00

108 lines
2.0 KiB
Go

package util
import "math"
// WrapF maps value into the half-open interval [0, float64(size)).
// It supports negative input values and is used for torus coordinates
// when the coordinate is represented as float64.
//
// size must be greater than zero.
func WrapF(value float64, size int) float64 {
if size <= 0 {
panic("WrapF: size must be > 0")
}
s := float64(size)
r := math.Mod(value, s)
if r < 0 {
r += s
}
// Protect against a possible boundary artifact and keep result in [0, s).
// In normal cases math.Mod already gives a value with |r| < s.
if r >= s {
r -= s
}
return r
}
func ShortDistance(w, h uint32, x1, y1, x2, y2 float64) float64 {
return math.Hypot(deltas(w, h, x1, y1, x2, y2))
}
func NextTravelCoord(w, h uint32, x1, y1, x2, y2, delta float64) (float64, float64, bool) {
deltaX, deltaY := deltas(w, h, x1, y1, x2, y2)
distance := math.Hypot(deltaX, deltaY)
if distance <= delta {
return x2, y2, true
}
// [ ] refactor - remove extra vars
xa := 0.
ya := 0.
xb := deltaX
yb := deltaY
d := distance
d2 := delta
xc := xa - (d2*(xa-xb))/d
yc := ya - (d2*(ya-yb))/d
// ---
var tx, ty float64
if math.Abs(x2-x1) > float64(w/2) {
// moving across X boundary
if x2 < x1 {
// moving across higher border
tx = math.Mod(x1+xc, float64(w))
} else {
// moving across lower border
tx = x1 - xc
if tx < 0 {
tx = float64(w) + tx
}
}
} else {
if x2 < x1 {
tx = x1 - xc
} else {
tx = x1 + xc
}
}
if math.Abs(y2-y1) > float64(h/2) {
// moving across Y boundary
if y2 < y1 {
// moving across higher border
ty = math.Mod(y1+yc, float64(h))
} else {
// moving across lower border
ty = y1 - yc
if ty < 0 {
ty = float64(h) + ty
}
}
} else {
if y2 < y1 {
ty = y1 - yc
} else {
ty = y1 + yc
}
}
return tx, ty, false
}
func deltas(w, h uint32, x1, y1, x2, y2 float64) (float64, float64) {
dx := math.Abs(x2 - x1)
dy := math.Abs(y2 - y1)
if dx > float64(w/2) {
dx = float64(h) - dx
}
if dy > float64(h/2) {
dy = float64(h) - dy
}
return dx, dy
}