Skip to content

Commit f5ae62d

Browse files
committed
Init Point and Vector
1 parent 0ce1b6b commit f5ae62d

File tree

14 files changed

+457
-3
lines changed

14 files changed

+457
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
77

88

99
## [Unreleased](https://github.com/gravitton/geometry/compare/v1.0.0...master)
10+
### Added
11+
- `Point`
12+
- `Vector`

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
[![Go Dev Reference][ico-go-dev-reference]][link-go-dev-reference]
99
[![Software License][ico-license]][link-licence]
1010

11-
2D geometry library for game development.
11+
Generic immutable 2D geometry library for game development.
1212

1313

1414
## Installation
@@ -24,7 +24,7 @@ go get github.com/gravitton/geometry
2424
package main
2525

2626
import (
27-
"github.com/gravitton/geometry"
27+
geom "github.com/gravitton/geometry"
2828
)
2929
```
3030

constraints.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package geom
2+
3+
type Number interface {
4+
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~float32 | ~float64
5+
}

doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
package geometry
1+
package geom

format.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package geom
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
// IsInt checks if Number is integer value
8+
func IsInt[T Number](value T) bool {
9+
return float64(value) == float64(int(value))
10+
}
11+
12+
// ToString format Number as numeric string
13+
func ToString[T Number](value T) string {
14+
if IsInt(value) {
15+
return fmt.Sprintf("%+d", int(value))
16+
} else {
17+
return fmt.Sprintf("%+.2f", float64(value))
18+
}
19+
}

format_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package geom
2+
3+
import (
4+
"github.com/gravitton/assert"
5+
"math"
6+
"testing"
7+
)
8+
9+
func TestIsInt(t *testing.T) {
10+
testIsInt(t, 1, true)
11+
testIsInt(t, -2, true)
12+
testIsInt(t, 986, true)
13+
testIsInt(t, 1.0, true)
14+
testIsInt(t, -2.0, true)
15+
testIsInt(t, 189.2, false)
16+
testIsInt(t, -9.3333, false)
17+
testIsInt(t, 1.000001, false)
18+
testIsInt(t, 23.0000000, true)
19+
testIsInt(t, math.NaN(), false)
20+
testIsInt(t, math.Inf(1), false)
21+
}
22+
23+
func TestToString(t *testing.T) {
24+
testToString(t, 3, "+3")
25+
testToString(t, -2, "-2")
26+
testToString(t, 0.0000, "+0")
27+
testToString(t, 1.00, "+1")
28+
testToString(t, 29.59, "+29.59")
29+
testToString(t, 1.001, "+1.00")
30+
testToString(t, 1.009, "+1.01")
31+
testToString(t, -1.011, "-1.01")
32+
}
33+
34+
func testIsInt[T Number](t *testing.T, value T, expected bool) {
35+
t.Helper()
36+
37+
assert.Equal(t, IsInt(value), expected)
38+
}
39+
40+
func testToString[T Number](t *testing.T, value T, expected string) {
41+
t.Helper()
42+
43+
assert.Equal(t, ToString(value), expected)
44+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module github.com/gravitton/geometry
22

33
go 1.24
4+
5+
require github.com/gravitton/assert v0.4.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/gravitton/assert v0.4.0 h1:uZVoJb79XoUpDYq0GBUHCJI3sS6mieOmoq+ZuXf2wvc=
2+
github.com/gravitton/assert v0.4.0/go.mod h1:t/H52Szce7uofC0H1sN9yLZsj1TBvky5sGmrFiaxypY=

math.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package geom
2+
3+
import "math"
4+
5+
const (
6+
Delta float64 = 1e-6
7+
)
8+
9+
// Midpoint calculate midpoint (point exactly halfway between two points)
10+
// Shorthand for `lerp(a, b, 0.5)`
11+
// TODO: fix rounding for int numbers
12+
func Midpoint[T Number](a, b T) T {
13+
return T(midpoint(float64(a), float64(b)))
14+
}
15+
16+
func midpoint(a, b float64) float64 {
17+
// optimized `a + (b-a)/2.0`
18+
// return lerp(a, b, 0.5)
19+
return (a + b) / 2.0
20+
}
21+
22+
// Lerp calculate linear interpolation (point along a line between two points based on a given ratio)
23+
// TODO: fix rounding for int numbers
24+
func Lerp[T Number](a, b T, t float64) T {
25+
return T(lerp(float64(a), float64(b), t))
26+
}
27+
28+
func lerp(a, b, t float64) float64 {
29+
// optimized `a + (b-a)*t`
30+
return a*(1-t) + b*t
31+
}
32+
33+
// Equal checks for nearly-equal values in Delta
34+
func Equal[T Number](a, b T) bool {
35+
return EqualDelta(a, b, Delta)
36+
}
37+
38+
// Equal checks for nearly-equal values in given delta
39+
func EqualDelta[T Number](a, b T, delta float64) bool {
40+
return equalDelta(float64(a), float64(b), delta)
41+
}
42+
43+
func equalDelta(a, b, delta float64) bool {
44+
return math.Abs(a-b) <= delta
45+
}

math_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package geom
2+
3+
import (
4+
"github.com/gravitton/assert"
5+
"testing"
6+
)
7+
8+
func TestMidpoint(t *testing.T) {
9+
assert.Equal(t, Midpoint(1, 4), 2)
10+
assert.Equal(t, Midpoint(1, 5), 3)
11+
assert.Equal(t, Midpoint(1, 6), 3)
12+
13+
assert.Equal(t, Midpoint(1.0, 6.0), 3.5)
14+
}
15+
16+
func TestLerp(t *testing.T) {
17+
assert.Equal(t, Lerp(1, 4, 0.25), 1)
18+
assert.Equal(t, Lerp(1, 5, 0.25), 2)
19+
assert.Equal(t, Lerp(1, 6, 0.25), 2)
20+
21+
assert.Equal(t, Lerp(1.0, 6.0, 0.25), 2.25)
22+
assert.Equal(t, Lerp(1.0, 6.0, 0.75), 4.75)
23+
24+
}

0 commit comments

Comments
 (0)