-
Notifications
You must be signed in to change notification settings - Fork 1
/
vec2i.go
204 lines (165 loc) · 5.38 KB
/
vec2i.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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
package vmath
import (
"fmt"
"github.com/maja42/vmath/math32"
"github.com/maja42/vmath/mathi"
)
type Vec2i [2]int
func (v Vec2i) String() string {
return fmt.Sprintf("Vec2i[%d x %d]", v[0], v[1])
}
// Format the vector to a string.
func (v Vec2i) Format(format string) string {
return fmt.Sprintf(format, v[0], v[1])
}
// Vec2f returns a float representation of the vector.
func (v Vec2i) Vec2f() Vec2f {
return Vec2f{float32(v[0]), float32(v[1])}
}
// Vec3i creates a 3D vector.
func (v Vec2i) Vec3i(z int) Vec3i {
return Vec3i{v[0], v[1], z}
}
// Vec4i creates a 4D vector.
func (v Vec2i) Vec4i(z, w int) Vec4i {
return Vec4i{v[0], v[1], z, w}
}
// Split returns the vector's components.
func (v Vec2i) Split() (x, y int) {
return v[0], v[1]
}
// X returns the vector's first component.
// Performance is equivalent to using v[0].
func (v Vec2i) X() int {
return v[0]
}
// Y returns the vector's second component.
// Performance is equivalent to using v[1].
func (v Vec2i) Y() int {
return v[1]
}
// IsOrthogonal returns true if the vector is horizontal or vertical (one of its components is zero).
func (v Vec2i) IsOrthogonal() bool {
return v[0] == 0 || v[1] == 0
}
// Abs returns a vector with the components turned into absolute values.
func (v Vec2i) Abs() Vec2i {
return Vec2i{mathi.Abs(v[0]), mathi.Abs(v[1])}
}
// Add performs component-wise addition between two vectors.
func (v Vec2i) Add(other Vec2i) Vec2i {
return Vec2i{v[0] + other[0], v[1] + other[1]}
}
// AddScalar performs a component-wise scalar addition.
func (v Vec2i) AddScalar(s int) Vec2i {
return Vec2i{v[0] + s, v[1] + s}
}
// AddScalarf performs a scalar addition.
func (v Vec2i) AddScalarf(s float32) Vec2f {
return Vec2f{float32(v[0]) + s, float32(v[1]) + s}
}
// Sub performs component-wise subtraction between two vectors.
func (v Vec2i) Sub(other Vec2i) Vec2i {
return Vec2i{v[0] - other[0], v[1] - other[1]}
}
// SubScalar performs a component-wise scalar subtraction.
func (v Vec2i) SubScalar(s int) Vec2i {
return Vec2i{v[0] - s, v[1] - s}
}
// SubScalarf performs a scalar subtraction.
func (v Vec2i) SubScalarf(s float32) Vec2f {
return Vec2f{float32(v[0]) - s, float32(v[1]) - s}
}
// Mul performs a component-wise multiplication.
func (v Vec2i) Mul(other Vec2i) Vec2i {
return Vec2i{v[0] * other[0], v[1] * other[1]}
}
// MulScalar performs a scalar multiplication.
func (v Vec2i) MulScalar(s int) Vec2i {
return Vec2i{v[0] * s, v[1] * s}
}
// MulScalar performs a scalar multiplication.
func (v Vec2i) MulScalarf(s float32) Vec2f {
return Vec2f{float32(v[0]) * s, float32(v[1]) * s}
}
// Div performs a component-wise division.
// Decimals are truncated.
func (v Vec2i) Div(other Vec2i) Vec2i {
return Vec2i{v[0] / other[0], v[1] / other[1]}
}
// DivScalar performs a scalar division.
// Decimals are truncated.
func (v Vec2i) DivScalar(s int) Vec2i {
return Vec2i{v[0] / s, v[1] / s}
}
// DivScalarf performs a scalar division.
func (v Vec2i) DivScalarf(s float32) Vec2f {
return Vec2f{float32(v[0]) / s, float32(v[1]) / s}
}
// Length returns the vector's length.
func (v Vec2i) Length() float32 {
return math32.Hypot(float32(v[0]), float32(v[1]))
}
// SquareLength returns the vector's squared length.
func (v Vec2i) SquareLength() int {
return v[0]*v[0] + v[1]*v[1]
}
// IsZero returns true if all components are zero.
func (v Vec2i) IsZero() bool {
return v[0] == 0 && v[1] == 0
}
// Equal compares two vectors component-wise.
func (v Vec2i) Equal(other Vec2i) bool {
return v[0] == other[0] && v[1] == other[1]
}
// Clamp clamps each component to the range of [min, max].
func (v Vec2i) Clamp(min, max int) Vec2i {
return Vec2i{
Clampi(v[0], min, max),
Clampi(v[1], min, max),
}
}
// Negate inverts all components.
func (v Vec2i) Negate() Vec2i {
return Vec2i{-v[0], -v[1]}
}
// Dot performs a dot product with another vector.
func (v Vec2i) Dot(other Vec2i) int {
return v[0]*other[0] + v[1]*other[1]
}
// MagCross returns the length of the cross product vector.
// This is equal to the magnitude of a 3D cross product vector, with the Z position implicitly set to zero.
// It represents twice the signed area between the two vectors.
func (v Vec2i) MagCross(other Vec2i) int {
return v[0]*other[1] - v[1]*other[0]
}
// IsParallel returns true if the given vector is parallel.
// Vectors that point in opposite directions are also parallel (but not collinear).
func (v Vec2i) IsParallel(other Vec2i) bool {
return v.MagCross(other) == 0
}
// IsCollinear returns true if the given vector is collinear (pointing in the same direction).
func (v Vec2i) IsCollinear(other Vec2i) bool {
return v.MagCross(other) == 0 && // parallel
(v[0] >= 0) == (other[0] >= 0) && // same x direction
(v[1] >= 0) == (other[1] >= 0) // same y direction
}
// NormalVec returns a normal vector on the 2D plane that is either on the left or right hand side.
func (v Vec2i) NormalVec(onLeft bool) Vec2i {
if onLeft {
return Vec2i{-v[1], v[0]}
}
return Vec2i{v[1], -v[0]}
}
// Project returns a vector representing the projection of vector v onto "other".
func (v Vec2i) Project(other Vec2i) Vec2f {
return v.Vec2f().Project(other.Vec2f())
}
// Distance returns the euclidean distance to another position.
func (v Vec2i) Distance(other Vec2i) float32 {
return other.Sub(v).Length()
}
// SquareDistance returns the squared euclidean distance to another position.
func (v Vec2i) SquareDistance(other Vec2i) int {
return other.Sub(v).SquareLength()
}