/
vectors.go
216 lines (175 loc) · 5.12 KB
/
vectors.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
205
206
207
208
209
210
211
212
213
214
215
216
package api
import (
"math"
)
// VecI is a 2D vector with integer components.
type VecI PointI
// Neg flips a vector to point in the opposite direction.
func (v VecI) Neg() VecI {
return VecI{-v.X, -v.Y}
}
// Add two vectors and return the result.
func (v VecI) Add(v2 VecI) VecI {
return VecI{v.X + v2.X, v.Y + v2.Y}
}
// Sub subtracts two vectors and returns the results.
func (v VecI) Sub(v2 VecI) VecI {
return VecI{v.X - v2.X, v.Y - v2.Y}
}
// Mul scales the vector by a constant.
func (v VecI) Mul(c int32) VecI {
return VecI{v.X * c, v.Y * c}
}
// Dot computes the dot product with another vector.
func (v VecI) Dot(v2 VecI) int32 {
return v.X*v2.X + v.Y*v2.Y
}
// Len2 computes the squared length (magnitude) of the vector.
func (v VecI) Len2() int32 {
return v.Dot(v)
}
// Len computes the length (magnitude) of the vector.
func (v VecI) Len() float32 {
return float32(v.Len())
}
// Len64 computes the length (magnitude) of the vector.
func (v VecI) Len64() float64 {
return math.Sqrt(float64(v.Len2()))
}
// Manhattan computes the manhattan distance represented by this vector.
func (v VecI) Manhattan() int32 {
if v.X < 0 {
v.X = -v.X
}
if v.Y < 0 {
v.Y = -v.Y
}
return v.X + v.Y
}
// Vec2D is a 2D vector if real components.
type Vec2D Point2D
// Neg flips a vector to point in the opposite direction.
func (v Vec2D) Neg() Vec2D {
return Vec2D{-v.X, -v.Y}
}
// Add two vectors and return the result.
func (v Vec2D) Add(v2 Vec2D) Vec2D {
return Vec2D{v.X + v2.X, v.Y + v2.Y}
}
// Sub subtracts two vectors and returns the results.
func (v Vec2D) Sub(v2 Vec2D) Vec2D {
return Vec2D{v.X - v2.X, v.Y - v2.Y}
}
// Mul scales the vector by a constant.
func (v Vec2D) Mul(c float32) Vec2D {
return Vec2D{v.X * c, v.Y * c}
}
// Div scaled the vector by the inverse of a constant.
func (v Vec2D) Div(c float32) Vec2D {
return Vec2D{v.X / c, v.Y / c}
}
// Mul64 scales the vector by a 64-bit constant. This involves additional casting so Mul should be preferred when 32-bits are sufficient.
func (v Vec2D) Mul64(c float64) Vec2D {
return Vec2D{float32(float64(v.X) * c), float32(float64(v.Y) * c)}
}
// Dot computes the dot product with another vector.
func (v Vec2D) Dot(v2 Vec2D) float32 {
return v.X*v2.X + v.Y*v2.Y
}
// Len2 computes the squared length (magnitude) of the vector.
func (v Vec2D) Len2() float32 {
return v.Dot(v)
}
// Len computes the length (magnitude) of the vector.
func (v Vec2D) Len() float32 {
return float32(v.Len64())
}
// Len64 computes the length (magnitude) of the vector.
func (v Vec2D) Len64() float64 {
return math.Sqrt(float64(v.Len2()))
}
// Manhattan computes the manhattan distance represented by this vector.
func (v Vec2D) Manhattan() float32 {
if v.X < 0 {
v.X = -v.X
}
if v.Y < 0 {
v.Y = -v.Y
}
return v.X + v.Y
}
// Norm computes the unit vector pointing is the same direction as v.
func (v Vec2D) Norm() Vec2D {
return v.Mul64(1.0 / v.Len64())
}
// Quadrant rounds the vector angle to the nearest nth of a circle and normalizes it.
func (v Vec2D) Quadrant(n int) Vec2D {
a := math.Atan2(float64(v.Y), float64(v.X))
q := int(float64(n)*a/(2*math.Pi)+float64(n)+0.5) % n
a = 2 * math.Pi * float64(q) / float64(n)
y, x := math.Sincos(a)
return Vec2D{float32(x), float32(y)}
}
// Vec is a 3D vector with real components.
type Vec Point
// Neg flips a vector to point in the opposite direction.
func (v Vec) Neg() Vec {
return Vec{-v.X, -v.Y, -v.Z}
}
// Add two vectors and return the result.
func (v Vec) Add(v2 Vec) Vec {
return Vec{v.X + v2.X, v.Y + v2.Y, v.Z + v2.Z}
}
// Sub subtracts two vectors and returns the results.
func (v Vec) Sub(v2 Vec) Vec {
return Vec{v.X - v2.X, v.Y - v2.Y, v.Z - v2.Z}
}
// Mul scales the vector by a constant.
func (v Vec) Mul(c float32) Vec {
return Vec{v.X * c, v.Y * c, v.Z * c}
}
// Div scaled the vector by the inverse of a constant.
func (v Vec) Div(c float32) Vec {
return Vec{v.X / c, v.Y / c, v.Z / c}
}
// Mul64 scales the vector by a 64-bit constant. This involves additional casting so Mul should be preferred when 32-bits are sufficient.
func (v Vec) Mul64(c float64) Vec {
return Vec{float32(float64(v.X) * c), float32(float64(v.Y) * c), float32(float64(v.Z) * c)}
}
// Dot computes the dot product with another vector.
func (v Vec) Dot(v2 Vec) float32 {
return v.X*v2.X + v.Y*v2.Y + v.Z*v2.Z
}
// Len2 computes the squared length (magnitude) of the vector.
func (v Vec) Len2() float32 {
return v.Dot(v)
}
// Len computes the length (magnitude) of the vector.
func (v Vec) Len() float32 {
return float32(v.Len64())
}
// Len64 computes the length (magnitude) of the vector.
func (v Vec) Len64() float64 {
return math.Sqrt(float64(v.Len2()))
}
// Manhattan computes the manhattan distance represented by this vector.
func (v Vec) Manhattan() float32 {
if v.X < 0 {
v.X = -v.X
}
if v.Y < 0 {
v.Y = -v.Y
}
if v.Z < 0 {
v.Z = -v.Z
}
return v.X + v.Y + v.Z
}
// Norm computes the unit vector pointing is the same direction as v.
func (v Vec) Norm() Vec {
return v.Mul64(1.0 / v.Len64())
}
// Cross computes the cross product of v x v2.
func (v Vec) Cross(v2 Vec) Vec {
return Vec{v.Y*v2.Z - v.Z*v2.Y, v.Z*v2.X - v.X*v2.Z, v.X*v2.Y - v.Y*v2.X}
}