@flighthq/geometry 0.3.1-next.847.2e6f8bf → 0.3.1-next.887.9f59a84
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform2d.d.ts","sourceRoot":"","sources":["../src/transform2d.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIzF,wBAAgB,iBAAiB,CAC/B,CAAC,CAAC,EAAE,MAAM,EACV,CAAC,CAAC,EAAE,MAAM,EACV,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,WAAW,CAYb;AAQD,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"transform2d.d.ts","sourceRoot":"","sources":["../src/transform2d.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIzF,wBAAgB,iBAAiB,CAC/B,CAAC,CAAC,EAAE,MAAM,EACV,CAAC,CAAC,EAAE,MAAM,EACV,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,WAAW,CAYb;AAQD,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CA8BrG"}
|
package/dist/transform2d.js
CHANGED
|
@@ -27,9 +27,12 @@ export function decomposeMatrixToTransform2D(out, source) {
|
|
|
27
27
|
const d = source.d;
|
|
28
28
|
const scaleX = Math.sqrt(a * a + b * b);
|
|
29
29
|
// A negative determinant is a reflection one scale factor cannot absorb; carry it on scaleY.
|
|
30
|
-
const
|
|
30
|
+
const reflected = a * d - b * c < 0;
|
|
31
|
+
const scaleY = reflected ? -Math.sqrt(c * c + d * d) : Math.sqrt(c * c + d * d);
|
|
31
32
|
// Forward: the c/d axis carries (rotation + skewX), the a/b axis carries (rotation + skewY).
|
|
32
|
-
|
|
33
|
+
// Inverting c = -sin(skewX) * scaleY and d = cos(skewX) * scaleY gives atan2(-c / scaleY, d / scaleY);
|
|
34
|
+
// dividing by a negative scaleY flips the sign of both arguments, so the reflected branch is atan2(c, -d).
|
|
35
|
+
const skewXDegrees = (reflected ? Math.atan2(c, -d) : Math.atan2(-c, d)) * RAD_TO_DEG;
|
|
33
36
|
const skewYDegrees = Math.atan2(b, a) * RAD_TO_DEG;
|
|
34
37
|
if (skewXDegrees === skewYDegrees) {
|
|
35
38
|
// Both axes share one angle: a pure rotation, no skew.
|
package/dist/transform2d.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform2d.js","sourceRoot":"","sources":["../src/transform2d.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,oGAAoG;AACpG,sDAAsD;AACtD,MAAM,UAAU,iBAAiB,CAC/B,CAAU,EACV,CAAU,EACV,QAAiB,EACjB,MAAe,EACf,MAAe,EACf,KAAc,EACd,KAAc,EACd,MAAe,EACf,MAAe;IAEf,OAAO,YAAY,CAAC;QAClB,MAAM,EAAE,MAAM,IAAI,CAAC;QACnB,MAAM,EAAE,MAAM,IAAI,CAAC;QACnB,QAAQ,EAAE,QAAQ,IAAI,CAAC;QACvB,MAAM,EAAE,MAAM,IAAI,CAAC;QACnB,MAAM,EAAE,MAAM,IAAI,CAAC;QACnB,KAAK,EAAE,KAAK,IAAI,CAAC;QACjB,KAAK,EAAE,KAAK,IAAI,CAAC;QACjB,CAAC,EAAE,CAAC,IAAI,CAAC;QACT,CAAC,EAAE,CAAC,IAAI,CAAC;KACV,CAAC,CAAC;AACL,CAAC;AAED,mGAAmG;AACnG,qGAAqG;AACrG,sGAAsG;AACtG,EAAE;AACF,oGAAoG;AACpG,qGAAqG;AACrG,MAAM,UAAU,4BAA4B,CAAC,GAAoB,EAAE,MAA4B;IAC7F,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IACnB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;IACnB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,6FAA6F;IAC7F,MAAM,
|
|
1
|
+
{"version":3,"file":"transform2d.js","sourceRoot":"","sources":["../src/transform2d.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/geometry",
|
|
3
|
-
"version": "0.3.1-next.
|
|
3
|
+
"version": "0.3.1-next.887.9f59a84",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/entity": "0.3.1-next.
|
|
42
|
-
"@flighthq/log": "0.3.1-next.
|
|
43
|
-
"@flighthq/types": "0.3.1-next.
|
|
41
|
+
"@flighthq/entity": "0.3.1-next.887.9f59a84",
|
|
42
|
+
"@flighthq/log": "0.3.1-next.887.9f59a84",
|
|
43
|
+
"@flighthq/types": "0.3.1-next.887.9f59a84"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"typescript": "^5.3.0"
|
package/src/transform2d.test.ts
CHANGED
|
@@ -81,4 +81,42 @@ describe('decomposeMatrixToTransform2D', () => {
|
|
|
81
81
|
expect(out.scaleX).toBeCloseTo(1);
|
|
82
82
|
expect(out.scaleY).toBeCloseTo(-1);
|
|
83
83
|
});
|
|
84
|
+
|
|
85
|
+
it('round-trips a mirrored matrix through the forward build', () => {
|
|
86
|
+
expectRoundTrip(createMatrix(1, 0, 0, -1, 0, 0));
|
|
87
|
+
expectRoundTrip(createMatrix(-1, 0, 0, 1, 0, 0));
|
|
88
|
+
expectRoundTrip(createMatrix(0.5, 0.8, 0.8, -0.5, 3, 4));
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// The failure set is the negative-determinant set on any input, not a mirror-specific shape, so the
|
|
92
|
+
// property is asserted over a grid spanning both determinant signs rather than at hand-picked cases.
|
|
93
|
+
it('round-trips every non-degenerate matrix in a grid spanning both determinant signs', () => {
|
|
94
|
+
const values = [-2, -1, -0.5, 0.5, 1, 2];
|
|
95
|
+
let negativeDeterminantCount = 0;
|
|
96
|
+
for (const a of values) {
|
|
97
|
+
for (const b of values) {
|
|
98
|
+
for (const c of values) {
|
|
99
|
+
for (const d of values) {
|
|
100
|
+
if (Math.abs(a * d - b * c) < 1e-9) continue;
|
|
101
|
+
if (a * d - b * c < 0) negativeDeterminantCount++;
|
|
102
|
+
expectRoundTrip(createMatrix(a, b, c, d, 0, 0));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Guards the guard: a grid that stopped covering reflections would still pass every assertion above.
|
|
108
|
+
expect(negativeDeterminantCount).toBe(572);
|
|
109
|
+
});
|
|
84
110
|
});
|
|
111
|
+
|
|
112
|
+
// Decomposing and rebuilding through the forward convention must reproduce the original cells. This is
|
|
113
|
+
// the losslessness `setNodeLocalMatrix` promises its callers, and it holds for both determinant signs.
|
|
114
|
+
function expectRoundTrip(source: Readonly<ReturnType<typeof createMatrix>>) {
|
|
115
|
+
const out = createTransform2D();
|
|
116
|
+
decomposeMatrixToTransform2D(out, source);
|
|
117
|
+
const rebuilt = buildMatrix(out.x, out.y, out.rotation, out.scaleX, out.scaleY, out.skewX, out.skewY);
|
|
118
|
+
expect(rebuilt.a).toBeCloseTo(source.a);
|
|
119
|
+
expect(rebuilt.b).toBeCloseTo(source.b);
|
|
120
|
+
expect(rebuilt.c).toBeCloseTo(source.c);
|
|
121
|
+
expect(rebuilt.d).toBeCloseTo(source.d);
|
|
122
|
+
}
|