@litecanvas/utils 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,8 @@
1
+ const sqrt = Math.sqrt,
2
+ cos = Math.cos,
3
+ sin = Math.sin,
4
+ PI2 = 2 * Math.PI
5
+
1
6
  export class Vector {
2
7
  /** @type {number} */
3
8
  x
@@ -22,13 +27,25 @@ export class Vector {
22
27
  }
23
28
 
24
29
  /**
25
- * Creates a new vector.
30
+ * @param {*} v
31
+ * @returns {boolean}
32
+ */
33
+ const isVector = (v) => v instanceof Vector
34
+
35
+ /**
36
+ * Copy an vector or creates a new one.
26
37
  *
27
- * @param {number} x
38
+ * @param {number|Vector} [x]
28
39
  * @param {number} [y]
29
40
  * @returns {Vector}
30
41
  */
31
- export const vec = (x = 0, y = x) => new Vector(x, y)
42
+ export const vec = (x = 0, y = x) => {
43
+ if (isVector(x)) {
44
+ y = x.y
45
+ x = x.x
46
+ }
47
+ return new Vector(x, y)
48
+ }
32
49
 
33
50
  /**
34
51
  * Checks whether two vectors are equal.
@@ -38,35 +55,29 @@ export const vec = (x = 0, y = x) => new Vector(x, y)
38
55
  * @param {number} [y]
39
56
  * @returns {boolean}
40
57
  */
41
- export const veceq = (v, x, y = x) => {
42
- if (isvector(x)) {
43
- return veceq(v, x.x, x.y)
58
+ export const vecEq = (v, x, y = x) => {
59
+ if (isVector(x)) {
60
+ return vecEq(v, x.x, x.y)
44
61
  }
45
62
  return v.x === x && v.y === y
46
63
  }
47
64
 
48
- /**
49
- * Copy a vector.
50
- *
51
- * @param {Vector} v The original vector
52
- * @returns {Vector} The clone
53
- */
54
- export const veccopy = (v) => vec(v.x, v.y)
55
-
56
65
  /**
57
66
  * Assigns new values to a vector.
58
67
  *
59
68
  * @param {Vector} v The vector
60
69
  * @param {number|Vector} x
61
70
  * @param {number} [y]
71
+ * @returns {Vector}
62
72
  */
63
- export const vecset = (v, x, y = x) => {
64
- if (isvector(x)) {
65
- vecset(v, x.x, x.y)
73
+ export const vecSet = (v, x, y = x) => {
74
+ if (isVector(x)) {
75
+ vecSet(v, x.x, x.y)
66
76
  } else {
67
77
  v.x = x
68
78
  v.y = y
69
79
  }
80
+ return v
70
81
  }
71
82
 
72
83
  /**
@@ -75,14 +86,17 @@ export const vecset = (v, x, y = x) => {
75
86
  * @param {Vector} v The vector
76
87
  * @param {number|Vector} x
77
88
  * @param {number} [y]
89
+ * @returns {Vector}
78
90
  */
79
- export const vecadd = (v, x, y = x) => {
80
- if (isvector(x)) {
81
- vecadd(v, x.x, x.y)
82
- } else {
83
- v.x += x
84
- v.y += y
91
+ export const vecAdd = (v, x, y = x) => {
92
+ if (isVector(x)) {
93
+ return vecAdd(v, x.x, x.y)
85
94
  }
95
+
96
+ v.x += x
97
+ v.y += y
98
+
99
+ return v
86
100
  }
87
101
 
88
102
  /**
@@ -91,14 +105,17 @@ export const vecadd = (v, x, y = x) => {
91
105
  * @param {Vector} v The vector
92
106
  * @param {number|Vector} x
93
107
  * @param {number} [y]
108
+ * @returns {Vector}
94
109
  */
95
- export const vecsub = (v, x, y = x) => {
96
- if (isvector(x)) {
97
- vecsub(v, x.x, x.y)
98
- } else {
99
- v.x -= x
100
- v.y -= y
110
+ export const vecSub = (v, x, y = x) => {
111
+ if (isVector(x)) {
112
+ return vecSub(v, x.x, x.y)
101
113
  }
114
+
115
+ v.x -= x
116
+ v.y -= y
117
+
118
+ return v
102
119
  }
103
120
 
104
121
  /**
@@ -107,14 +124,17 @@ export const vecsub = (v, x, y = x) => {
107
124
  * @param {Vector} v
108
125
  * @param {number|Vector} x
109
126
  * @param {number} [y]
127
+ * @returns {Vector}
110
128
  */
111
- export const vecmult = (v, x, y = x) => {
112
- if (isvector(x)) {
113
- vecmult(v, x.x, x.y)
114
- } else {
115
- v.x *= x
116
- v.y *= y
129
+ export const vecMult = (v, x, y = x) => {
130
+ if (isVector(x)) {
131
+ return vecMult(v, x.x, x.y)
117
132
  }
133
+
134
+ v.x *= x
135
+ v.y *= y
136
+
137
+ return v
118
138
  }
119
139
 
120
140
  /**
@@ -123,14 +143,17 @@ export const vecmult = (v, x, y = x) => {
123
143
  * @param {Vector} v
124
144
  * @param {number|Vector} x
125
145
  * @param {number} [y]
146
+ * @returns {Vector}
126
147
  */
127
- export const vecdiv = (v, x, y = x) => {
128
- if (isvector(x)) {
129
- vecdiv(v, x.x, x.y)
130
- } else {
131
- v.x /= x
132
- v.y /= y
148
+ export const vecDiv = (v, x, y = x) => {
149
+ if (isVector(x)) {
150
+ return vecDiv(v, x.x, x.y)
133
151
  }
152
+
153
+ v.x /= x
154
+ v.y /= y
155
+
156
+ return v
134
157
  }
135
158
 
136
159
  /**
@@ -138,13 +161,41 @@ export const vecdiv = (v, x, y = x) => {
138
161
  *
139
162
  * @param {Vector} v
140
163
  * @param {number} radians
164
+ * @returns {Vector}
141
165
  */
142
- export const vecrot = (v, radians) => {
143
- const cos = Math.cos(radians),
144
- sin = Math.sin(radians)
166
+ export const vecRotate = (v, radians) => {
167
+ const c = cos(radians),
168
+ s = sin(radians)
169
+
170
+ v.x = c * v.x - s * v.y
171
+ v.y = s * v.x + c * v.y
145
172
 
146
- v.x = cos * v.x - sin * v.y
147
- v.y = sin * v.x + cos * v.y
173
+ return v
174
+ }
175
+
176
+ /**
177
+ * Reflects a vector about a line (second argument).
178
+ *
179
+ * @param {Vector} v
180
+ * @param {Vector} normal
181
+ * @returns {Vector}
182
+ */
183
+ export const vecReflect = (v, normal) => {
184
+ const normalCopy = vecNorm(vec(normal))
185
+ return vecSub(v, vecMult(normalCopy, 2 * vecDot(v, normalCopy)))
186
+ }
187
+
188
+ /**
189
+ * Reflects a vector about a line (second argument).
190
+ *
191
+ * @param {Vector} v
192
+ * @param {Vector} normal
193
+ * @returns {Vector}
194
+ */
195
+ export const vecSetMag = (v, value) => {
196
+ vecNorm(v)
197
+ vecMult(v, value)
198
+ return v
148
199
  }
149
200
 
150
201
  /**
@@ -153,7 +204,7 @@ export const vecrot = (v, radians) => {
153
204
  * @param {Vector} v
154
205
  * @returns {number}
155
206
  */
156
- export const vecmag = (v) => Math.sqrt(v.x * v.x + v.y * v.y)
207
+ export const vecMag = (v) => sqrt(v.x * v.x + v.y * v.y)
157
208
 
158
209
  /**
159
210
  * Calculates the magnitude (length) of the vector squared.
@@ -161,18 +212,20 @@ export const vecmag = (v) => Math.sqrt(v.x * v.x + v.y * v.y)
161
212
  * @param {Vector} v
162
213
  * @returns {number}
163
214
  */
164
- export const vecmag2 = (v) => v.x * v.x + v.y * v.y
215
+ export const vecMag2 = (v) => v.x * v.x + v.y * v.y
165
216
 
166
217
  /**
167
218
  * Scales the values of a vector so that its magnitude is 1.
168
219
  *
169
220
  * @param {Vector} v
221
+ * @returns {Vector}
170
222
  */
171
- export const vecnorm = (v) => {
172
- const length = vecmag(v)
223
+ export const vecNorm = (v) => {
224
+ const length = vecMag(v)
173
225
  if (length > 0) {
174
- vecdiv(v, length)
226
+ vecDiv(v, length)
175
227
  }
228
+ return v
176
229
  }
177
230
 
178
231
  /**
@@ -180,13 +233,15 @@ export const vecnorm = (v) => {
180
233
  *
181
234
  * @param {Vector} v
182
235
  * @param {number} max
236
+ * @returns {Vector}
183
237
  */
184
- export const veclimit = (v, max) => {
185
- const sq = vecmag2(v)
238
+ export const vecLimit = (v, max = 1) => {
239
+ const sq = vecMag2(v)
186
240
  if (sq > max * max) {
187
- vecdiv(v, Math.sqrt(sq)) //normalize it
188
- vecmult(v, max)
241
+ vecDiv(v, sqrt(sq)) //normalize it
242
+ vecMult(v, max)
189
243
  }
244
+ return v
190
245
  }
191
246
 
192
247
  /**
@@ -196,10 +251,10 @@ export const veclimit = (v, max) => {
196
251
  * @param {Vector} b
197
252
  * @returns {number}
198
253
  */
199
- export const vecdist = (a, b) => {
254
+ export const vecDist = (a, b) => {
200
255
  const dx = a.x - b.x
201
256
  const dy = a.y - b.y
202
- return Math.sqrt(dx * dx + dy * dy)
257
+ return sqrt(dx * dx + dy * dy)
203
258
  }
204
259
 
205
260
  /**
@@ -209,7 +264,7 @@ export const vecdist = (a, b) => {
209
264
  * @param {Vector} b
210
265
  * @returns {number}
211
266
  */
212
- export const vecdist2 = (a, b) => {
267
+ export const vecDist2 = (a, b) => {
213
268
  const dx = a.x - b.x
214
269
  const dy = a.y - b.y
215
270
  return dx * dx + dy * dy
@@ -221,7 +276,7 @@ export const vecdist2 = (a, b) => {
221
276
  * @param {Vector} v
222
277
  * @returns {number}
223
278
  */
224
- export const vecdir = (v) => Math.atan2(v.y, v.x)
279
+ export const vecAngle = (v) => Math.atan2(v.y, v.x)
225
280
 
226
281
  /**
227
282
  * Calculates the dot product of two vectors.
@@ -236,7 +291,7 @@ export const vecdir = (v) => Math.atan2(v.y, v.x)
236
291
  * @param {Vector} b
237
292
  * @returns {number}
238
293
  */
239
- export const vecdot = (a, b) => a.x * b.x + a.y * b.y
294
+ export const vecDot = (a, b) => a.x * b.x + a.y * b.y
240
295
 
241
296
  /**
242
297
  * Calculates the cross product of two vectors.
@@ -249,7 +304,7 @@ export const vecdot = (a, b) => a.x * b.x + a.y * b.y
249
304
  * @param {Vector} b
250
305
  * @returns {number}
251
306
  */
252
- export const veccross = (a, b) => a.x * b.y - a.y * b.x
307
+ export const vecCross = (a, b) => a.x * b.y - a.y * b.x
253
308
 
254
309
  /**
255
310
  * Calculates new vector values that are proportionally the same distance between two vectors.
@@ -260,10 +315,12 @@ export const veccross = (a, b) => a.x * b.y - a.y * b.x
260
315
  * @param {Vector} a
261
316
  * @param {Vector} b
262
317
  * @param {number} t
318
+ * @returns {Vector}
263
319
  */
264
- export const veclerp = (a, b, t) => {
320
+ export const vecLerp = (a, b, t) => {
265
321
  a.x += (b.x - a.x) * t || 0
266
322
  a.y += (b.y - a.y) * t || 0
323
+ return a
267
324
  }
268
325
 
269
326
  /**
@@ -274,26 +331,92 @@ export const veclerp = (a, b, t) => {
274
331
  *
275
332
  * @param {number} [minlength]
276
333
  * @param {number} [maxlength]
334
+ * @param {() => number} [randomFn]
277
335
  * @returns {Vector}
278
336
  */
279
- export const vecrand = (minlength = 1, maxlength = minlength) => {
280
- const angle = vecconfig.random() * 2 * Math.PI
281
- const radius = vecconfig.random() * (maxlength - minlength) + minlength
282
- return vec(Math.cos(angle) * radius, Math.sin(angle) * radius)
337
+ export const vecRand = (
338
+ minlength = 1,
339
+ maxlength = minlength,
340
+ randomFn = globalThis.rand || Math.random
341
+ ) => {
342
+ const angle = randomFn() * PI2
343
+ const radius = randomFn() * (maxlength - minlength) + minlength
344
+ return vec(cos(angle) * radius, sin(angle) * radius)
283
345
  }
284
346
 
285
347
  /**
286
- * @param {any} v
287
- * @returns {boolean}
348
+ * @param {Vector} v
349
+ * @returns {Vector}
288
350
  */
289
- export const isvector = (v) => v instanceof Vector
351
+ export const vecAbs = (v) => {
352
+ v.x = Math.abs(v.x)
353
+ v.y = Math.abs(v.y)
354
+ return v
355
+ }
290
356
 
291
- export const vecconfig = {
292
- random: () => {
293
- return globalThis.rand ? rand() : Math.random()
294
- },
357
+ /**
358
+ * Rounded up all the vector components.
359
+ *
360
+ * @param {Vector} v
361
+ * @returns {Vector}
362
+ */
363
+ export const vecCeil = (v) => {
364
+ v.x = Math.ceil(v.x)
365
+ v.y = Math.ceil(v.y)
366
+ return v
367
+ }
368
+
369
+ /**
370
+ * Rounded down all the vector components.
371
+ *
372
+ * @param {Vector} v
373
+ * @returns {Vector}
374
+ */
375
+ export const vecFloor = (v) => {
376
+ v.x = Math.floor(v.x)
377
+ v.y = Math.floor(v.y)
378
+ return v
295
379
  }
296
380
 
381
+ /**
382
+ * Rounded to the nearest integer all the vector components.
383
+ *
384
+ * @param {Vector} v
385
+ * @returns {Vector}
386
+ */
387
+ export const vecRound = (v) => {
388
+ v.x = Math.round(v.x)
389
+ v.y = Math.round(v.y)
390
+ return v
391
+ }
392
+
393
+ /**
394
+ * Clamp all components between the components of min and max.
395
+ *
396
+ * @param {Vector} v
397
+ * @param {Vector} min
398
+ * @param {Vector} max
399
+ * @returns {Vector}
400
+ */
401
+ export const vecClamp = (v, min, max) => {
402
+ if (v.x < min.x) v.x = min.x
403
+ if (v.x > max.x) v.x = max.x
404
+ if (v.y < min.y) v.y = min.y
405
+ if (v.y > max.y) v.y = max.y
406
+ return v
407
+ }
408
+
409
+ /**
410
+ * @param {Vector} v
411
+ * @param {Vector} to
412
+ * @param {number} delta
413
+ * @returns {Vector}
414
+ */
415
+ export const vecMove = (v, to, delta = 1) =>
416
+ vecAdd(v, to.x * delta, to.y * delta)
417
+
418
+ export const vecIsZero = (v) => vecEq(v, ZERO)
419
+
297
420
  // constants
298
421
  export const ZERO = /** @__PURE__ */ vec(0, 0)
299
422
  export const ONE = /** @__PURE__ */ vec(1, 1)