@litecanvas/utils 0.12.1 → 0.14.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}
165
+ */
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
172
+
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}
141
182
  */
142
- export const vecrot = (v, radians) => {
143
- const cos = Math.cos(radians),
144
- sin = Math.sin(radians)
183
+ export const vecReflect = (v, normal) => {
184
+ const normalCopy = vecNorm(vec(normal))
185
+ return vecSub(v, vecMult(normalCopy, 2 * vecDot(v, normalCopy)))
186
+ }
145
187
 
146
- v.x = cos * v.x - sin * v.y
147
- v.y = sin * v.x + cos * v.y
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,16 @@ 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)
280
+
281
+ /**
282
+ * Calculates the angle between two vectors.
283
+ *
284
+ * @param {Vector} v1
285
+ * @param {Vector} v2
286
+ * @returns {number}
287
+ */
288
+ export const vecAngleBetween = (v1, v2) => Math.atan2(v2.y - v1.y, v2.x - v1.x)
225
289
 
226
290
  /**
227
291
  * Calculates the dot product of two vectors.
@@ -236,7 +300,7 @@ export const vecdir = (v) => Math.atan2(v.y, v.x)
236
300
  * @param {Vector} b
237
301
  * @returns {number}
238
302
  */
239
- export const vecdot = (a, b) => a.x * b.x + a.y * b.y
303
+ export const vecDot = (a, b) => a.x * b.x + a.y * b.y
240
304
 
241
305
  /**
242
306
  * Calculates the cross product of two vectors.
@@ -249,7 +313,7 @@ export const vecdot = (a, b) => a.x * b.x + a.y * b.y
249
313
  * @param {Vector} b
250
314
  * @returns {number}
251
315
  */
252
- export const veccross = (a, b) => a.x * b.y - a.y * b.x
316
+ export const vecCross = (a, b) => a.x * b.y - a.y * b.x
253
317
 
254
318
  /**
255
319
  * Calculates new vector values that are proportionally the same distance between two vectors.
@@ -260,10 +324,12 @@ export const veccross = (a, b) => a.x * b.y - a.y * b.x
260
324
  * @param {Vector} a
261
325
  * @param {Vector} b
262
326
  * @param {number} t
327
+ * @returns {Vector}
263
328
  */
264
- export const veclerp = (a, b, t) => {
329
+ export const vecLerp = (a, b, t) => {
265
330
  a.x += (b.x - a.x) * t || 0
266
331
  a.y += (b.y - a.y) * t || 0
332
+ return a
267
333
  }
268
334
 
269
335
  /**
@@ -274,26 +340,92 @@ export const veclerp = (a, b, t) => {
274
340
  *
275
341
  * @param {number} [minlength]
276
342
  * @param {number} [maxlength]
343
+ * @param {() => number} [randomFn]
277
344
  * @returns {Vector}
278
345
  */
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)
346
+ export const vecRand = (
347
+ minlength = 1,
348
+ maxlength = minlength,
349
+ randomFn = globalThis.rand || Math.random
350
+ ) => {
351
+ const angle = randomFn() * PI2
352
+ const radius = randomFn() * (maxlength - minlength) + minlength
353
+ return vec(cos(angle) * radius, sin(angle) * radius)
283
354
  }
284
355
 
285
356
  /**
286
- * @param {any} v
287
- * @returns {boolean}
357
+ * @param {Vector} v
358
+ * @returns {Vector}
359
+ */
360
+ export const vecAbs = (v) => {
361
+ v.x = Math.abs(v.x)
362
+ v.y = Math.abs(v.y)
363
+ return v
364
+ }
365
+
366
+ /**
367
+ * Rounded up all the vector components.
368
+ *
369
+ * @param {Vector} v
370
+ * @returns {Vector}
371
+ */
372
+ export const vecCeil = (v) => {
373
+ v.x = Math.ceil(v.x)
374
+ v.y = Math.ceil(v.y)
375
+ return v
376
+ }
377
+
378
+ /**
379
+ * Rounded down all the vector components.
380
+ *
381
+ * @param {Vector} v
382
+ * @returns {Vector}
288
383
  */
289
- export const isvector = (v) => v instanceof Vector
384
+ export const vecFloor = (v) => {
385
+ v.x = Math.floor(v.x)
386
+ v.y = Math.floor(v.y)
387
+ return v
388
+ }
389
+
390
+ /**
391
+ * Rounded to the nearest integer all the vector components.
392
+ *
393
+ * @param {Vector} v
394
+ * @returns {Vector}
395
+ */
396
+ export const vecRound = (v) => {
397
+ v.x = Math.round(v.x)
398
+ v.y = Math.round(v.y)
399
+ return v
400
+ }
290
401
 
291
- export const vecconfig = {
292
- random: () => {
293
- return globalThis.rand ? rand() : Math.random()
294
- },
402
+ /**
403
+ * Clamp all components between the components of min and max.
404
+ *
405
+ * @param {Vector} v
406
+ * @param {Vector} min
407
+ * @param {Vector} max
408
+ * @returns {Vector}
409
+ */
410
+ export const vecClamp = (v, min, max) => {
411
+ if (v.x < min.x) v.x = min.x
412
+ if (v.x > max.x) v.x = max.x
413
+ if (v.y < min.y) v.y = min.y
414
+ if (v.y > max.y) v.y = max.y
415
+ return v
295
416
  }
296
417
 
418
+ /**
419
+ * @param {Vector} v
420
+ * @param {Vector} to
421
+ * @param {number} delta
422
+ * @returns {Vector}
423
+ */
424
+ export const vecMove = (v, to, delta = 1) =>
425
+ vecAdd(v, to.x * delta, to.y * delta)
426
+
427
+ export const vecIsZero = (v) => vecEq(v, ZERO)
428
+
297
429
  // constants
298
430
  export const ZERO = /** @__PURE__ */ vec(0, 0)
299
431
  export const ONE = /** @__PURE__ */ vec(1, 1)