Skip to content

Commit

Permalink
Replace Mid and MidInt with one generic function Mid
Browse files Browse the repository at this point in the history
This new function accepts integers, floats and even strings
  • Loading branch information
elgopher committed Jul 30, 2023
1 parent 8e6a697 commit 3c5994d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 56 deletions.
3 changes: 1 addition & 2 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
* [ ] map API
* [ ] math API
* [x] Cos, Sin, Atan2
* [x] Mid for integers
* [x] Mid for float64
* [x] Generic Mid for float64 and integers
* [x] Game controller support: gamepad and keyboard
* [x] Mouse support
* [ ] Add mouse wheel support
Expand Down
42 changes: 9 additions & 33 deletions math.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

package pi

import "math"
import (
"cmp"
"math"
)

// Sin returns the sine of angle which is in the range of 0.0-1.0 measured clockwise.
//
Expand Down Expand Up @@ -36,42 +39,15 @@ func Atan2(dx, dy float64) float64 {
return math.Mod(0.75+v/(math.Pi*2), 1)
}

// Int is a generic type for all integer types
type Int interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
}

// MidInt returns the middle of three integer numbers. Very useful for clamping.
func MidInt[T Int](x, y, z T) T {
if x > y {
x, y = y, x
}

if y > z {
y = z
}

if x > y {
y = x
}

return y
}

// Mid returns the middle of three float64 numbers. Very useful for clamping.
// NaNs are always put at the beginning (are the smallest ones).
func Mid(x, y, z float64) float64 {
if x > y || math.IsNaN(y) {
x, y = y, x
}

if y > z || math.IsNaN(z) {
y = z
}

if x > y || math.IsNaN(y) {
y = x
}
// Mid returns the middle of three numbers. Very useful for clamping.
func Mid[T cmp.Ordered](x, y, z T) T {
x, y = min(x, y), max(x, y)
y = min(y, z)
y = max(x, y)

return y
}
40 changes: 19 additions & 21 deletions math_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,33 +114,31 @@ func TestAtan2(t *testing.T) {
}
}

func TestMidInt(t *testing.T) {
assert.Equal(t, 0, pi.MidInt(0, 0, 0))
assert.Equal(t, 1, pi.MidInt(0, 1, 2))
assert.Equal(t, 1, pi.MidInt(2, 1, 0))
assert.Equal(t, 1, pi.MidInt(1, 0, 2))
assert.Equal(t, 1, pi.MidInt(1, 2, 0))
assert.Equal(t, 1, pi.MidInt(2, 0, 1))
assert.Equal(t, 1, pi.MidInt(0, 2, 1))
assert.Equal(t, -1, pi.MidInt(0, -1, -2))
}

func TestMid(t *testing.T) {
assert.Equal(t, 0.0, pi.Mid(0, 0, 0))
assert.Equal(t, 1.0, pi.Mid(0, 1, 2))
assert.Equal(t, 1.0, pi.Mid(2, 1, 0))
assert.Equal(t, 1.0, pi.Mid(1, 0, 2))
assert.Equal(t, 1.0, pi.Mid(1, 2, 0))
assert.Equal(t, 1.0, pi.Mid(2, 0, 1))
assert.Equal(t, 1.0, pi.Mid(0, 2, 1))
assert.Equal(t, -1.0, pi.Mid(0, -1, -2))
assert.Equal(t, 0, pi.Mid(0, 0, 0))
assert.Equal(t, 1, pi.Mid(0, 1, 2))
assert.Equal(t, 1, pi.Mid(2, 1, 0))
assert.Equal(t, 1, pi.Mid(1, 0, 2))
assert.Equal(t, 1, pi.Mid(1, 2, 0))
assert.Equal(t, 1, pi.Mid(2, 0, 1))
assert.Equal(t, 1, pi.Mid(0, 2, 1))
assert.Equal(t, -1, pi.Mid(0, -1, -2))

assert.Equal(t, 0.0, pi.Mid(0.0, 0.0, 0.0))
assert.Equal(t, 1.0, pi.Mid(0.0, 1.0, 2.0))
assert.Equal(t, 1.0, pi.Mid(2.0, 1.0, 0.0))
assert.Equal(t, 1.0, pi.Mid(1.0, 0.0, 2.0))
assert.Equal(t, 1.0, pi.Mid(1.0, 2.0, 0.0))
assert.Equal(t, 1.0, pi.Mid(2.0, 0.0, 1.0))
assert.Equal(t, 1.0, pi.Mid(0.0, 2.0, 1.0))
assert.Equal(t, -1.0, pi.Mid(0.0, -1.0, -2.0))

assertNaN(t, pi.Mid(math.NaN(), math.NaN(), math.NaN()))
assertInf(t, pi.Mid(math.Inf(1), math.Inf(1), math.Inf(1)), 1)
assert.Equal(t, 1.0, pi.Mid(1.0, math.NaN(), 2.0)) // NaNs always go to the beginning
assertNaN(t, pi.Mid(1.0, math.NaN(), 2.0))
assertNaN(t, pi.Mid(math.NaN(), math.NaN(), 1.0))
assertNaN(t, pi.Mid(1.0, math.NaN(), math.NaN()))
assert.Equal(t, 1.0, pi.Mid(1.0, 2.0, math.NaN()))
assertNaN(t, pi.Mid(1.0, 2.0, math.NaN()))
assert.Equal(t, 1.0, pi.Mid(math.Inf(1), math.Inf(-1), 1.0))
}

Expand Down

0 comments on commit 3c5994d

Please sign in to comment.