pts 1.0.0 → 1.0.2
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/dist/index.d.mts +292 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +292 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6104 -4631
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6103 -4632
- package/dist/index.mjs.map +1 -1
- package/dist/pts.js +6155 -4682
- package/dist/pts.js.map +1 -1
- package/dist/pts.min.js +2 -2
- package/dist/pts.min.js.map +1 -1
- package/package.json +3 -2
- package/src/Canvas.ts +99 -4
- package/src/Color.ts +48 -28
- package/src/Create.ts +290 -2
- package/src/Dom.ts +1 -1
- package/src/LinearAlgebra.ts +7 -6
- package/src/Num.ts +18 -11
- package/src/Op.ts +315 -0
- package/src/Pt.ts +8 -1
- package/src/Svg.ts +82 -3
- package/src/Types.ts +17 -0
- package/src/UI.ts +21 -1
- package/src/Util.ts +23 -1
- package/src/_path.ts +1402 -0
- package/src/_triangulate.ts +72 -10
package/src/_triangulate.ts
CHANGED
|
@@ -43,9 +43,12 @@ const EMPTY: Triangulation = {
|
|
|
43
43
|
const EPS = 1.1102230246251565e-16;
|
|
44
44
|
// Bounds on the rounding error of the determinants below, relative to the sum
|
|
45
45
|
// of the absolute values of their terms (the classic forward error analysis
|
|
46
|
-
// of the orientation and in-circle determinants).
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
// of the orientation and in-circle determinants). Computed through a function
|
|
47
|
+
// marked pure so bundles that never triangulate drop them: a bundler that
|
|
48
|
+
// turns these consts into vars cannot prove the bare products side-effect free.
|
|
49
|
+
const errorBound = (a: number, b: number) => (a + b * EPS) * EPS;
|
|
50
|
+
const ORIENT_BOUND = /* @__PURE__ */ errorBound(3, 16);
|
|
51
|
+
const INCIRCLE_BOUND = /* @__PURE__ */ errorBound(10, 96);
|
|
49
52
|
// Coordinates that become integers below 2^31 when scaled by one power of two
|
|
50
53
|
// (pixel grids, halves, quarters, every Float32 value in a sane range) keep
|
|
51
54
|
// their differences exact in a double; the products those differences form are
|
|
@@ -322,15 +325,28 @@ function _incircleInt(
|
|
|
322
325
|
// Exact evaluation: each double is sign * mantissa * 2^exponent with an
|
|
323
326
|
// integer mantissa, so scaling every input to the smallest exponent gives
|
|
324
327
|
// exact integers whose determinant has the same sign as the real one.
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
const
|
|
328
|
+
// Views over one buffer, and the indices of the words holding a double's
|
|
329
|
+
// high bits (sign, exponent, top of the mantissa) and low bits. Every
|
|
330
|
+
// initializer is a call marked pure, so a bundle that never triangulates
|
|
331
|
+
// drops all of it (a bundler cannot prove `HI ^ 1` free of side effects).
|
|
332
|
+
const _buffer = /* @__PURE__ */ new ArrayBuffer(8);
|
|
333
|
+
const _bits = /* @__PURE__ */ new Float64Array(_buffer);
|
|
334
|
+
const _words = /* @__PURE__ */ new Uint32Array(_buffer);
|
|
335
|
+
const HI = /* @__PURE__ */ wordIndex(true);
|
|
336
|
+
const LO = /* @__PURE__ */ wordIndex(false);
|
|
337
|
+
|
|
338
|
+
function wordIndex(high: boolean): number {
|
|
339
|
+
// little-endian hosts store the high word of 1.0 (0x3ff00000) second
|
|
340
|
+
const probe = new Float64Array([1]);
|
|
341
|
+
const highSecond = new Uint32Array(probe.buffer)[1] === 0x3ff00000;
|
|
342
|
+
return high === highSecond ? 1 : 0;
|
|
343
|
+
}
|
|
344
|
+
|
|
330
345
|
const _mant = new Float64Array(8);
|
|
331
346
|
const _expo = new Int32Array(8);
|
|
332
|
-
// BigInt is only
|
|
333
|
-
//
|
|
347
|
+
// BigInt is used only when called: by `crossingParameter` (every proper
|
|
348
|
+
// crossing in the polygon overlay) and by the exact predicates below, so
|
|
349
|
+
// loading this module never requires it
|
|
334
350
|
|
|
335
351
|
function _scaled(values: Float64Array, count: number): bigint[] {
|
|
336
352
|
let minExpo = 0x7fffffff;
|
|
@@ -359,6 +375,52 @@ function _scaled(values: Float64Array, count: number): bigint[] {
|
|
|
359
375
|
return out;
|
|
360
376
|
}
|
|
361
377
|
|
|
378
|
+
// `Number(bigint)` is finite below 2^1024; shift in whole limbs until then.
|
|
379
|
+
// Created on first use, so loading this module never evaluates BigInt.
|
|
380
|
+
let _finiteLimit: bigint | undefined;
|
|
381
|
+
let _shiftStep: bigint;
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Parameter of a known proper crossing along a→b. Evaluate the determinants
|
|
385
|
+
* exactly before division: shallow crossings can lose most of their digits
|
|
386
|
+
* when two rounded products are subtracted. Used by the polygon overlay.
|
|
387
|
+
*/
|
|
388
|
+
export function crossingParameter(
|
|
389
|
+
ax: number,
|
|
390
|
+
ay: number,
|
|
391
|
+
bx: number,
|
|
392
|
+
by: number,
|
|
393
|
+
cx: number,
|
|
394
|
+
cy: number,
|
|
395
|
+
dx: number,
|
|
396
|
+
dy: number,
|
|
397
|
+
): number {
|
|
398
|
+
_input.set([ax, ay, bx, by, cx, cy, dx, dy]);
|
|
399
|
+
const [a, b, c, d, e, f, g, h] = _scaled(_input, 8);
|
|
400
|
+
const rx = g - e;
|
|
401
|
+
const ry = h - f;
|
|
402
|
+
let numerator = rx * (b - f) - ry * (a - e);
|
|
403
|
+
let denominator = numerator - (rx * (d - f) - ry * (c - e));
|
|
404
|
+
if (denominator < BigInt(0)) {
|
|
405
|
+
numerator = -numerator;
|
|
406
|
+
denominator = -denominator;
|
|
407
|
+
}
|
|
408
|
+
// Keep the conversion finite even when the input doubles span hundreds of
|
|
409
|
+
// binary exponents. The numerator is between zero and the denominator, and
|
|
410
|
+
// a denominator of ordinary size needs no shift at all.
|
|
411
|
+
if (_finiteLimit === undefined) {
|
|
412
|
+
_finiteLimit = BigInt(1) << BigInt(1023);
|
|
413
|
+
_shiftStep = BigInt(64);
|
|
414
|
+
}
|
|
415
|
+
let shift = BigInt(0);
|
|
416
|
+
let scaled = denominator;
|
|
417
|
+
while (scaled >= _finiteLimit) {
|
|
418
|
+
scaled >>= _shiftStep;
|
|
419
|
+
shift += _shiftStep;
|
|
420
|
+
}
|
|
421
|
+
return Number(numerator >> shift) / Number(scaled);
|
|
422
|
+
}
|
|
423
|
+
|
|
362
424
|
/** Exact orientation, evaluated in BigInt. Used when the fast filter cannot decide. */
|
|
363
425
|
export function orient2dExact(
|
|
364
426
|
ax: number,
|