-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
geometry.go
162 lines (132 loc) · 4.65 KB
/
geometry.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package fyne
var (
_ Vector2 = (*Delta)(nil)
_ Vector2 = (*Position)(nil)
_ Vector2 = (*Size)(nil)
)
// Vector2 marks geometry types that can operate as a coordinate vector.
type Vector2 interface {
Components() (float32, float32)
IsZero() bool
}
// Delta is a generic X, Y coordinate, size or movement representation.
type Delta struct {
DX, DY float32
}
// NewDelta returns a newly allocated [Delta] representing a movement in the X and Y axis.
func NewDelta(dx float32, dy float32) Delta {
return Delta{DX: dx, DY: dy}
}
// Components returns the X and Y elements of v.
func (v Delta) Components() (float32, float32) {
return v.DX, v.DY
}
// IsZero returns whether the Position is at the zero-point.
func (v Delta) IsZero() bool {
return v.DX == 0.0 && v.DY == 0.0
}
// Position describes a generic X, Y coordinate relative to a parent [Canvas]
// or [CanvasObject].
type Position struct {
X float32 // The position from the parent's left edge
Y float32 // The position from the parent's top edge
}
// NewPos returns a newly allocated [Position] representing the specified coordinates.
func NewPos(x float32, y float32) Position {
return Position{x, y}
}
// NewSquareOffsetPos returns a newly allocated [Position] with the same x and y position.
//
// Since: 2.4
func NewSquareOffsetPos(length float32) Position {
return Position{length, length}
}
// Add returns a new [Position] that is the result of offsetting the current
// position by p2 X and Y.
func (p Position) Add(v Vector2) Position {
// NOTE: Do not simplify to `return p.AddXY(v.Components())`, it prevents inlining.
x, y := v.Components()
return Position{p.X + x, p.Y + y}
}
// AddXY returns a new [Position] by adding x and y to the current one.
func (p Position) AddXY(x, y float32) Position {
return Position{p.X + x, p.Y + y}
}
// Components returns the X and Y elements of p.
func (p Position) Components() (float32, float32) {
return p.X, p.Y
}
// IsZero returns whether the Position is at the zero-point.
func (p Position) IsZero() bool {
return p.X == 0.0 && p.Y == 0.0
}
// Subtract returns a new [Position] that is the result of offsetting the current
// position by p2 -X and -Y.
func (p Position) Subtract(v Vector2) Position {
// NOTE: Do not simplify to `return p.SubtractXY(v.Components())`, it prevents inlining.
x, y := v.Components()
return Position{p.X - x, p.Y - y}
}
// SubtractXY returns a new [Position] by subtracting x and y from the current one.
func (p Position) SubtractXY(x, y float32) Position {
return Position{p.X - x, p.Y - y}
}
// Size describes something with width and height.
type Size struct {
Width float32 // The number of units along the X axis.
Height float32 // The number of units along the Y axis.
}
// NewSize returns a newly allocated Size of the specified dimensions.
func NewSize(w float32, h float32) Size {
return Size{w, h}
}
// NewSquareSize returns a newly allocated Size with the same width and height.
//
// Since: 2.4
func NewSquareSize(side float32) Size {
return Size{side, side}
}
// Add returns a new Size that is the result of increasing the current size by
// s2 Width and Height.
func (s Size) Add(v Vector2) Size {
// NOTE: Do not simplify to `return s.AddXY(v.Components())`, it prevents inlining.
w, h := v.Components()
return Size{s.Width + w, s.Height + h}
}
// AddWidthHeight returns a new Size by adding width and height to the current one.
func (s Size) AddWidthHeight(width, height float32) Size {
return Size{s.Width + width, s.Height + height}
}
// IsZero returns whether the Size has zero width and zero height.
func (s Size) IsZero() bool {
return s.Width == 0.0 && s.Height == 0.0
}
// Max returns a new [Size] that is the maximum of the current Size and s2.
func (s Size) Max(v Vector2) Size {
x, y := v.Components()
maxW := Max(s.Width, x)
maxH := Max(s.Height, y)
return NewSize(maxW, maxH)
}
// Min returns a new [Size] that is the minimum of s and v.
func (s Size) Min(v Vector2) Size {
x, y := v.Components()
minW := Min(s.Width, x)
minH := Min(s.Height, y)
return NewSize(minW, minH)
}
// Components returns the Width and Height elements of this Size
func (s Size) Components() (float32, float32) {
return s.Width, s.Height
}
// Subtract returns a new Size that is the result of decreasing the current size
// by s2 Width and Height.
func (s Size) Subtract(v Vector2) Size {
// NOTE: Do not simplify to `return s.SubtractXY(v.Components())`, it prevents inlining.
w, h := v.Components()
return Size{s.Width - w, s.Height - h}
}
// SubtractWidthHeight returns a new Size by subtracting width and height from the current one.
func (s Size) SubtractWidthHeight(width, height float32) Size {
return Size{s.Width - width, s.Height - height}
}