@emasoft/svg-matrix 1.0.30 → 1.0.31
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.
- package/bin/svg-matrix.js +310 -61
- package/bin/svglinter.cjs +102 -3
- package/bin/svgm.js +236 -27
- package/package.json +1 -1
- package/src/animation-optimization.js +137 -17
- package/src/animation-references.js +123 -6
- package/src/arc-length.js +213 -4
- package/src/bezier-analysis.js +217 -21
- package/src/bezier-intersections.js +275 -12
- package/src/browser-verify.js +237 -4
- package/src/clip-path-resolver.js +168 -0
- package/src/convert-path-data.js +479 -28
- package/src/css-specificity.js +73 -10
- package/src/douglas-peucker.js +219 -2
- package/src/flatten-pipeline.js +284 -26
- package/src/geometry-to-path.js +250 -25
- package/src/gjk-collision.js +236 -33
- package/src/index.js +261 -3
- package/src/inkscape-support.js +86 -28
- package/src/logger.js +48 -3
- package/src/marker-resolver.js +278 -74
- package/src/mask-resolver.js +265 -66
- package/src/matrix.js +44 -5
- package/src/mesh-gradient.js +352 -102
- package/src/off-canvas-detection.js +382 -13
- package/src/path-analysis.js +192 -18
- package/src/path-data-plugins.js +309 -5
- package/src/path-optimization.js +129 -5
- package/src/path-simplification.js +188 -32
- package/src/pattern-resolver.js +454 -106
- package/src/polygon-clip.js +324 -1
- package/src/svg-boolean-ops.js +226 -9
- package/src/svg-collections.js +7 -5
- package/src/svg-flatten.js +386 -62
- package/src/svg-parser.js +179 -8
- package/src/svg-rendering-context.js +235 -6
- package/src/svg-toolbox.js +45 -8
- package/src/svg2-polyfills.js +40 -10
- package/src/transform-decomposition.js +258 -32
- package/src/transform-optimization.js +259 -13
- package/src/transforms2d.js +82 -9
- package/src/transforms3d.js +62 -10
- package/src/use-symbol-resolver.js +286 -42
- package/src/vector.js +64 -8
- package/src/verification.js +392 -1
package/src/vector.js
CHANGED
|
@@ -5,8 +5,19 @@ import Decimal from 'decimal.js';
|
|
|
5
5
|
* Accepts numbers, strings, or Decimal instances.
|
|
6
6
|
* @param {number|string|Decimal} x - The value to convert
|
|
7
7
|
* @returns {Decimal} The Decimal representation
|
|
8
|
+
* @throws {Error} If x is null, undefined, or cannot be converted to Decimal
|
|
8
9
|
*/
|
|
9
|
-
const D = x =>
|
|
10
|
+
const D = x => {
|
|
11
|
+
if (x === null || x === undefined) {
|
|
12
|
+
throw new Error(`Cannot convert ${x === null ? 'null' : 'undefined'} to Decimal`);
|
|
13
|
+
}
|
|
14
|
+
if (x instanceof Decimal) return x;
|
|
15
|
+
try {
|
|
16
|
+
return new Decimal(x);
|
|
17
|
+
} catch (err) {
|
|
18
|
+
throw new Error(`Invalid numeric value: ${err.message}`);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
10
21
|
|
|
11
22
|
/**
|
|
12
23
|
* Vector - Decimal-backed vector class for arbitrary-precision vector operations.
|
|
@@ -28,11 +39,21 @@ export class Vector {
|
|
|
28
39
|
/**
|
|
29
40
|
* Create a new Vector from an array of components.
|
|
30
41
|
* @param {Array<number|string|Decimal>} components - Array of vector components
|
|
31
|
-
* @throws {Error} If components is not an array
|
|
42
|
+
* @throws {Error} If components is not an array, is empty, or contains invalid values
|
|
32
43
|
*/
|
|
33
44
|
constructor(components) {
|
|
34
45
|
if (!Array.isArray(components)) throw new Error('Vector requires array');
|
|
35
|
-
|
|
46
|
+
if (components.length === 0) throw new Error('Vector requires at least one component');
|
|
47
|
+
try {
|
|
48
|
+
this.data = components.map((c, i) => {
|
|
49
|
+
if (c === null || c === undefined) {
|
|
50
|
+
throw new Error(`Vector component at index ${i} is ${c === null ? 'null' : 'undefined'}`);
|
|
51
|
+
}
|
|
52
|
+
return D(c);
|
|
53
|
+
});
|
|
54
|
+
} catch (err) {
|
|
55
|
+
throw new Error(`Vector constructor failed: ${err.message}`);
|
|
56
|
+
}
|
|
36
57
|
this.length = this.data.length;
|
|
37
58
|
}
|
|
38
59
|
|
|
@@ -40,8 +61,12 @@ export class Vector {
|
|
|
40
61
|
* Factory method to create a Vector from an array.
|
|
41
62
|
* @param {Array<number|string|Decimal>} arr - Array of vector components
|
|
42
63
|
* @returns {Vector} New Vector instance
|
|
64
|
+
* @throws {Error} If arr is null or undefined
|
|
43
65
|
*/
|
|
44
66
|
static from(arr) {
|
|
67
|
+
if (arr === null || arr === undefined) {
|
|
68
|
+
throw new Error(`Vector.from: argument is ${arr === null ? 'null' : 'undefined'}`);
|
|
69
|
+
}
|
|
45
70
|
return new Vector(arr);
|
|
46
71
|
}
|
|
47
72
|
|
|
@@ -116,9 +141,18 @@ export class Vector {
|
|
|
116
141
|
* Scalar multiplication.
|
|
117
142
|
* @param {number|string|Decimal} scalar - Scalar to multiply by
|
|
118
143
|
* @returns {Vector} New scaled Vector
|
|
144
|
+
* @throws {Error} If scalar is null, undefined, or invalid
|
|
119
145
|
*/
|
|
120
146
|
scale(scalar) {
|
|
121
|
-
|
|
147
|
+
if (scalar === null || scalar === undefined) {
|
|
148
|
+
throw new Error(`scale: scalar is ${scalar === null ? 'null' : 'undefined'}`);
|
|
149
|
+
}
|
|
150
|
+
let s;
|
|
151
|
+
try {
|
|
152
|
+
s = D(scalar);
|
|
153
|
+
} catch (err) {
|
|
154
|
+
throw new Error(`scale: invalid scalar - ${err.message}`);
|
|
155
|
+
}
|
|
122
156
|
return new Vector(this.data.map(v => v.mul(s)));
|
|
123
157
|
}
|
|
124
158
|
|
|
@@ -156,12 +190,15 @@ export class Vector {
|
|
|
156
190
|
*
|
|
157
191
|
* @param {Vector} other - Vector to compute outer product with
|
|
158
192
|
* @returns {Decimal[][]} 2D array of Decimals (can be passed to Matrix.from())
|
|
159
|
-
* @throws {Error} If other is not a Vector
|
|
193
|
+
* @throws {Error} If other is not a Vector or either vector is empty
|
|
160
194
|
*/
|
|
161
195
|
outer(other) {
|
|
162
196
|
if (!other || !(other instanceof Vector)) {
|
|
163
197
|
throw new Error('outer: argument must be a Vector');
|
|
164
198
|
}
|
|
199
|
+
if (this.length === 0 || other.length === 0) {
|
|
200
|
+
throw new Error('outer: cannot compute outer product with empty vector');
|
|
201
|
+
}
|
|
165
202
|
const rows = this.length, cols = other.length;
|
|
166
203
|
const out = Array.from({ length: rows }, (_, i) =>
|
|
167
204
|
Array.from({ length: cols }, (_, j) => this.data[i].mul(other.data[j]))
|
|
@@ -267,8 +304,12 @@ export class Vector {
|
|
|
267
304
|
* @throws {Error} If unable to find orthogonal vector (e.g., zero vector)
|
|
268
305
|
*/
|
|
269
306
|
orthogonal() {
|
|
307
|
+
const n = this.norm();
|
|
308
|
+
if (n.isZero()) {
|
|
309
|
+
throw new Error('orthogonal: cannot find orthogonal vector to zero vector');
|
|
310
|
+
}
|
|
270
311
|
if (this.length === 2) {
|
|
271
|
-
// 2D perpendicular: rotate 90 degrees counterclockwise
|
|
312
|
+
// 2D perpendicular: rotate 90 degrees counterclockwise [-y, x]
|
|
272
313
|
return new Vector([this.data[1].negated(), this.data[0]]);
|
|
273
314
|
}
|
|
274
315
|
// For n > 2: find a standard basis vector not parallel to this,
|
|
@@ -282,7 +323,7 @@ export class Vector {
|
|
|
282
323
|
const orthNorm = orth.norm();
|
|
283
324
|
if (!orthNorm.isZero()) return orth.normalize();
|
|
284
325
|
}
|
|
285
|
-
throw new Error('
|
|
326
|
+
throw new Error('orthogonal: unable to find orthogonal vector (degenerate case)');
|
|
286
327
|
}
|
|
287
328
|
|
|
288
329
|
/**
|
|
@@ -322,11 +363,26 @@ export class Vector {
|
|
|
322
363
|
* @param {Vector} other - Vector to compare with
|
|
323
364
|
* @param {number|string|Decimal} [tolerance=0] - Maximum allowed difference per component
|
|
324
365
|
* @returns {boolean} True if vectors are equal within tolerance
|
|
366
|
+
* @throws {Error} If tolerance is invalid (null, NaN, or negative)
|
|
325
367
|
*/
|
|
326
368
|
equals(other, tolerance = 0) {
|
|
327
369
|
if (!(other instanceof Vector)) return false;
|
|
328
370
|
if (other.length !== this.length) return false;
|
|
329
|
-
|
|
371
|
+
if (tolerance === null) {
|
|
372
|
+
throw new Error('equals: tolerance cannot be null');
|
|
373
|
+
}
|
|
374
|
+
let tol;
|
|
375
|
+
try {
|
|
376
|
+
tol = D(tolerance);
|
|
377
|
+
if (tol.isNaN()) {
|
|
378
|
+
throw new Error('equals: tolerance cannot be NaN');
|
|
379
|
+
}
|
|
380
|
+
if (tol.isNegative()) {
|
|
381
|
+
throw new Error('equals: tolerance must be non-negative');
|
|
382
|
+
}
|
|
383
|
+
} catch (err) {
|
|
384
|
+
throw new Error(`equals: invalid tolerance - ${err.message}`);
|
|
385
|
+
}
|
|
330
386
|
for (let i = 0; i < this.length; i++) {
|
|
331
387
|
const diff = this.data[i].minus(other.data[i]).abs();
|
|
332
388
|
if (diff.greaterThan(tol)) return false;
|