Skip to content

Commit f17f285

Browse files
committed
Refactor shorthand constructors and tests for geometric types, update naming conventions for clarity
1 parent 0e37d4d commit f17f285

23 files changed

+582
-434
lines changed

README.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
Generic immutable 2D geometry library for game development.
1111

12+
This library use top-left origin with +Y down and -Y up. It only affect human-readable getters like `(Top|Bottom)Left()`, `(Top|Bottom)Right()` and `(Up/Down)Vector`.
13+
1214

1315
## Installation
1416

@@ -25,6 +27,17 @@ package main
2527
import (
2628
geom "github.com/gravitton/geometry"
2729
)
30+
31+
type HexLayout struct {
32+
Origin geom.Point[float64]
33+
Size geom.Size[float64]
34+
FromPixel geom.Matrix
35+
}
36+
37+
// FromPoint converts a pixel point to a fractional hex (Q, R)
38+
func (l HexLayout) FromPixel(point geom.Point[float64]) (Q, R float64) {
39+
return point.Subtract(l.Origin).DivideXY(l.Size.XY()).Transform(l.FromPixel).XY()
40+
}
2841
```
2942

3043
## API
@@ -327,14 +340,15 @@ func (rp RegularPolygon[T]) ToPolygon() Polygon[T]
327340
Short constructors for convenience
328341

329342
```go
330-
func P[T Number](x, y T) Point[T]
331-
func V[T Number](x, y T) Vector[T]
332-
func S[T Number](w, h T) Size[T]
333-
func C[T Number](center Point[T], radius T) Circle[T]
334-
func R[T Number](center Point[T], size Size[T]) Rectangle[T]
335-
func L[T Number](start, end Point[T]) Line[T]
336-
func RP[T Number](center Point[T], size Size[T], n int, angle float64) RegularPolygon[T]
337-
func M(a, b, c, d, e, f float64) Matrix
343+
func Pt[T Number](x, y T) Point[T]
344+
func Vec[T Number](x, y T) Vector[T]
345+
func Sz[T Number](w, h T) Size[T]
346+
func Circ[T Number](center Point[T], radius T) Circle[T]
347+
func Rect[T Number](center Point[T], size Size[T]) Rectangle[T]
348+
func Ln[T Number](start, end Point[T]) Line[T]
349+
func Pol[T Number](vertices []Point[T]) Polygon[T]
350+
func RegPol[T Number](center Point[T], size Size[T], n int, angle float64) RegularPolygon[T]
351+
func Mat(a, b, c, d, e, f float64) Matrix
338352
```
339353

340354

circle.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ type Circle[T Number] struct {
1111
Radius T `json:"r"`
1212
}
1313

14-
// C is shorthand for Circle{center, radius}.
15-
func C[T Number](center Point[T], radius T) Circle[T] {
14+
// Circ is shorthand for Circle{center, radius}.
15+
func Circ[T Number](center Point[T], radius T) Circle[T] {
1616
return Circle[T]{center, radius}
1717
}
1818

circle_test.go

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,85 +9,85 @@ import (
99
)
1010

1111
func TestCircle_New(t *testing.T) {
12-
testCircle(t, C(P(10, 16), 12), 10, 16, 12)
13-
testCircle(t, C[float64](P(0.16, 204), 5.1), 0.16, 204.0, 5.1)
12+
testCircle(t, Circ(Pt(10, 16), 12), 10, 16, 12)
13+
testCircle(t, Circ[float64](Pt(0.16, 204), 5.1), 0.16, 204.0, 5.1)
1414
}
1515

1616
func TestCircle_Translate(t *testing.T) {
17-
testCircle(t, C(P(1, 2), 10).Translate(V(3, -2)), 4, 0, 10)
18-
testCircle(t, C(P(0.4, -0.25), 1.2).Translate(V(100.1, -0.1)), 100.5, -0.35, 1.2)
17+
testCircle(t, Circ(Pt(1, 2), 10).Translate(Vec(3, -2)), 4, 0, 10)
18+
testCircle(t, Circ(Pt(0.4, -0.25), 1.2).Translate(Vec(100.1, -0.1)), 100.5, -0.35, 1.2)
1919
}
2020

2121
func TestCircle_MoveTo(t *testing.T) {
22-
testCircle(t, C(P(1, 2), 10).MoveTo(P(3, -2)), 3, -2, 10)
23-
testCircle(t, C(P(0.4, -0.25), 1.2).MoveTo(P(100.1, -0.1)), 100.1, -0.1, 1.2)
22+
testCircle(t, Circ(Pt(1, 2), 10).MoveTo(Pt(3, -2)), 3, -2, 10)
23+
testCircle(t, Circ(Pt(0.4, -0.25), 1.2).MoveTo(Pt(100.1, -0.1)), 100.1, -0.1, 1.2)
2424
}
2525

2626
func TestCircle_Scale(t *testing.T) {
27-
testCircle(t, C(P(1, 2), 10).Scale(2.5), 1, 2, 25)
28-
testCircle(t, C(P(0.4, -0.25), 1.2).Scale(2.5), 0.4, -0.25, 3.0)
27+
testCircle(t, Circ(Pt(1, 2), 10).Scale(2.5), 1, 2, 25)
28+
testCircle(t, Circ(Pt(0.4, -0.25), 1.2).Scale(2.5), 0.4, -0.25, 3.0)
2929
}
3030

3131
func TestCircle_Resize(t *testing.T) {
32-
testCircle(t, C(P(1, 2), 10).Resize(8), 1, 2, 8)
33-
testCircle(t, C(P(0.4, -0.25), 1.2).Resize(3.1), 0.4, -0.25, 3.1)
32+
testCircle(t, Circ(Pt(1, 2), 10).Resize(8), 1, 2, 8)
33+
testCircle(t, Circ(Pt(0.4, -0.25), 1.2).Resize(3.1), 0.4, -0.25, 3.1)
3434
}
3535

36-
func TestCircle_Expand(t *testing.T) {
37-
testCircle(t, C(P(1, 2), 10).Grow(8), 1, 2, 18)
38-
testCircle(t, C(P(0.4, -0.25), 1.2).Grow(3.1), 0.4, -0.25, 4.3)
36+
func TestCircle_Grow(t *testing.T) {
37+
testCircle(t, Circ(Pt(1, 2), 10).Grow(8), 1, 2, 18)
38+
testCircle(t, Circ(Pt(0.4, -0.25), 1.2).Grow(3.1), 0.4, -0.25, 4.3)
3939
}
4040

41-
func TestCircle_Shrunk(t *testing.T) {
42-
testCircle(t, C(P(1, 2), 10).Shrink(8), 1, 2, 2)
43-
testCircle(t, C(P(0.4, -0.25), 1.2).Shrink(0.3), 0.4, -0.25, 0.9)
41+
func TestCircle_Shrink(t *testing.T) {
42+
testCircle(t, Circ(Pt(1, 2), 10).Shrink(8), 1, 2, 2)
43+
testCircle(t, Circ(Pt(0.4, -0.25), 1.2).Shrink(0.3), 0.4, -0.25, 0.9)
4444
}
4545

4646
func TestCircle_Area(t *testing.T) {
47-
assert.EqualDelta(t, C(P(1, 2), 10).Area(), math.Pi*100.0, Delta)
48-
assert.EqualDelta(t, C(P(0.4, -0.25), 1.2).Area(), math.Pi*1.44, Delta)
47+
assert.EqualDelta(t, Circ(Pt(1, 2), 10).Area(), math.Pi*100.0, Delta)
48+
assert.EqualDelta(t, Circ(Pt(0.4, -0.25), 1.2).Area(), math.Pi*1.44, Delta)
4949
}
5050

5151
func TestCircle_Circumference(t *testing.T) {
52-
assert.EqualDelta(t, C(P(1, 2), 10).Circumference(), math.Pi*20.0, Delta)
53-
assert.EqualDelta(t, C(P(0.4, -0.25), 1.2).Circumference(), math.Pi*2.4, Delta)
52+
assert.EqualDelta(t, Circ(Pt(1, 2), 10).Circumference(), math.Pi*20.0, Delta)
53+
assert.EqualDelta(t, Circ(Pt(0.4, -0.25), 1.2).Circumference(), math.Pi*2.4, Delta)
5454
}
5555

5656
func TestCircle_Diameter(t *testing.T) {
57-
assert.Equal(t, C(P(1, 2), 10).Diameter(), 20)
58-
assert.EqualDelta(t, C(P(0.4, -0.25), 1.2).Diameter(), 2.4, Delta)
57+
assert.Equal(t, Circ(Pt(1, 2), 10).Diameter(), 20)
58+
assert.EqualDelta(t, Circ(Pt(0.4, -0.25), 1.2).Diameter(), 2.4, Delta)
5959
}
6060

6161
func TestCircle_Bounds(t *testing.T) {
62-
testRect(t, C(P(1, 2), 10).Bounds(), 1, 2, 10, 10)
63-
testRect(t, C(P(0.4, -0.25), 1.2).Bounds(), 0.4, -0.25, 1.2, 1.2)
62+
testRect(t, Circ(Pt(1, 2), 10).Bounds(), 1, 2, 10, 10)
63+
testRect(t, Circ(Pt(0.4, -0.25), 1.2).Bounds(), 0.4, -0.25, 1.2, 1.2)
6464
}
6565

6666
func TestCircle_Equal(t *testing.T) {
67-
assert.False(t, C(P(1, 2), 10).Equal(C(P(3, -3), 10)))
68-
assert.True(t, C(P(1, 2), 10).Equal(C(P(1, 2), 10)))
67+
assert.False(t, Circ(Pt(1, 2), 10).Equal(Circ(Pt(3, -3), 10)))
68+
assert.True(t, Circ(Pt(1, 2), 10).Equal(Circ(Pt(1, 2), 10)))
6969

70-
assert.False(t, C(P(0.4, -0.25), 1.2).Equal(C(P(100.1, -0.1), 1.2)))
71-
assert.True(t, C(P(0.4, -0.25), 1.2).Equal(C(P(0.4, -0.25), 1.2)))
72-
assert.True(t, C(P(0.4, -0.25), 1.2).Equal(C(P(0.4, -0.250001), 1.2)))
70+
assert.False(t, Circ(Pt(0.4, -0.25), 1.2).Equal(Circ(Pt(100.1, -0.1), 1.2)))
71+
assert.True(t, Circ(Pt(0.4, -0.25), 1.2).Equal(Circ(Pt(0.4, -0.25), 1.2)))
72+
assert.True(t, Circ(Pt(0.4, -0.25), 1.2).Equal(Circ(Pt(0.4, -0.250001), 1.2)))
7373
}
7474

7575
func TestCircle_Contains(t *testing.T) {
76-
assert.False(t, C(P(1, 2), 10).Contains(P(1, 12)))
77-
assert.True(t, C(P(1, 2), 10).Contains(P(4, 4)))
76+
assert.False(t, Circ(Pt(1, 2), 10).Contains(Pt(1, 12)))
77+
assert.True(t, Circ(Pt(1, 2), 10).Contains(Pt(4, 4)))
7878

79-
assert.False(t, C(P(0.4, -0.25), 1.2).Contains(P(0.0, 1.7)))
80-
assert.True(t, C(P(0.4, -0.25), 1.2).Contains(P(0.1, 0.8)))
79+
assert.False(t, Circ(Pt(0.4, -0.25), 1.2).Contains(Pt(0.0, 1.7)))
80+
assert.True(t, Circ(Pt(0.4, -0.25), 1.2).Contains(Pt(0.1, 0.8)))
8181
}
8282

8383
func TestCircle_String(t *testing.T) {
84-
assert.Equal(t, C(P(10, 16), 5).String(), "C((10,16);5)")
85-
assert.Equal(t, C(P(100, -34.0000115), 0.2).String(), "C((100,-34.00);0.20)")
84+
assert.Equal(t, Circ(Pt(10, 16), 5).String(), "C((10,16);5)")
85+
assert.Equal(t, Circ(Pt(100, -34.0000115), 0.2).String(), "C((100,-34.00);0.20)")
8686
}
8787

8888
func TestCircle_Marshall(t *testing.T) {
89-
assert.JSON(t, C(P(10, 16), 12), `{"x":10,"y":16,"r":12}`)
90-
assert.JSON(t, C(P(100, -34.0000115), 0.2), `{"x":100.0,"y":-34.0000115,"r":0.2}`)
89+
assert.JSON(t, Circ(Pt(10, 16), 12), `{"x":10,"y":16,"r":12}`)
90+
assert.JSON(t, Circ(Pt(100, -34.0000115), 0.2), `{"x":100.0,"y":-34.0000115,"r":0.2}`)
9191
}
9292

9393
func TestCircle_Unmarshall(t *testing.T) {
@@ -101,10 +101,10 @@ func TestCircle_Unmarshall(t *testing.T) {
101101
}
102102

103103
func TestCircle_Immutable(t *testing.T) {
104-
c1 := C(P(1, 2), 10)
104+
c1 := Circ(Pt(1, 2), 10)
105105

106-
c1.Translate(V(3, -2))
107-
c1.MoveTo(P(4, 3))
106+
c1.Translate(Vec(3, -2))
107+
c1.MoveTo(Pt(4, 3))
108108
c1.Scale(2)
109109
c1.Resize(15)
110110
c1.Grow(1)

image.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ func SizeFromImage[T Number](r image.Rectangle) Size[T] {
1414
return Size[T]{T(r.Dx()), T(r.Dy())}
1515
}
1616

17-
// RectangleFromImage converts a Rectangle from an image.Rectangle.
18-
func RectangleFromImage[T Number](r image.Rectangle) Rectangle[T] {
19-
return RectangleFromMin(PointFromImage[T](r.Min), SizeFromImage[T](r))
17+
// RectFromImage converts a Rectangle from an image.Rectangle.
18+
func RectFromImage[T Number](r image.Rectangle) Rectangle[T] {
19+
return RectFromMin(PointFromImage[T](r.Min), SizeFromImage[T](r))
2020
}
2121

2222
// ToImagePoint converts a Point to an image.Point.

line.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ type Line[T Number] struct {
1010
End Point[T] `json:"b"`
1111
}
1212

13-
// L is shorthand for Line{start, end}.
14-
func L[T Number](start, end Point[T]) Line[T] {
13+
// Ln is shorthand for Line{start, end}.
14+
func Ln[T Number](start, end Point[T]) Line[T] {
1515
return Line[T]{start, end}
1616
}
1717

@@ -47,7 +47,7 @@ func (l Line[T]) Length() float64 {
4747

4848
// Bounds returns the axis-aligned bounding rectangle.
4949
func (l Line[T]) Bounds() Rectangle[T] {
50-
return Rectangle[T]{Center: l.Midpoint(), Size: S(l.Direction().Abs().XY())}
50+
return Rectangle[T]{Center: l.Midpoint(), Size: Sz(l.Direction().Abs().XY())}
5151
}
5252

5353
// Equal checks if the start and end points of the lines are equal.

line_test.go

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,76 +9,76 @@ import (
99
)
1010

1111
func TestLine_New(t *testing.T) {
12-
testLine(t, L(P(1, -1), P(2, 0)), 1, -1, 2, 0)
13-
testLine(t, L(P(0.5, -1.25), P(2.5, 3.75)), 0.5, -1.25, 2.5, 3.75)
12+
testLine(t, Ln(Pt(1, -1), Pt(2, 0)), 1, -1, 2, 0)
13+
testLine(t, Ln(Pt(0.5, -1.25), Pt(2.5, 3.75)), 0.5, -1.25, 2.5, 3.75)
1414
}
1515

1616
func TestLine_Translate(t *testing.T) {
17-
testLine(t, L(P(1, 2), P(3, 4)).Translate(V(3, -2)), 4, 0, 6, 2)
18-
testLine(t, L(P(0.4, -0.25), P(1.2, 3.4)).Translate(V(100.1, -0.1)), 100.5, -0.35, 101.3, 3.3)
17+
testLine(t, Ln(Pt(1, 2), Pt(3, 4)).Translate(Vec(3, -2)), 4, 0, 6, 2)
18+
testLine(t, Ln(Pt(0.4, -0.25), Pt(1.2, 3.4)).Translate(Vec(100.1, -0.1)), 100.5, -0.35, 101.3, 3.3)
1919
}
2020

2121
func TestLine_MoveTo(t *testing.T) {
22-
testLine(t, L(P(1, 2), P(3, 4)).MoveTo(P(3, -2)), 3, -2, 5, 0)
23-
testLine(t, L(P(0.4, -0.25), P(1.2, 3.4)).MoveTo(P(100.1, -0.1)), 100.1, -0.1, 100.9, 3.55)
22+
testLine(t, Ln(Pt(1, 2), Pt(3, 4)).MoveTo(Pt(3, -2)), 3, -2, 5, 0)
23+
testLine(t, Ln(Pt(0.4, -0.25), Pt(1.2, 3.4)).MoveTo(Pt(100.1, -0.1)), 100.1, -0.1, 100.9, 3.55)
2424
}
2525

2626
func TestLine_Reversed(t *testing.T) {
27-
testLine(t, L(P(1, 2), P(3, 4)).Reversed(), 3, 4, 1, 2)
28-
testLine(t, L(P(0.4, -0.25), P(1.2, 3.4)).Reversed(), 1.2, 3.4, 0.4, -0.25)
27+
testLine(t, Ln(Pt(1, 2), Pt(3, 4)).Reversed(), 3, 4, 1, 2)
28+
testLine(t, Ln(Pt(0.4, -0.25), Pt(1.2, 3.4)).Reversed(), 1.2, 3.4, 0.4, -0.25)
2929
}
3030

3131
func TestLine_Midpoint(t *testing.T) {
32-
testPoint(t, L(P(1, 2), P(3, 4)).Midpoint(), 2, 3)
33-
testPoint(t, L(P(0.4, -0.25), P(1.2, 3.4)).Midpoint(), 0.8, 1.575)
32+
testPoint(t, Ln(Pt(1, 2), Pt(3, 4)).Midpoint(), 2, 3)
33+
testPoint(t, Ln(Pt(0.4, -0.25), Pt(1.2, 3.4)).Midpoint(), 0.8, 1.575)
3434
}
3535

3636
func TestLine_Direction(t *testing.T) {
37-
testVector(t, L(P(1, 2), P(3, 4)).Direction(), 2, 2)
38-
testVector(t, L(P(0.4, -0.25), P(1.2, 3.4)).Direction(), 0.8, 3.65)
37+
testVector(t, Ln(Pt(1, 2), Pt(3, 4)).Direction(), 2, 2)
38+
testVector(t, Ln(Pt(0.4, -0.25), Pt(1.2, 3.4)).Direction(), 0.8, 3.65)
3939
}
4040

4141
func TestLine_Length(t *testing.T) {
42-
assert.EqualDelta(t, L(P(1, 2), P(3, 5)).Length(), math.Sqrt(13), Delta)
43-
assert.EqualDelta(t, L(P(0.4, -0.25), P(1.2, 3.4)).Length(), math.Sqrt(13.9625), Delta)
42+
assert.EqualDelta(t, Ln(Pt(1, 2), Pt(3, 5)).Length(), math.Sqrt(13), Delta)
43+
assert.EqualDelta(t, Ln(Pt(0.4, -0.25), Pt(1.2, 3.4)).Length(), math.Sqrt(13.9625), Delta)
4444
}
4545

4646
func TestLine_Equal(t *testing.T) {
47-
assert.False(t, L(P(1, 2), P(3, 4)).Equal(L(P(1, 2), P(3, 5))))
48-
assert.True(t, L(P(1, 2), P(3, 4)).Equal(L(P(1, 2), P(3, 4))))
47+
assert.False(t, Ln(Pt(1, 2), Pt(3, 4)).Equal(Ln(Pt(1, 2), Pt(3, 5))))
48+
assert.True(t, Ln(Pt(1, 2), Pt(3, 4)).Equal(Ln(Pt(1, 2), Pt(3, 4))))
4949

50-
assert.False(t, L(P(0.4, -0.25), P(1.2, 3.4)).Equal(L(P(0.5, -0.25), P(1.2, 3.4))))
51-
assert.True(t, L(P(0.4, -0.25), P(1.2, 3.4)).Equal(L(P(0.4, -0.25), P(1.2, 3.4))))
50+
assert.False(t, Ln(Pt(0.4, -0.25), Pt(1.2, 3.4)).Equal(Ln(Pt(0.5, -0.25), Pt(1.2, 3.4))))
51+
assert.True(t, Ln(Pt(0.4, -0.25), Pt(1.2, 3.4)).Equal(Ln(Pt(0.4, -0.25), Pt(1.2, 3.4))))
5252
}
5353

5454
func TestLine_String(t *testing.T) {
55-
assert.Equal(t, L(P(10, 16), P(1, 2)).String(), "L((10,16);(1,2))")
56-
assert.Equal(t, L(P(100, -34.0000115), P(0.2, 0.4)).String(), "L((100,-34.00);(0.20,0.40))")
55+
assert.Equal(t, Ln(Pt(10, 16), Pt(1, 2)).String(), "L((10,16);(1,2))")
56+
assert.Equal(t, Ln(Pt(100, -34.0000115), Pt(0.2, 0.4)).String(), "L((100,-34.00);(0.20,0.40))")
5757
}
5858

5959
func TestLine_Marshal_Unmarshal(t *testing.T) {
60-
assert.JSON(t, L(P(10, 16), P(1, 2)), `{"a":{"x":10,"y":16},"b":{"x":1,"y":2}}`)
61-
assert.JSON(t, L(P(100, -34.0000115), P(0.2, 0.4)), `{"a":{"x":100.0,"y":-34.0000115},"b":{"x":0.2,"y":0.4}}`)
60+
assert.JSON(t, Ln(Pt(10, 16), Pt(1, 2)), `{"a":{"x":10,"y":16},"b":{"x":1,"y":2}}`)
61+
assert.JSON(t, Ln(Pt(100, -34.0000115), Pt(0.2, 0.4)), `{"a":{"x":100.0,"y":-34.0000115},"b":{"x":0.2,"y":0.4}}`)
6262
}
6363

6464
func TestLine_Unmarshal(t *testing.T) {
6565
var l1 Line[int]
6666
assert.NoError(t, json.Unmarshal([]byte(`{"a":{"x":10,"y":16},"b":{"x":1,"y":2}}`), &l1))
67-
assert.True(t, l1.Equal(L(P(10, 16), P(1, 2))))
67+
assert.True(t, l1.Equal(Ln(Pt(10, 16), Pt(1, 2))))
6868

6969
var l2 Line[float64]
7070
assert.NoError(t, json.Unmarshal([]byte(`{"a":{"x":10.1,"y":-34.0000115},"b":{"x":0.2,"y":0.4}}`), &l2))
71-
assert.True(t, l2.Equal(L(P(10.1, -34.0000115), P(0.2, 0.4))))
71+
assert.True(t, l2.Equal(Ln(Pt(10.1, -34.0000115), Pt(0.2, 0.4))))
7272
}
7373

7474
func TestLine_Immutable(t *testing.T) {
75-
l := L(P(1, 2), P(3, 4))
75+
l := Ln(Pt(1, 2), Pt(3, 4))
7676

77-
l.Translate(V(3, -2))
78-
l.MoveTo(P(4, 3))
77+
l.Translate(Vec(3, -2))
78+
l.MoveTo(Pt(4, 3))
7979
l.Reversed()
8080

81-
assert.True(t, l.Equal(L(P(1, 2), P(3, 4))))
81+
assert.True(t, l.Equal(Ln(Pt(1, 2), Pt(3, 4))))
8282
}
8383

8484
func testLine[T Number](t *testing.T, l Line[T], sx, sy, ex, ey T) {

matrix.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ type Matrix struct {
1111
// [0 0 1] implicit third row
1212
}
1313

14-
// M is shorthand for Matrix{a, b, c, d, e, f}.
15-
func M(a, b, c, d, e, f float64) Matrix {
14+
// Mat is shorthand for Matrix{a, b, c, d, e, f}.
15+
func Mat(a, b, c, d, e, f float64) Matrix {
1616
return Matrix{a, b, c, d, e, f}
1717
}
1818

@@ -112,7 +112,7 @@ func (m Matrix) Equal(matrix Matrix) bool {
112112
func (m Matrix) IsZero() bool { return m.Equal(Matrix{}) }
113113

114114
//func (m Matrix) String() string {
115-
// return fmt.Sprintf("[[%.2f, %.2f, %.2f], [%.2f, %.2f, %.2f]]", m.A, m.B, m.C, m.D, m.E, m.F)
115+
// return fmt.Sprintf("[[%.2f, %.2f, %.2f], [%.2f, %.2f, %.2f]]", m.A, m.B, m.Circ, m.D, m.E, m.F)
116116
//}
117117

118118
// IdentityMatrix creates a new identity matrix.

padding.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package geom
2+
3+
// Padding represents a 2D padding.
4+
type Padding[T Number] struct {
5+
Top, Right, Bottom, Left T
6+
}
7+
8+
// Pd is shorthand for Padding{top, right, bottom, left}.
9+
func Pd[T Number](top, right, bottom, left T) Padding[T] {
10+
return Padding[T]{top, right, bottom, left}
11+
}
12+
13+
// PdU is shorthand for Padding{padding, padding, padding, padding}.
14+
func PdU[T Number](padding T) Padding[T] {
15+
return Padding[T]{padding, padding, padding, padding}
16+
}
17+
18+
// Width returns the width of the padding.
19+
func (p Padding[T]) Width() T {
20+
return p.Left + p.Right
21+
}
22+
23+
// Height returns the height of the padding.
24+
func (p Padding[T]) Height() T {
25+
return p.Top + p.Bottom
26+
}
27+
28+
// XY returns the width and height of the padding.
29+
func (p Padding[T]) XY() (T, T) {
30+
return p.Width(), p.Height()
31+
}

0 commit comments

Comments
 (0)