circle radius
This commit is contained in:
@@ -2,6 +2,32 @@ 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))
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package util_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"galaxy/util"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestShortDistance(t *testing.T) {
|
||||
@@ -54,3 +56,96 @@ func TestNextTravelCoord(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrapF(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
value float64
|
||||
size int
|
||||
want float64
|
||||
}{
|
||||
{
|
||||
name: "already in range integer",
|
||||
value: 3,
|
||||
size: 10,
|
||||
want: 3,
|
||||
},
|
||||
{
|
||||
name: "already in range fractional",
|
||||
value: 3.25,
|
||||
size: 10,
|
||||
want: 3.25,
|
||||
},
|
||||
{
|
||||
name: "positive overflow integer",
|
||||
value: 12,
|
||||
size: 10,
|
||||
want: 2,
|
||||
},
|
||||
{
|
||||
name: "positive overflow fractional",
|
||||
value: 12.75,
|
||||
size: 10,
|
||||
want: 2.75,
|
||||
},
|
||||
{
|
||||
name: "negative small fractional",
|
||||
value: -0.25,
|
||||
size: 10,
|
||||
want: 9.75,
|
||||
},
|
||||
{
|
||||
name: "negative overflow integer",
|
||||
value: -12,
|
||||
size: 10,
|
||||
want: 8,
|
||||
},
|
||||
{
|
||||
name: "negative overflow fractional",
|
||||
value: -12.75,
|
||||
size: 10,
|
||||
want: 7.25,
|
||||
},
|
||||
{
|
||||
name: "exact multiple positive",
|
||||
value: 20,
|
||||
size: 10,
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "exact multiple negative",
|
||||
value: -20,
|
||||
size: 10,
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "size one wraps into [0,1)",
|
||||
value: 123.456,
|
||||
size: 1,
|
||||
want: math.Mod(123.456, 1),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := util.WrapF(tt.value, tt.size)
|
||||
require.InDelta(t, tt.want, got, 1e-12)
|
||||
require.GreaterOrEqual(t, got, 0.0)
|
||||
require.Less(t, got, float64(tt.size))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestWrapF_NaNAndInf verifies IEEE 754 behavior inherited from math.Mod.
|
||||
func TestWrapF_NaNAndInf(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.True(t, math.IsNaN(util.WrapF(math.NaN(), 10)))
|
||||
require.True(t, math.IsNaN(util.WrapF(math.Inf(1), 10)))
|
||||
require.True(t, math.IsNaN(util.WrapF(math.Inf(-1), 10)))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user