@bitbybit-dev/base 0.19.0-alpha.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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +71 -0
  3. package/babel.config.cjs +14 -0
  4. package/babel.config.d.cts +5 -0
  5. package/index.d.ts +1 -0
  6. package/index.js +4 -0
  7. package/lib/api/index.d.ts +1 -0
  8. package/lib/api/index.js +1 -0
  9. package/lib/api/inputs/base-inputs.d.ts +35 -0
  10. package/lib/api/inputs/base-inputs.js +1 -0
  11. package/lib/api/inputs/color-inputs.d.ts +122 -0
  12. package/lib/api/inputs/color-inputs.js +164 -0
  13. package/lib/api/inputs/index.d.ts +8 -0
  14. package/lib/api/inputs/index.js +8 -0
  15. package/lib/api/inputs/inputs.d.ts +10 -0
  16. package/lib/api/inputs/inputs.js +10 -0
  17. package/lib/api/inputs/lists-inputs.d.ts +478 -0
  18. package/lib/api/inputs/lists-inputs.js +576 -0
  19. package/lib/api/inputs/logic-inputs.d.ts +163 -0
  20. package/lib/api/inputs/logic-inputs.js +111 -0
  21. package/lib/api/inputs/math-inputs.d.ts +311 -0
  22. package/lib/api/inputs/math-inputs.js +391 -0
  23. package/lib/api/inputs/point-inputs.d.ts +446 -0
  24. package/lib/api/inputs/point-inputs.js +521 -0
  25. package/lib/api/inputs/text-inputs.d.ts +83 -0
  26. package/lib/api/inputs/text-inputs.js +120 -0
  27. package/lib/api/inputs/transforms-inputs.d.ts +136 -0
  28. package/lib/api/inputs/transforms-inputs.js +200 -0
  29. package/lib/api/inputs/vector-inputs.d.ts +300 -0
  30. package/lib/api/inputs/vector-inputs.js +304 -0
  31. package/lib/api/services/color.d.ts +114 -0
  32. package/lib/api/services/color.js +170 -0
  33. package/lib/api/services/geometry-helper.d.ts +15 -0
  34. package/lib/api/services/geometry-helper.js +151 -0
  35. package/lib/api/services/index.d.ts +9 -0
  36. package/lib/api/services/index.js +9 -0
  37. package/lib/api/services/lists.d.ts +287 -0
  38. package/lib/api/services/lists.js +682 -0
  39. package/lib/api/services/logic.d.ts +99 -0
  40. package/lib/api/services/logic.js +203 -0
  41. package/lib/api/services/math.d.ts +349 -0
  42. package/lib/api/services/math.js +621 -0
  43. package/lib/api/services/point.d.ts +223 -0
  44. package/lib/api/services/point.js +351 -0
  45. package/lib/api/services/text.d.ts +69 -0
  46. package/lib/api/services/text.js +84 -0
  47. package/lib/api/services/transforms.d.ts +122 -0
  48. package/lib/api/services/transforms.js +256 -0
  49. package/lib/api/services/vector.d.ts +320 -0
  50. package/lib/api/services/vector.js +468 -0
  51. package/lib/index.d.ts +1 -0
  52. package/lib/index.js +1 -0
  53. package/package.json +93 -0
@@ -0,0 +1,468 @@
1
+ /**
2
+ * Contains various methods for vector mathematics. Vector in bitbybit is simply an array, usually containing numbers.
3
+ * In 3D [x, y, z] form describes space, where y is the up vector.
4
+ * Because of this form Vector can be interchanged with Point, which also is an array in [x, y, z] form.
5
+ */
6
+ export class Vector {
7
+ constructor(math, geometryHelper) {
8
+ this.math = math;
9
+ this.geometryHelper = geometryHelper;
10
+ }
11
+ /**
12
+ * Removes all duplicate vectors from the input array
13
+ * @param inputs Contains vectors and a tolerance value
14
+ * @returns Array of vectors without duplicates
15
+ * @group remove
16
+ * @shortname remove all duplicates
17
+ * @drawable false
18
+ */
19
+ removeAllDuplicateVectors(inputs) {
20
+ return this.geometryHelper.removeAllDuplicateVectors(inputs.vectors, inputs.tolerance);
21
+ }
22
+ /**
23
+ * Removes consecutive duplicate vectors from the input array
24
+ * @param inputs Contains vectors and a tolerance value
25
+ * @returns Array of vectors without duplicates
26
+ * @group remove
27
+ * @shortname remove consecutive duplicates
28
+ * @drawable false
29
+ */
30
+ removeConsecutiveDuplicateVectors(inputs) {
31
+ return this.geometryHelper.removeConsecutiveVectorDuplicates(inputs.vectors, inputs.checkFirstAndLast, inputs.tolerance);
32
+ }
33
+ /**
34
+ * Measures the angle between two vectors in degrees
35
+ * @param inputs Contains two vectors represented as number arrays
36
+ * @group angles
37
+ * @shortname angle
38
+ * @returns Number in degrees
39
+ * @drawable false
40
+ */
41
+ angleBetween(inputs) {
42
+ return this.math.radToDeg({
43
+ number: Math.acos(this.dot({ first: inputs.first, second: inputs.second }) / (this.norm({ vector: inputs.first }) * this.norm({ vector: inputs.second })))
44
+ });
45
+ }
46
+ /**
47
+ * Measures the normalized 2d angle between two vectors in degrees
48
+ * @param inputs Contains two vectors represented as number arrays
49
+ * @returns Number in degrees
50
+ * @group angles
51
+ * @shortname angle normalized 2d
52
+ * @drawable false
53
+ */
54
+ angleBetweenNormalized2d(inputs) {
55
+ const perpDot = inputs.first[0] * inputs.second[1] - inputs.first[1] * inputs.second[0];
56
+ return this.math.radToDeg({
57
+ number: Math.atan2(perpDot, this.dot({ first: inputs.first, second: inputs.second }))
58
+ });
59
+ }
60
+ /**
61
+ * Measures a positive angle between two vectors given the reference vector in degrees
62
+ * @param inputs Contains information of two vectors and a reference vector
63
+ * @returns Number in degrees
64
+ * @group angles
65
+ * @shortname positive angle
66
+ * @drawable false
67
+ */
68
+ positiveAngleBetween(inputs) {
69
+ const angle = this.signedAngleBetween(inputs);
70
+ return angle < 0 ? 360 + angle : angle;
71
+ }
72
+ /**
73
+ * Adds all vector xyz values together and create a new vector
74
+ * @param inputs Vectors to be added
75
+ * @returns New vector that has xyz values as sums of all the vectors
76
+ * @group sum
77
+ * @shortname add all
78
+ * @drawable false
79
+ */
80
+ addAll(inputs) {
81
+ const res = [];
82
+ for (let i = 0; i < inputs.vectors[0].length; i++) {
83
+ let sum = 0;
84
+ for (const vector of inputs.vectors) {
85
+ sum += vector[i];
86
+ }
87
+ res.push(sum);
88
+ }
89
+ return res;
90
+ }
91
+ /**
92
+ * Adds two vectors together
93
+ * @param inputs Two vectors to be added
94
+ * @returns Number array representing vector
95
+ * @group sum
96
+ * @shortname add
97
+ * @drawable false
98
+ */
99
+ add(inputs) {
100
+ const res = [];
101
+ for (let i = 0; i < inputs.first.length; i++) {
102
+ res.push(inputs.first[i] + inputs.second[i]);
103
+ }
104
+ return res;
105
+ }
106
+ /**
107
+ * Checks if the boolean array contains only true values, if there's a single false it will return false.
108
+ * @param inputs Vectors to be checked
109
+ * @returns Boolean indicating if vector contains only true values
110
+ * @group sum
111
+ * @shortname all
112
+ * @drawable false
113
+ */
114
+ all(inputs) {
115
+ return inputs.vector.every(v => v);
116
+ }
117
+ /**
118
+ * Cross two vectors
119
+ * @param inputs Two vectors to be crossed
120
+ * @group base
121
+ * @shortname all
122
+ * @returns Crossed vector
123
+ * @drawable false
124
+ */
125
+ cross(inputs) {
126
+ const res = [];
127
+ res.push(inputs.first[1] * inputs.second[2] - inputs.first[2] * inputs.second[1]);
128
+ res.push(inputs.first[2] * inputs.second[0] - inputs.first[0] * inputs.second[2]);
129
+ res.push(inputs.first[0] * inputs.second[1] - inputs.first[1] * inputs.second[0]);
130
+ return res;
131
+ }
132
+ /**
133
+ * Squared distance between two vectors
134
+ * @param inputs Two vectors
135
+ * @returns Number representing squared distance between two vectors
136
+ * @group distance
137
+ * @shortname dist squared
138
+ * @drawable false
139
+ */
140
+ distSquared(inputs) {
141
+ let res = 0;
142
+ for (let i = 0; i < inputs.first.length; i++) {
143
+ res += Math.pow(inputs.first[i] - inputs.second[i], 2);
144
+ }
145
+ return res;
146
+ }
147
+ /**
148
+ * Distance between two vectors
149
+ * @param inputs Two vectors
150
+ * @returns Number representing distance between two vectors
151
+ * @group distance
152
+ * @shortname dist
153
+ * @drawable false
154
+ */
155
+ dist(inputs) {
156
+ return Math.sqrt(this.distSquared(inputs));
157
+ }
158
+ /**
159
+ * Divide the vector by a scalar value
160
+ * @param inputs Contains vector and a scalar
161
+ * @returns Vector that is a result of division by a scalar
162
+ * @group base
163
+ * @shortname div
164
+ * @drawable false
165
+ */
166
+ div(inputs) {
167
+ const res = [];
168
+ for (let i = 0; i < inputs.vector.length; i++) {
169
+ res.push(inputs.vector[i] / inputs.scalar);
170
+ }
171
+ return res;
172
+ }
173
+ /**
174
+ * Computes the domain between minimum and maximum values of the vector
175
+ * @param inputs Vector information
176
+ * @returns Number representing distance between two vectors
177
+ * @group base
178
+ * @shortname domain
179
+ * @drawable false
180
+ */
181
+ domain(inputs) {
182
+ return inputs.vector[inputs.vector.length - 1] - inputs.vector[0];
183
+ }
184
+ /**
185
+ * Dot product between two vectors
186
+ * @param inputs Two vectors
187
+ * @returns Number representing dot product of the vector
188
+ * @group base
189
+ * @shortname dot
190
+ * @drawable false
191
+ */
192
+ dot(inputs) {
193
+ let res = 0;
194
+ for (let i = 0; i < inputs.first.length; i++) {
195
+ res += inputs.first[i] * inputs.second[i];
196
+ }
197
+ return res;
198
+ }
199
+ /**
200
+ * Checks if vector is finite for each number and returns a boolean array
201
+ * @param inputs Vector with possibly infinite values
202
+ * @returns Vector array that contains boolean values for each number in the input
203
+ * vector that identifies if value is finite (true) or infinite (false)
204
+ * @group validate
205
+ * @shortname finite
206
+ * @drawable false
207
+ */
208
+ finite(inputs) {
209
+ return inputs.vector.map(v => isFinite(v));
210
+ }
211
+ /**
212
+ * Checks if the vector is zero length
213
+ * @param inputs Vector to be checked
214
+ * @returns Boolean that identifies if vector is zero length
215
+ * @group validate
216
+ * @shortname isZero
217
+ * @drawable false
218
+ */
219
+ isZero(inputs) {
220
+ return this.norm({ vector: inputs.vector }) === 0;
221
+ }
222
+ /**
223
+ * Finds in between vector between two vectors by providing a fracture
224
+ * @param inputs Information for finding vector between two vectors using a fraction
225
+ * @returns Vector that is in between two vectors
226
+ * @group distance
227
+ * @shortname lerp
228
+ * @drawable false
229
+ */
230
+ lerp(inputs) {
231
+ return this.add({
232
+ first: this.mul({ vector: inputs.first, scalar: inputs.fraction }),
233
+ second: this.mul({ vector: inputs.second, scalar: 1.0 - inputs.fraction })
234
+ });
235
+ }
236
+ /**
237
+ * Finds the maximum value in the vector
238
+ * @param inputs Vector to be checked
239
+ * @returns Largest number in the vector
240
+ * @group extract
241
+ * @shortname max
242
+ * @drawable false
243
+ */
244
+ max(inputs) {
245
+ return Math.max(...inputs.vector);
246
+ }
247
+ /**
248
+ * Finds the minimum value in the vector
249
+ * @param inputs Vector to be checked
250
+ * @returns Lowest number in the vector
251
+ * @group extract
252
+ * @shortname min
253
+ * @drawable false
254
+ */
255
+ min(inputs) {
256
+ return Math.min(...inputs.vector);
257
+ }
258
+ /**
259
+ * Multiple vector with the scalar
260
+ * @param inputs Vector with a scalar
261
+ * @returns Vector that results from multiplication
262
+ * @group base
263
+ * @shortname mul
264
+ * @drawable false
265
+ */
266
+ mul(inputs) {
267
+ const res = [];
268
+ for (let i = 0; i < inputs.vector.length; i++) {
269
+ res.push(inputs.vector[i] * inputs.scalar);
270
+ }
271
+ return res;
272
+ }
273
+ /**
274
+ * Negates the vector
275
+ * @param inputs Vector to negate
276
+ * @returns Negative vector
277
+ * @group base
278
+ * @shortname neg
279
+ * @drawable false
280
+ */
281
+ neg(inputs) {
282
+ const res = [];
283
+ for (let i = 0; i < inputs.vector.length; i++) {
284
+ res.push(-inputs.vector[i]);
285
+ }
286
+ return res;
287
+ }
288
+ /**
289
+ * Compute squared norm
290
+ * @param inputs Vector for squared norm
291
+ * @returns Number that is squared norm
292
+ * @group base
293
+ * @shortname norm squared
294
+ * @drawable false
295
+ */
296
+ normSquared(inputs) {
297
+ return this.dot({ first: inputs.vector, second: inputs.vector });
298
+ }
299
+ /**
300
+ * Norm of the vector
301
+ * @param inputs Vector to compute the norm
302
+ * @returns Number that is norm of the vector
303
+ * @group base
304
+ * @shortname norm
305
+ * @drawable false
306
+ */
307
+ norm(inputs) {
308
+ const norm2 = this.normSquared(inputs);
309
+ return norm2 !== 0.0 ? Math.sqrt(norm2) : norm2;
310
+ }
311
+ /**
312
+ * Normalize the vector into a unit vector, that has a length of 1
313
+ * @param inputs Vector to normalize
314
+ * @returns Unit vector that has length of 1
315
+ * @group base
316
+ * @shortname normalized
317
+ * @drawable false
318
+ */
319
+ normalized(inputs) {
320
+ return this.div({ scalar: this.norm(inputs), vector: inputs.vector });
321
+ }
322
+ /**
323
+ * Finds a point coordinates on the given distance ray that spans between the point along the direction vector
324
+ * @param inputs Provide a point, vector and a distance for finding a point
325
+ * @returns Vector representing point on the ray
326
+ * @group base
327
+ * @shortname on ray
328
+ * @drawable false
329
+ */
330
+ onRay(inputs) {
331
+ return this.add({ first: inputs.point, second: this.mul({ vector: inputs.vector, scalar: inputs.distance }) });
332
+ }
333
+ /**
334
+ * Create a xyz vector
335
+ * @param inputs Vector coordinates
336
+ * @returns Create a vector of xyz values
337
+ * @group create
338
+ * @shortname vector XYZ
339
+ * @drawable true
340
+ */
341
+ vectorXYZ(inputs) {
342
+ return [inputs.x, inputs.y, inputs.z];
343
+ }
344
+ /**
345
+ * Create 2d xy vector
346
+ * @param inputs Vector coordinates
347
+ * @returns Create a vector of xy values
348
+ * @group create
349
+ * @shortname vector XY
350
+ * @drawable true
351
+ */
352
+ vectorXY(inputs) {
353
+ return [inputs.x, inputs.y];
354
+ }
355
+ /**
356
+ * Creates a vector of integers between 0 and maximum ceiling integer
357
+ * @param inputs Max value for the range
358
+ * @returns Vector containing items from 0 to max
359
+ * @group create
360
+ * @shortname range
361
+ * @drawable false
362
+ */
363
+ range(inputs) {
364
+ const res = [];
365
+ for (let i = 0; i < inputs.max; i++) {
366
+ res.push(i);
367
+ }
368
+ return res;
369
+ }
370
+ /**
371
+ * Computes signed angle between two vectors and a reference. This will always return a smaller angle between two possible angles.
372
+ * @param inputs Contains information of two vectors and a reference vector
373
+ * @returns Signed angle in degrees
374
+ * @group angles
375
+ * @shortname signed angle
376
+ * @drawable false
377
+ */
378
+ signedAngleBetween(inputs) {
379
+ const nab = this.cross({ first: inputs.first, second: inputs.second });
380
+ const al = this.norm({ vector: inputs.first });
381
+ const bl = this.norm({ vector: inputs.second });
382
+ const abl = al * bl;
383
+ const adb = this.dot({ first: inputs.first, second: inputs.second });
384
+ const sina = this.norm({ vector: nab }) / abl;
385
+ const cosa = adb / abl;
386
+ const w = Math.atan2(sina, cosa);
387
+ const s = this.dot({ first: inputs.reference, second: nab });
388
+ const res = s > 0.0 ? w : 2 * Math.PI - w;
389
+ return this.math.radToDeg({ number: res });
390
+ }
391
+ /**
392
+ * Creates a vector that contains numbers spanning between minimum and maximum values at a given step
393
+ * @param inputs Span information containing min, max and step values
394
+ * @returns Vector containing number between min, max and increasing at a given step
395
+ * @group create
396
+ * @shortname span
397
+ * @drawable false
398
+ */
399
+ span(inputs) {
400
+ const res = [];
401
+ for (let i = inputs.min; i <= inputs.max; i += inputs.step) {
402
+ res.push(i);
403
+ }
404
+ return res;
405
+ }
406
+ /**
407
+ * Creates a vector that contains numbers spanning between minimum and maximum values at a given ease function
408
+ * @param inputs Span information containing min, max and ease function
409
+ * @returns Vector containing numbers between min, max and increasing in non-linear steps defined by nr of items in the vector and type
410
+ * @group create
411
+ * @shortname span ease items
412
+ * @drawable false
413
+ */
414
+ spanEaseItems(inputs) {
415
+ const res = [];
416
+ for (let i = 0; i < inputs.nrItems; i++) {
417
+ const x = i * 1 / (inputs.nrItems - 1);
418
+ res.push(this.math.ease({ x: x, ease: inputs.ease, min: inputs.min, max: inputs.max }));
419
+ }
420
+ if (inputs.intervals) {
421
+ return res.map((v, i, a) => i === 0 ? v : v - a[i - 1]);
422
+ }
423
+ return res;
424
+ }
425
+ /**
426
+ * Creates a vector that contains numbers spanning between minimum and maximum values by giving nr of items
427
+ * @param inputs Span information containing min, max and step values
428
+ * @returns Vector containing number between min, max by giving nr of items
429
+ * @group create
430
+ * @shortname span linear items
431
+ * @drawable false
432
+ */
433
+ spanLinearItems(inputs) {
434
+ const res = [];
435
+ const dist = (inputs.max - inputs.min);
436
+ for (let i = 0; i < inputs.nrItems; i++) {
437
+ const x = dist * i / (inputs.nrItems - 1);
438
+ res.push(x + inputs.min);
439
+ }
440
+ return res;
441
+ }
442
+ /**
443
+ * Subtract two vectors
444
+ * @param inputs Two vectors
445
+ * @returns Vector that result by subtraction two vectors
446
+ * @group base
447
+ * @shortname sub
448
+ * @drawable false
449
+ */
450
+ sub(inputs) {
451
+ const res = [];
452
+ for (let i = 0; i < inputs.first.length; i++) {
453
+ res.push(inputs.first[i] - inputs.second[i]);
454
+ }
455
+ return res;
456
+ }
457
+ /**
458
+ * Sums the values of the vector
459
+ * @param inputs Vector to sum
460
+ * @returns Number that results by adding up all values in the vector
461
+ * @group base
462
+ * @shortname sum
463
+ * @drawable false
464
+ */
465
+ sum(inputs) {
466
+ return inputs.vector.reduce((a, b) => a + b, 0);
467
+ }
468
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./api";
package/lib/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./api";
package/package.json ADDED
@@ -0,0 +1,93 @@
1
+ {
2
+ "name": "@bitbybit-dev/base",
3
+ "version": "0.19.0-alpha.0",
4
+ "description": "Bit By Bit Developers Base CAD Library to Program Geometry",
5
+ "main": "index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/bitbybit-dev/bitbybit"
9
+ },
10
+ "keywords": [
11
+ "Bit By Bit Developers",
12
+ "bitbybit",
13
+ "bitbybit.dev",
14
+ "Geometry",
15
+ "CAD",
16
+ "3D",
17
+ "JSCAD",
18
+ "OCCT",
19
+ "OpenCascade",
20
+ "Creative coding",
21
+ "CSG",
22
+ "Mesh",
23
+ "Meshing",
24
+ "Manifold",
25
+ "Manifold-3D",
26
+ "WebGL",
27
+ "WebGPU",
28
+ "Parametric",
29
+ "Modeling",
30
+ "Browser CAD",
31
+ "3D algorithms",
32
+ "3D modeling",
33
+ "3D printing",
34
+ "3D printing algorithms",
35
+ "3D software",
36
+ "OpenCascade Technology",
37
+ "AEC",
38
+ "Automotive",
39
+ "Engineering",
40
+ "CAE",
41
+ "CAM"
42
+ ],
43
+ "directories": {
44
+ "lib": "lib"
45
+ },
46
+ "scripts": {
47
+ "build": "tsc -p tsconfig.bitbybit.json",
48
+ "build-p": "npm run build && npm run copy-package && npm run copy-readme && npm run delete-coverage",
49
+ "copy-package": "cp -R ./package.json ./dist",
50
+ "copy-readme": "cp -R ./README.md ./dist && cp -R ./LICENSE ./dist",
51
+ "delete-coverage": "rm -R ./dist/coverage",
52
+ "test": "set NODE_OPTIONS=--experimental-specifier-resolution=node && jest --watchAll=true",
53
+ "test-c": "set NODE_OPTIONS=--experimental-specifier-resolution=node && jest --coverage --watchAll=false",
54
+ "test-c-l": "set NODE_OPTIONS=--experimental-specifier-resolution=node && jest --coverage --watchAll=true"
55
+ },
56
+ "author": "Bit by bit developers",
57
+ "license": "MIT",
58
+ "types": "./index.d.ts",
59
+ "type": "module",
60
+ "dependencies": {
61
+ },
62
+ "devDependencies": {
63
+ "sass": "1.57.1",
64
+ "@testing-library/jest-dom": "5.14.1",
65
+ "mvdir": "1.0.21",
66
+ "jest": "29.4.1",
67
+ "ts-node": "10.9.1",
68
+ "ts-jest": "29.0.0",
69
+ "typescript": "4.8.2",
70
+ "@types/jest": "29.0.0",
71
+ "@types/three": "0.169.0",
72
+ "babel-jest": "29.0.0",
73
+ "@babel/core": "7.16.0",
74
+ "@babel/preset-env": "7.16.0",
75
+ "@babel/preset-typescript": "7.16.0",
76
+ "jest-html-reporters": "3.0.11"
77
+ },
78
+ "jest": {
79
+ "preset": "ts-jest",
80
+ "transform": {
81
+ "\\.[jt]sx?$": "babel-jest"
82
+ },
83
+ "extensionsToTreatAsEsm": [
84
+ ".ts"
85
+ ],
86
+ "transformIgnorePatterns": [
87
+ "node_modules/(?!@bitbybit-dev)/"
88
+ ],
89
+ "collectCoverageFrom": [
90
+ "lib/api/**/*"
91
+ ]
92
+ }
93
+ }