three-text 0.4.9 → 0.4.11
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/LICENSE_THIRD_PARTY +8 -4
- package/README.md +1 -1
- package/dist/index.cjs +566 -553
- package/dist/index.d.ts +3 -0
- package/dist/index.js +566 -553
- package/dist/index.min.cjs +1079 -849
- package/dist/index.min.js +1076 -846
- package/dist/index.umd.js +566 -553
- package/dist/index.umd.min.js +1079 -849
- package/dist/three/react.d.ts +3 -0
- package/dist/types/core/geometry/PathOptimizer.d.ts +0 -2
- package/dist/types/core/geometry/Polygonizer.d.ts +10 -5
- package/dist/types/core/types.d.ts +3 -0
- package/package.json +3 -4
- package/dist/types/utils/MinHeap.d.ts +0 -14
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* three-text v0.4.
|
|
2
|
+
* three-text v0.4.11
|
|
3
3
|
* Copyright (C) 2025 Countertype LLC
|
|
4
4
|
*
|
|
5
5
|
* This program is free software: you can redistribute it and/or modify
|
|
@@ -2434,102 +2434,17 @@ const globalContourCache = new Cache();
|
|
|
2434
2434
|
const globalWordCache = new Cache();
|
|
2435
2435
|
const globalClusteringCache = new Cache();
|
|
2436
2436
|
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
var a = function a () {
|
|
2448
|
-
if (this instanceof a) {
|
|
2449
|
-
return Reflect.construct(f, arguments, this.constructor);
|
|
2450
|
-
}
|
|
2451
|
-
return f.apply(this, arguments);
|
|
2452
|
-
};
|
|
2453
|
-
a.prototype = f.prototype;
|
|
2454
|
-
} else a = {};
|
|
2455
|
-
Object.defineProperty(a, '__esModule', {value: true});
|
|
2456
|
-
Object.keys(n).forEach(function (k) {
|
|
2457
|
-
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
2458
|
-
Object.defineProperty(a, k, d.get ? d : {
|
|
2459
|
-
enumerable: true,
|
|
2460
|
-
get: function () {
|
|
2461
|
-
return n[k];
|
|
2462
|
-
}
|
|
2463
|
-
});
|
|
2464
|
-
});
|
|
2465
|
-
return a;
|
|
2466
|
-
}
|
|
2467
|
-
|
|
2468
|
-
var libtess_min = {exports: {}};
|
|
2469
|
-
|
|
2470
|
-
/*
|
|
2471
|
-
|
|
2472
|
-
Copyright 2000, Silicon Graphics, Inc. All Rights Reserved.
|
|
2473
|
-
Copyright 2015, Google Inc. All Rights Reserved.
|
|
2474
|
-
|
|
2475
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
2476
|
-
of this software and associated documentation files (the "Software"), to
|
|
2477
|
-
deal in the Software without restriction, including without limitation the
|
|
2478
|
-
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
2479
|
-
sell copies of the Software, and to permit persons to whom the Software is
|
|
2480
|
-
furnished to do so, subject to the following conditions:
|
|
2481
|
-
|
|
2482
|
-
The above copyright notice including the dates of first publication and
|
|
2483
|
-
either this permission notice or a reference to http://oss.sgi.com/projects/FreeB/
|
|
2484
|
-
shall be included in all copies or substantial portions of the Software.
|
|
2485
|
-
|
|
2486
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
2487
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
2488
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
2489
|
-
SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
2490
|
-
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
2491
|
-
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
2492
|
-
|
|
2493
|
-
Original Code. The Original Code is: OpenGL Sample Implementation,
|
|
2494
|
-
Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
|
|
2495
|
-
Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
|
|
2496
|
-
Copyright in any portions created by third parties is as indicated
|
|
2497
|
-
elsewhere herein. All Rights Reserved.
|
|
2498
|
-
*/
|
|
2499
|
-
|
|
2500
|
-
(function (module) {
|
|
2501
|
-
var n;function t(a,b){return a.b===b.b&&a.a===b.a}function u(a,b){return a.b<b.b||a.b===b.b&&a.a<=b.a}function v(a,b,c){var d=b.b-a.b,e=c.b-b.b;return 0<d+e?d<e?b.a-a.a+d/(d+e)*(a.a-c.a):b.a-c.a+e/(d+e)*(c.a-a.a):0}function x(a,b,c){var d=b.b-a.b,e=c.b-b.b;return 0<d+e?(b.a-c.a)*d+(b.a-a.a)*e:0}function z(a,b){return a.a<b.a||a.a===b.a&&a.b<=b.b}function aa(a,b,c){var d=b.a-a.a,e=c.a-b.a;return 0<d+e?d<e?b.b-a.b+d/(d+e)*(a.b-c.b):b.b-c.b+e/(d+e)*(c.b-a.b):0}
|
|
2502
|
-
function ba(a,b,c){var d=b.a-a.a,e=c.a-b.a;return 0<d+e?(b.b-c.b)*d+(b.b-a.b)*e:0}function ca(a){return u(a.b.a,a.a)}function da(a){return u(a.a,a.b.a)}function A(a,b,c,d){a=0>a?0:a;c=0>c?0:c;return a<=c?0===c?(b+d)/2:b+a/(a+c)*(d-b):d+c/(a+c)*(b-d)}function ea(a){var b=B(a.b);C(b,a.c);C(b.b,a.c);D(b,a.a);return b}function E(a,b){var c=!1,d=!1;a!==b&&(b.a!==a.a&&(d=!0,F(b.a,a.a)),b.d!==a.d&&(c=!0,G(b.d,a.d)),H(b,a),d||(C(b,a.a),a.a.c=a),c||(D(b,a.d),a.d.a=a));}function I(a){var b=a.b,c=!1;a.d!==a.b.d&&(c=!0,G(a.d,a.b.d));a.c===a?F(a.a,null):(a.b.d.a=J(a),a.a.c=a.c,H(a,J(a)),c||D(a,a.d));b.c===b?(F(b.a,null),G(b.d,null)):(a.d.a=J(b),b.a.c=b.c,H(b,J(b)));fa(a);}
|
|
2503
|
-
function K(a){var b=B(a),c=b.b;H(b,a.e);b.a=a.b.a;C(c,b.a);b.d=c.d=a.d;b=b.b;H(a.b,J(a.b));H(a.b,b);a.b.a=b.a;b.b.a.c=b.b;b.b.d=a.b.d;b.f=a.f;b.b.f=a.b.f;return b}function L(a,b){var c=!1,d=B(a),e=d.b;b.d!==a.d&&(c=!0,G(b.d,a.d));H(d,a.e);H(e,b);d.a=a.b.a;e.a=b.a;d.d=e.d=a.d;a.d.a=e;c||D(d,a.d);return d}function B(a){var b=new M,c=new M,d=a.b.h;c.h=d;d.b.h=b;b.h=a;a.b.h=c;b.b=c;b.c=b;b.e=c;c.b=b;c.c=c;return c.e=b}function H(a,b){var c=a.c,d=b.c;c.b.e=b;d.b.e=a;a.c=d;b.c=c;}
|
|
2504
|
-
function C(a,b){var c=b.f,d=new N(b,c);c.e=d;b.f=d;c=d.c=a;do c.a=d,c=c.c;while(c!==a)}function D(a,b){var c=b.d,d=new ga(b,c);c.b=d;b.d=d;d.a=a;d.c=b.c;c=a;do c.d=d,c=c.e;while(c!==a)}function fa(a){var b=a.h;a=a.b.h;b.b.h=a;a.b.h=b;}function F(a,b){var c=a.c,d=c;do d.a=b,d=d.c;while(d!==c);c=a.f;d=a.e;d.f=c;c.e=d;}function G(a,b){var c=a.a,d=c;do d.d=b,d=d.e;while(d!==c);c=a.d;d=a.b;d.d=c;c.b=d;}function ha(a){var b=0;Math.abs(a[1])>Math.abs(a[0])&&(b=1);Math.abs(a[2])>Math.abs(a[b])&&(b=2);return b}var O=4*1E150;function P(a,b){a.f+=b.f;a.b.f+=b.b.f;}function ia(a,b,c){a=a.a;b=b.a;c=c.a;if(b.b.a===a)return c.b.a===a?u(b.a,c.a)?0>=x(c.b.a,b.a,c.a):0<=x(b.b.a,c.a,b.a):0>=x(c.b.a,a,c.a);if(c.b.a===a)return 0<=x(b.b.a,a,b.a);b=v(b.b.a,a,b.a);a=v(c.b.a,a,c.a);return b>=a}function Q(a){a.a.i=null;var b=a.e;b.a.c=b.c;b.c.a=b.a;a.e=null;}function ja(a,b){I(a.a);a.c=!1;a.a=b;b.i=a;}function ka(a){var b=a.a.a;do a=R(a);while(a.a.a===b);a.c&&(b=L(S(a).a.b,a.a.e),ja(a,b),a=R(a));return a}
|
|
2505
|
-
function la(a,b,c){var d=new ma;d.a=c;d.e=na(a.f,b.e,d);return c.i=d}function oa(a,b){switch(a.s){case 100130:return 0!==(b&1);case 100131:return 0!==b;case 100132:return 0<b;case 100133:return 0>b;case 100134:return 2<=b||-2>=b}return !1}function pa(a){var b=a.a,c=b.d;c.c=a.d;c.a=b;Q(a);}function T(a,b,c){a=b;for(b=b.a;a!==c;){a.c=!1;var d=S(a),e=d.a;if(e.a!==b.a){if(!d.c){pa(a);break}e=L(b.c.b,e.b);ja(d,e);}b.c!==e&&(E(J(e),e),E(b,e));pa(a);b=d.a;a=d;}return b}
|
|
2506
|
-
function U(a,b,c,d,e,f){var g=!0;do la(a,b,c.b),c=c.c;while(c!==d);for(null===e&&(e=S(b).a.b.c);;){d=S(b);c=d.a.b;if(c.a!==e.a)break;c.c!==e&&(E(J(c),c),E(J(e),c));d.f=b.f-c.f;d.d=oa(a,d.f);b.b=!0;!g&&qa(a,b)&&(P(c,e),Q(b),I(e));g=!1;b=d;e=c;}b.b=!0;f&&ra(a,b);}function sa(a,b,c,d,e){var f=[b.g[0],b.g[1],b.g[2]];b.d=null;b.d=a.o?a.o(f,c,d,a.c)||null:null;null===b.d&&(e?a.n||(V(a,100156),a.n=!0):b.d=c[0]);}
|
|
2507
|
-
function ta(a,b,c){var d=[null,null,null,null];d[0]=b.a.d;d[1]=c.a.d;sa(a,b.a,d,[.5,.5,0,0],!1);E(b,c);}function ua(a,b,c,d,e){var f=Math.abs(b.b-a.b)+Math.abs(b.a-a.a),g=Math.abs(c.b-a.b)+Math.abs(c.a-a.a),h=e+1;d[e]=.5*g/(f+g);d[h]=.5*f/(f+g);a.g[0]+=d[e]*b.g[0]+d[h]*c.g[0];a.g[1]+=d[e]*b.g[1]+d[h]*c.g[1];a.g[2]+=d[e]*b.g[2]+d[h]*c.g[2];}
|
|
2508
|
-
function qa(a,b){var c=S(b),d=b.a,e=c.a;if(u(d.a,e.a)){if(0<x(e.b.a,d.a,e.a))return !1;if(!t(d.a,e.a))K(e.b),E(d,J(e)),b.b=c.b=!0;else if(d.a!==e.a){var c=a.e,f=d.a.h;if(0<=f){var c=c.b,g=c.d,h=c.e,k=c.c,l=k[f];g[l]=g[c.a];k[g[l]]=l;l<=--c.a&&(1>=l?W(c,l):u(h[g[l>>1]],h[g[l]])?W(c,l):va(c,l));h[f]=null;k[f]=c.b;c.b=f;}else for(c.c[-(f+1)]=null;0<c.a&&null===c.c[c.d[c.a-1]];)--c.a;ta(a,J(e),d);}}else {if(0>x(d.b.a,e.a,d.a))return !1;R(b).b=b.b=!0;K(d.b);E(J(e),d);}return !0}
|
|
2509
|
-
function wa(a,b){var c=S(b),d=b.a,e=c.a,f=d.a,g=e.a,h=d.b.a,k=e.b.a,l=new N;x(h,a.a,f);x(k,a.a,g);if(f===g||Math.min(f.a,h.a)>Math.max(g.a,k.a))return !1;if(u(f,g)){if(0<x(k,f,g))return !1}else if(0>x(h,g,f))return !1;var r=h,p=f,q=k,y=g,m,w;u(r,p)||(m=r,r=p,p=m);u(q,y)||(m=q,q=y,y=m);u(r,q)||(m=r,r=q,q=m,m=p,p=y,y=m);u(q,p)?u(p,y)?(m=v(r,q,p),w=v(q,p,y),0>m+w&&(m=-m,w=-w),l.b=A(m,q.b,w,p.b)):(m=x(r,q,p),w=-x(r,y,p),0>m+w&&(m=-m,w=-w),l.b=A(m,q.b,w,y.b)):l.b=(q.b+p.b)/2;z(r,p)||(m=r,r=p,p=m);z(q,y)||
|
|
2510
|
-
(m=q,q=y,y=m);z(r,q)||(m=r,r=q,q=m,m=p,p=y,y=m);z(q,p)?z(p,y)?(m=aa(r,q,p),w=aa(q,p,y),0>m+w&&(m=-m,w=-w),l.a=A(m,q.a,w,p.a)):(m=ba(r,q,p),w=-ba(r,y,p),0>m+w&&(m=-m,w=-w),l.a=A(m,q.a,w,y.a)):l.a=(q.a+p.a)/2;u(l,a.a)&&(l.b=a.a.b,l.a=a.a.a);r=u(f,g)?f:g;u(r,l)&&(l.b=r.b,l.a=r.a);if(t(l,f)||t(l,g))return qa(a,b),!1;if(!t(h,a.a)&&0<=x(h,a.a,l)||!t(k,a.a)&&0>=x(k,a.a,l)){if(k===a.a)return K(d.b),E(e.b,d),b=ka(b),d=S(b).a,T(a,S(b),c),U(a,b,J(d),d,d,!0),!0;if(h===a.a){K(e.b);E(d.e,J(e));f=c=b;g=f.a.b.a;
|
|
2511
|
-
do f=R(f);while(f.a.b.a===g);b=f;f=S(b).a.b.c;c.a=J(e);e=T(a,c,null);U(a,b,e.c,d.b.c,f,!0);return !0}0<=x(h,a.a,l)&&(R(b).b=b.b=!0,K(d.b),d.a.b=a.a.b,d.a.a=a.a.a);0>=x(k,a.a,l)&&(b.b=c.b=!0,K(e.b),e.a.b=a.a.b,e.a.a=a.a.a);return !1}K(d.b);K(e.b);E(J(e),d);d.a.b=l.b;d.a.a=l.a;d.a.h=xa(a.e,d.a);d=d.a;e=[0,0,0,0];l=[f.d,h.d,g.d,k.d];d.g[0]=d.g[1]=d.g[2]=0;ua(d,f,h,e,0);ua(d,g,k,e,2);sa(a,d,l,e,!0);R(b).b=b.b=c.b=!0;return !1}
|
|
2512
|
-
function ra(a,b){for(var c=S(b);;){for(;c.b;)b=c,c=S(c);if(!b.b&&(c=b,b=R(b),null===b||!b.b))break;b.b=!1;var d=b.a,e=c.a,f;if(f=d.b.a!==e.b.a)a:{f=b;var g=S(f),h=f.a,k=g.a,l=void 0;if(u(h.b.a,k.b.a)){if(0>x(h.b.a,k.b.a,h.a)){f=!1;break a}R(f).b=f.b=!0;l=K(h);E(k.b,l);l.d.c=f.d;}else {if(0<x(k.b.a,h.b.a,k.a)){f=!1;break a}f.b=g.b=!0;l=K(k);E(h.e,k.b);l.b.d.c=f.d;}f=!0;}f&&(c.c?(Q(c),I(e),c=S(b),e=c.a):b.c&&(Q(b),I(d),b=R(c),d=b.a));if(d.a!==e.a)if(d.b.a===e.b.a||b.c||c.c||d.b.a!==a.a&&e.b.a!==a.a)qa(a,
|
|
2513
|
-
b);else if(wa(a,b))break;d.a===e.a&&d.b.a===e.b.a&&(P(e,d),Q(b),I(d),b=R(c));}}
|
|
2514
|
-
function ya(a,b){a.a=b;for(var c=b.c;null===c.i;)if(c=c.c,c===b.c){var c=a,d=b,e=new ma;e.a=d.c.b;var f=c.f,g=f.a;do g=g.a;while(null!==g.b&&!f.c(f.b,e,g.b));var f=g.b,h=S(f),e=f.a,g=h.a;if(0===x(e.b.a,d,e.a))e=f.a,t(e.a,d)||t(e.b.a,d)||(K(e.b),f.c&&(I(e.c),f.c=!1),E(d.c,e),ya(c,d));else {var k=u(g.b.a,e.b.a)?f:h,h=void 0;f.d||k.c?(k===f?h=L(d.c.b,e.e):h=L(g.b.c.b,d.c).b,k.c?ja(k,h):(e=c,f=la(c,f,h),f.f=R(f).f+f.a.f,f.d=oa(e,f.f)),ya(c,d)):U(c,f,d.c,d.c,null,!0);}return}c=ka(c.i);e=S(c);f=e.a;e=T(a,
|
|
2515
|
-
e,null);if(e.c===f){var f=e,e=f.c,g=S(c),h=c.a,k=g.a,l=!1;h.b.a!==k.b.a&&wa(a,c);t(h.a,a.a)&&(E(J(e),h),c=ka(c),e=S(c).a,T(a,S(c),g),l=!0);t(k.a,a.a)&&(E(f,J(k)),f=T(a,g,null),l=!0);l?U(a,c,f.c,e,e,!0):(u(k.a,h.a)?d=J(k):d=h,d=L(f.c.b,d),U(a,c,d,d.c,d.c,!1),d.b.i.c=!0,ra(a,c));}else U(a,c,e.c,f,f,!0);}function za(a,b){var c=new ma,d=ea(a.b);d.a.b=O;d.a.a=b;d.b.a.b=-O;d.b.a.a=b;a.a=d.b.a;c.a=d;c.f=0;c.d=!1;c.c=!1;c.h=!0;c.b=!1;d=a.f;d=na(d,d.a,c);c.e=d;}function Aa(a){this.a=new Ba;this.b=a;this.c=ia;}function na(a,b,c){do b=b.c;while(null!==b.b&&!a.c(a.b,b.b,c));a=new Ba(c,b.a,b);b.a.c=a;return b.a=a}function Ba(a,b,c){this.b=a||null;this.a=b||this;this.c=c||this;}function X(){this.d=Y;this.p=this.b=this.q=null;this.j=[0,0,0];this.s=100130;this.n=!1;this.o=this.a=this.e=this.f=null;this.m=!1;this.c=this.r=this.i=this.k=this.l=this.h=null;}var Y=0;n=X.prototype;n.x=function(){Z(this,Y);};n.B=function(a,b){switch(a){case 100142:return;case 100140:switch(b){case 100130:case 100131:case 100132:case 100133:case 100134:this.s=b;return}break;case 100141:this.m=!!b;return;default:V(this,100900);return}V(this,100901);};
|
|
2516
|
-
n.y=function(a){switch(a){case 100142:return 0;case 100140:return this.s;case 100141:return this.m;default:V(this,100900);}return !1};n.A=function(a,b,c){this.j[0]=a;this.j[1]=b;this.j[2]=c;};
|
|
2517
|
-
n.z=function(a,b){var c=b?b:null;switch(a){case 100100:case 100106:this.h=c;break;case 100104:case 100110:this.l=c;break;case 100101:case 100107:this.k=c;break;case 100102:case 100108:this.i=c;break;case 100103:case 100109:this.p=c;break;case 100105:case 100111:this.o=c;break;case 100112:this.r=c;break;default:V(this,100900);}};
|
|
2518
|
-
n.C=function(a,b){var c=!1,d=[0,0,0];Z(this,2);for(var e=0;3>e;++e){var f=a[e];-1E150>f&&(f=-1E150,c=!0);1E150<f&&(f=1E150,c=!0);d[e]=f;}c&&V(this,100155);c=this.q;null===c?(c=ea(this.b),E(c,c.b)):(K(c),c=c.e);c.a.d=b;c.a.g[0]=d[0];c.a.g[1]=d[1];c.a.g[2]=d[2];c.f=1;c.b.f=-1;this.q=c;};n.u=function(a){Z(this,Y);this.d=1;this.b=new Ca;this.c=a;};n.t=function(){Z(this,1);this.d=2;this.q=null;};n.v=function(){Z(this,2);this.d=1;};
|
|
2519
|
-
n.w=function(){Z(this,1);this.d=Y;var a=this.j[0],b=this.j[1],c=this.j[2],d=!1,e=[a,b,c];if(0===a&&0===b&&0===c){for(var b=[-2*1E150,-2*1E150,-2*1E150],f=[2*1E150,2*1E150,2*1E150],c=[],g=[],d=this.b.c,a=d.e;a!==d;a=a.e)for(var h=0;3>h;++h){var k=a.g[h];k<f[h]&&(f[h]=k,g[h]=a);k>b[h]&&(b[h]=k,c[h]=a);}a=0;b[1]-f[1]>b[0]-f[0]&&(a=1);b[2]-f[2]>b[a]-f[a]&&(a=2);if(f[a]>=b[a])e[0]=0,e[1]=0,e[2]=1;else {b=0;f=g[a];c=c[a];g=[0,0,0];f=[f.g[0]-c.g[0],f.g[1]-c.g[1],f.g[2]-c.g[2]];h=[0,0,0];for(a=d.e;a!==d;a=
|
|
2520
|
-
a.e)h[0]=a.g[0]-c.g[0],h[1]=a.g[1]-c.g[1],h[2]=a.g[2]-c.g[2],g[0]=f[1]*h[2]-f[2]*h[1],g[1]=f[2]*h[0]-f[0]*h[2],g[2]=f[0]*h[1]-f[1]*h[0],k=g[0]*g[0]+g[1]*g[1]+g[2]*g[2],k>b&&(b=k,e[0]=g[0],e[1]=g[1],e[2]=g[2]);0>=b&&(e[0]=e[1]=e[2]=0,e[ha(f)]=1);}d=!0;}g=ha(e);a=this.b.c;b=(g+1)%3;c=(g+2)%3;g=0<e[g]?1:-1;for(e=a.e;e!==a;e=e.e)e.b=e.g[b],e.a=g*e.g[c];if(d){e=0;d=this.b.a;for(a=d.b;a!==d;a=a.b)if(b=a.a,!(0>=b.f)){do e+=(b.a.b-b.b.a.b)*(b.a.a+b.b.a.a),b=b.e;while(b!==a.a)}if(0>e)for(e=this.b.c,d=e.e;d!==
|
|
2521
|
-
e;d=d.e)d.a=-d.a;}this.n=!1;e=this.b.b;for(a=e.h;a!==e;a=d)if(d=a.h,b=a.e,t(a.a,a.b.a)&&a.e.e!==a&&(ta(this,b,a),I(a),a=b,b=a.e),b.e===a){if(b!==a){if(b===d||b===d.b)d=d.h;I(b);}if(a===d||a===d.b)d=d.h;I(a);}this.e=e=new Da;d=this.b.c;for(a=d.e;a!==d;a=a.e)a.h=xa(e,a);Ea(e);this.f=new Aa(this);za(this,-O);for(za(this,O);null!==(e=Fa(this.e));){for(;;){a:if(a=this.e,0===a.a)d=Ga(a.b);else if(d=a.c[a.d[a.a-1]],0!==a.b.a&&(a=Ga(a.b),u(a,d))){d=a;break a}if(null===d||!t(d,e))break;d=Fa(this.e);ta(this,e.c,
|
|
2522
|
-
d.c);}ya(this,e);}this.a=this.f.a.a.b.a.a;for(e=0;null!==(d=this.f.a.a.b);)d.h||++e,Q(d);this.f=null;e=this.e;e.b=null;e.d=null;this.e=e.c=null;e=this.b;for(a=e.a.b;a!==e.a;a=d)d=a.b,a=a.a,a.e.e===a&&(P(a.c,a),I(a));if(!this.n){e=this.b;if(this.m)for(a=e.b.h;a!==e.b;a=d)d=a.h,a.b.d.c!==a.d.c?a.f=a.d.c?1:-1:I(a);else for(a=e.a.b;a!==e.a;a=d)if(d=a.b,a.c){for(a=a.a;u(a.b.a,a.a);a=a.c.b);for(;u(a.a,a.b.a);a=a.e);b=a.c.b;for(c=void 0;a.e!==b;)if(u(a.b.a,b.a)){for(;b.e!==a&&(ca(b.e)||0>=x(b.a,b.b.a,b.e.b.a));)c=
|
|
2523
|
-
L(b.e,b),b=c.b;b=b.c.b;}else {for(;b.e!==a&&(da(a.c.b)||0<=x(a.b.a,a.a,a.c.b.a));)c=L(a,a.c.b),a=c.b;a=a.e;}for(;b.e.e!==a;)c=L(b.e,b),b=c.b;}if(this.h||this.i||this.k||this.l)if(this.m)for(e=this.b,d=e.a.b;d!==e.a;d=d.b){if(d.c){this.h&&this.h(2,this.c);a=d.a;do this.k&&this.k(a.a.d,this.c),a=a.e;while(a!==d.a);this.i&&this.i(this.c);}}else {e=this.b;d=!!this.l;a=!1;b=-1;for(c=e.a.d;c!==e.a;c=c.d)if(c.c){a||(this.h&&this.h(4,this.c),a=!0);g=c.a;do d&&(f=g.b.d.c?0:1,b!==f&&(b=f,this.l&&this.l(!!b,this.c))),
|
|
2524
|
-
this.k&&this.k(g.a.d,this.c),g=g.e;while(g!==c.a)}a&&this.i&&this.i(this.c);}if(this.r){e=this.b;for(a=e.a.b;a!==e.a;a=d)if(d=a.b,!a.c){b=a.a;c=b.e;g=void 0;do g=c,c=g.e,g.d=null,null===g.b.d&&(g.c===g?F(g.a,null):(g.a.c=g.c,H(g,J(g))),f=g.b,f.c===f?F(f.a,null):(f.a.c=f.c,H(f,J(f))),fa(g));while(g!==b);b=a.d;a=a.b;a.d=b;b.b=a;}this.r(this.b);this.c=this.b=null;return}}this.b=this.c=null;};
|
|
2525
|
-
function Z(a,b){if(a.d!==b)for(;a.d!==b;)if(a.d<b)switch(a.d){case Y:V(a,100151);a.u(null);break;case 1:V(a,100152),a.t();}else switch(a.d){case 2:V(a,100154);a.v();break;case 1:V(a,100153),a.w();}}function V(a,b){a.p&&a.p(b,a.c);}function ga(a,b){this.b=a||this;this.d=b||this;this.a=null;this.c=!1;}function M(){this.h=this;this.i=this.d=this.a=this.e=this.c=this.b=null;this.f=0;}function J(a){return a.b.e}function Ca(){this.c=new N;this.a=new ga;this.b=new M;this.d=new M;this.b.b=this.d;this.d.b=this.b;}function N(a,b){this.e=a||this;this.f=b||this;this.d=this.c=null;this.g=[0,0,0];this.h=this.a=this.b=0;}function Da(){this.c=[];this.d=null;this.a=0;this.e=!1;this.b=new Ha;}function Ea(a){a.d=[];for(var b=0;b<a.a;b++)a.d[b]=b;a.d.sort(function(a){return function(b,e){return u(a[b],a[e])?1:-1}}(a.c));a.e=!0;Ia(a.b);}function xa(a,b){if(a.e){var c=a.b,d=++c.a;2*d>c.f&&(c.f*=2,c.c=Ja(c.c,c.f+1));var e;0===c.b?e=d:(e=c.b,c.b=c.c[c.b]);c.e[e]=b;c.c[e]=d;c.d[d]=e;c.h&&va(c,d);return e}c=a.a++;a.c[c]=b;return -(c+1)}
|
|
2526
|
-
function Fa(a){if(0===a.a)return Ka(a.b);var b=a.c[a.d[a.a-1]];if(0!==a.b.a&&u(Ga(a.b),b))return Ka(a.b);do--a.a;while(0<a.a&&null===a.c[a.d[a.a-1]]);return b}function Ha(){this.d=Ja([0],33);this.e=[null,null];this.c=[0,0];this.a=0;this.f=32;this.b=0;this.h=!1;this.d[1]=1;}function Ja(a,b){for(var c=Array(b),d=0;d<a.length;d++)c[d]=a[d];for(;d<b;d++)c[d]=0;return c}function Ia(a){for(var b=a.a;1<=b;--b)W(a,b);a.h=!0;}function Ga(a){return a.e[a.d[1]]}function Ka(a){var b=a.d,c=a.e,d=a.c,e=b[1],f=c[e];0<a.a&&(b[1]=b[a.a],d[b[1]]=1,c[e]=null,d[e]=a.b,a.b=e,0<--a.a&&W(a,1));return f}
|
|
2527
|
-
function W(a,b){for(var c=a.d,d=a.e,e=a.c,f=b,g=c[f];;){var h=f<<1;h<a.a&&u(d[c[h+1]],d[c[h]])&&(h+=1);var k=c[h];if(h>a.a||u(d[g],d[k])){c[f]=g;e[g]=f;break}c[f]=k;e[k]=f;f=h;}}function va(a,b){for(var c=a.d,d=a.e,e=a.c,f=b,g=c[f];;){var h=f>>1,k=c[h];if(0===h||u(d[k],d[g])){c[f]=g;e[g]=f;break}c[f]=k;e[k]=f;f=h;}}function ma(){this.e=this.a=null;this.f=0;this.c=this.b=this.h=this.d=!1;}function S(a){return a.e.c.b}function R(a){return a.e.a.b}commonjsGlobal.libtess={GluTesselator:X,windingRule:{GLU_TESS_WINDING_ODD:100130,GLU_TESS_WINDING_NONZERO:100131,GLU_TESS_WINDING_POSITIVE:100132,GLU_TESS_WINDING_NEGATIVE:100133,GLU_TESS_WINDING_ABS_GEQ_TWO:100134},primitiveType:{GL_LINE_LOOP:2,GL_TRIANGLES:4,GL_TRIANGLE_STRIP:5,GL_TRIANGLE_FAN:6},errorType:{GLU_TESS_MISSING_BEGIN_POLYGON:100151,GLU_TESS_MISSING_END_POLYGON:100153,GLU_TESS_MISSING_BEGIN_CONTOUR:100152,GLU_TESS_MISSING_END_CONTOUR:100154,GLU_TESS_COORD_TOO_LARGE:100155,GLU_TESS_NEED_COMBINE_CALLBACK:100156},
|
|
2528
|
-
gluEnum:{GLU_TESS_MESH:100112,GLU_TESS_TOLERANCE:100142,GLU_TESS_WINDING_RULE:100140,GLU_TESS_BOUNDARY_ONLY:100141,GLU_INVALID_ENUM:100900,GLU_INVALID_VALUE:100901,GLU_TESS_BEGIN:100100,GLU_TESS_VERTEX:100101,GLU_TESS_END:100102,GLU_TESS_ERROR:100103,GLU_TESS_EDGE_FLAG:100104,GLU_TESS_COMBINE:100105,GLU_TESS_BEGIN_DATA:100106,GLU_TESS_VERTEX_DATA:100107,GLU_TESS_END_DATA:100108,GLU_TESS_ERROR_DATA:100109,GLU_TESS_EDGE_FLAG_DATA:100110,GLU_TESS_COMBINE_DATA:100111}};X.prototype.gluDeleteTess=X.prototype.x;
|
|
2529
|
-
X.prototype.gluTessProperty=X.prototype.B;X.prototype.gluGetTessProperty=X.prototype.y;X.prototype.gluTessNormal=X.prototype.A;X.prototype.gluTessCallback=X.prototype.z;X.prototype.gluTessVertex=X.prototype.C;X.prototype.gluTessBeginPolygon=X.prototype.u;X.prototype.gluTessBeginContour=X.prototype.t;X.prototype.gluTessEndContour=X.prototype.v;X.prototype.gluTessEndPolygon=X.prototype.w; { module.exports = commonjsGlobal.libtess; }
|
|
2530
|
-
} (libtess_min));
|
|
2531
|
-
|
|
2532
|
-
var libtess_minExports = libtess_min.exports;
|
|
2437
|
+
/**
|
|
2438
|
+
* @license
|
|
2439
|
+
* libtess-ts - TypeScript port of the SGI GLU tessellator
|
|
2440
|
+
* Original Code: OpenGL Sample Implementation, Version 1.2.1,
|
|
2441
|
+
* released January 26, 2000. Copyright (c) 1991-2000 Silicon Graphics, Inc.
|
|
2442
|
+
* Copyright 2012, Google Inc. All Rights Reserved.
|
|
2443
|
+
* Copyright 2026, Countertype LLC. All Rights Reserved.
|
|
2444
|
+
* SGI Free Software License B (Version 2.0)
|
|
2445
|
+
* http://oss.sgi.com/projects/FreeB/
|
|
2446
|
+
*/
|
|
2447
|
+
function t(t,i){return t.s===i.s&&t.t===i.t}function i(t,i){return i.s>t.s||t.s===i.s&&i.t>=t.t}function s(t,i){return i.t>t.t||t.t===i.t&&i.s>=t.s}function e(t){return i(t.h.i,t.i)}function n(t){return i(t.i,t.h.i)}function h(t,i){return Math.abs(t.s-i.s)+Math.abs(t.t-i.t)}function r(t,i,s){let e=i.s-t.s,n=s.s-i.s;return e+n>0?n>e?i.t-t.t+e/(e+n)*(t.t-s.t):i.t-s.t+n/(e+n)*(s.t-t.t):0}function l(t,i,s){let e=i.s-t.s,n=s.s-i.s;return e+n>0?(i.t-s.t)*e+(i.t-t.t)*n:0}function o(t,i,s){let e=i.t-t.t,n=s.t-i.t;return e+n>0?n>e?i.s-t.s+e/(e+n)*(t.s-s.s):i.s-s.s+n/(e+n)*(s.s-t.s):0}function u(t,i,s){let e=i.t-t.t,n=s.t-i.t;return e+n>0?(i.s-s.s)*e+(i.s-t.s)*n:0}function c(t,i,s,e){return (t=0>t?0:t)>(s=0>s?0:s)?e+s/(t+s)*(i-e):0===s?(i+e)/2:i+t/(t+s)*(e-i)}function a(t,s,e){const n=t.event,h=s.l,o=e.l;return h.h.i===n?o.h.i===n?i(h.i,o.i)?0>=l(o.h.i,h.i,o.i):l(h.h.i,o.i,h.i)>=0:0>=l(o.h.i,n,o.i):o.h.i===n?l(h.h.i,n,h.i)>=0:r(h.h.i,n,h.i)>=r(o.h.i,n,o.i)}function f(t){return t.o}function d(t){return t.next}function w(t,i){t.u+=i.u,t.h.u+=i.h.u;}function E(t,i){i.l.N=null,t._.delete(i);}function N(t,i,s){t.A.delete(i.l),i.I=0,i.l=s,s.N=i;}function _(t,i){let s,e=i.l.i;do{i=d(i);}while(i.l.i===e);return i.I&&(s=t.A.connect(f(i).l.h,i.l.O),N(t,i,s),i=d(i)),i}function A(t){let i=t.l.h.i;do{t=d(t);}while(t.l.h.i===i);return t}function I(t,i,s){const e=new Z;return e.l=s,t._.insertBefore(i,e),e.I=0,e.k=0,e.T=0,s.N=e,e}function g(t,i){switch(t.M){case Y.ODD:return !!(1&i);case Y.NONZERO:return 0!==i;case Y.POSITIVE:return i>0;case Y.NEGATIVE:return 0>i;case Y.ABS_GEQ_TWO:return i>=2||-2>=i}throw Error("Invalid winding rule")}function O(t,i){const s=i.l,e=s.D;e.p=i.p,e.L=s,E(t,i);}function k(t,i,s){let e,n=null,h=i,r=i.l;for(;h!==s;){if(h.I=0,n=f(h),e=n.l,e.i!=r.i){if(!n.I){O(t,h);break}e=t.A.connect(r.C.h,e.h),N(t,n,e);}r.C!==e&&(t.A.splice(e.h.O,e),t.A.splice(r,e)),O(t,h),r=n.l,h=n;}return r}function y(t,i,s,e,n,h){let r,l,o,u,c=1;o=s;do{I(t,i,o.h),o=o.C;}while(o!==e);for(null===n&&(n=f(i).l.h.C),l=i,u=n;r=f(l),o=r.l.h,o.i===u.i;)o.C!==u&&(t.A.splice(o.h.O,o),t.A.splice(u.h.O,o)),r.G=l.G-o.u,r.p=g(t,r.G),l.T=1,!c&&D(t,l)&&(w(o,u),E(t,l),t.A.delete(u)),c=0,l=r,u=o;l.T=1,h&&C(t,l);}function T(t,i,s,e,n){i.data=null,t.R&&(rt[0]=i.coords[0],rt[1]=i.coords[1],rt[2]=i.coords[2],i.data=t.R(rt,s,e,t.m)),null===i.data&&(n?(t.v(100156),t.U=1):i.data=s[0]);}function b(t,i,s){t.R&&(ht[0]=i.i.data,ht[1]=s.i.data,ht[2]=null,ht[3]=null,nt[0]=.5,nt[1]=.5,nt[2]=0,nt[3]=0,T(t,i.i,ht,nt,0)),t.A.splice(i,s);}function M(t,i,s,e,n){let r=h(i,t),l=h(s,t),o=.5*l/(r+l),u=.5*r/(r+l);void 0!==e&&void 0!==n&&(e[n]=o,e[n+1]=u),t.coords[0]+=o*i.coords[0]+u*s.coords[0],t.coords[1]+=o*i.coords[1]+u*s.coords[1],t.coords[2]+=o*i.coords[2]+u*s.coords[2];}function D(i,s){let e=f(s);const n=s.l,h=e.l;if(h.i.s>n.i.s||n.i.s===h.i.s&&h.i.t>=n.i.t){if(l(h.h.i,n.i,h.i)>0)return 0;t(n.i,h.i)?n.i!==h.i&&(i.S.delete(n.i.B),b(i,h.h.O,n)):(i.A.V(h.h),i.A.splice(n,h.h.O),s.T=e.T=1);}else {if(0>l(n.h.i,h.i,n.i))return 0;d(s).T=s.T=1,i.A.V(n.h),i.A.splice(h.h.O,n);}return 1}function p(t,i){let s=f(i);const e=i.l,n=s.l;let h;if(n.h.i.s>e.h.i.s||e.h.i.s===n.h.i.s&&n.h.i.t>=e.h.i.t){if(0>l(e.h.i,n.h.i,e.i))return 0;d(i).T=i.T=1,h=t.A.V(e),t.A.splice(n.h,h),h.D.p=i.p;}else {if(l(n.h.i,e.h.i,n.i)>0)return 0;i.T=s.T=1,h=t.A.V(n),t.A.splice(e.O,n.h),h.h.D.p=i.p;}return 1}function L(e,n){let h=f(n),a=n.l,w=h.l;const E=a.i,N=w.i;let I,g,O=a.h.i,b=w.h.i;const p=st||(st=new X);let L,C;if(E===N)return 0;if(I=Math.min(E.t,O.t),g=Math.max(N.t,b.t),I>g)return 0;if(i(E,N)){if(l(b,E,N)>0)return 0}else if(0>l(O,N,E))return 0;return ((t,e,n,h,a)=>{let f,d,w;i(t,e)||(w=t,t=e,e=w),i(n,h)||(w=n,n=h,h=w),i(t,n)||(w=t,t=n,n=w,w=e,e=h,h=w),i(n,e)?i(e,h)?(f=r(t,n,e),d=r(n,e,h),0>f+d&&(f=-f,d=-d),a.s=c(f,n.s,d,e.s)):(f=l(t,n,e),d=-l(t,h,e),0>f+d&&(f=-f,d=-d),a.s=c(f,n.s,d,h.s)):a.s=.5*(n.s+e.s),s(t,e)||(w=t,t=e,e=w),s(n,h)||(w=n,n=h,h=w),s(t,n)||(w=t,t=n,n=w,w=e,e=h,h=w),s(n,e)?s(e,h)?(f=o(t,n,e),d=o(n,e,h),0>f+d&&(f=-f,d=-d),a.t=c(f,n.t,d,e.t)):(f=u(t,n,e),d=-u(t,h,e),0>f+d&&(f=-f,d=-d),a.t=c(f,n.t,d,h.t)):a.t=.5*(n.t+e.t);})(O,E,b,N,p),(e.event.s>p.s||p.s===e.event.s&&e.event.t>=p.t)&&(p.s=e.event.s,p.t=e.event.t),L=N.s>E.s||E.s===N.s&&N.t>=E.t?E:N,(p.s>L.s||L.s===p.s&&p.t>=L.t)&&(p.s=L.s,p.t=L.t),t(p,E)||t(p,N)?(D(e,n),0):!t(O,e.event)&&l(O,e.event,p)>=0||!t(b,e.event)&&0>=l(b,e.event,p)?b===e.event?(e.A.V(a.h),e.A.splice(w.h,a),a=f(n=_(e,n)).l,k(e,f(n),h),y(e,n,a.h.O,a,a,1),1):O===e.event?(e.A.V(w.h),e.A.splice(a.O,w.h.O),h=n,C=f(n=A(n)).l.h.C,h.l=w.h.O,w=k(e,h,null),y(e,n,w.C,a.h.C,C,1),1):(0>l(O,e.event,p)||(d(n).T=n.T=1,e.A.V(a.h),a.i.s=e.event.s,a.i.t=e.event.t),l(b,e.event,p)>0||(n.T=h.T=1,e.A.V(w.h),w.i.s=e.event.s,w.i.t=e.event.t),0):(e.A.V(a.h),e.A.V(w.h),e.A.splice(w.h.O,a),a.i.s=p.s,a.i.t=p.t,a.i.B=e.S.P(a.i),((t,i,s,e,n,h)=>{nt[0]=0,nt[1]=0,nt[2]=0,nt[3]=0,ht[0]=s.data,ht[1]=e.data,ht[2]=n.data,ht[3]=h.data,i.coords[0]=i.coords[1]=i.coords[2]=0,M(i,s,e,nt,0),M(i,n,h,nt,2),T(t,i,ht,nt,1);})(e,a.i,E,O,N,b),d(n).T=n.T=h.T=1,0)}function C(t,i){let s,e,n=f(i);for(;;){for(;n.T;)i=n,n=f(n);if(!i.T&&(n=i,null===(i=d(i))||!i.T))return;if(i.T=0,s=i.l,e=n.l,s.h.i!==e.h.i&&p(t,i)&&(n.I?(E(t,n),t.A.delete(e),n=f(i),e=n.l):i.I&&(E(t,i),t.A.delete(s),s=(i=d(n)).l)),s.i!==e.i)if(s.h.i===e.h.i||i.I||n.I||s.h.i!==t.event&&e.h.i!==t.event)D(t,i);else if(L(t,i))return;s.i===e.i&&s.h.i===e.h.i&&(w(e,s),E(t,i),t.A.delete(s),i=d(n));}}function G(s,n){let h,r,o,u,c,a;const w=et||(et=new Z);w.l=n.L.h,h=s._.search(w),r=f(h),r&&(u=h.l,c=r.l,0!==l(u.h.i,n,u.i)?(o=i(c.h.i,u.h.i)?h:r,h.p||o.I?(a=o===h?s.A.connect(n.L.h,u.O):s.A.connect(c.h.C.h,n.L).h,o.I?N(s,o,a):((t,i)=>{i.G=d(i).G+i.l.u,i.p=g(t,i.G);})(s,I(s,h,a)),R(s,n)):y(s,h,n.L,n.L,null,1)):((i,s,n)=>{let h,r,l,o,u;if(h=s.l,t(h.i,n))b(i,h,n.L);else {if(!t(h.h.i,n))return i.A.V(h.h),s.I&&(i.A.delete(h.C),s.I=0),i.A.splice(n.L,h),void R(i,n);u=f(s=A(s)),l=u.l.h,r=o=l.C,u.I&&(E(i,u),i.A.delete(l),l=r.h.O),i.A.splice(n.L,l),e(r)||(r=null),y(i,s,l.C,o,r,1);}})(s,h,n));}function R(s,e){s.event=e;let n=e.L;for(;null===n.N;)if(n=n.C,n===e.L)return void G(s,e);let h=_(s,n.N),r=f(h);const l=r.l;let o=k(s,r,null);o.C===l?((s,e,n)=>{let h,r=n.C,l=f(e),o=e.l,u=l.l,c=0;o.h.i!==u.h.i&&L(s,e),t(o.i,s.event)&&(s.A.splice(r.h.O,o),r=f(e=_(s,e)).l,k(s,f(e),l),c=1),t(u.i,s.event)&&(s.A.splice(n,u.h.O),n=k(s,l,null),c=1),c?y(s,e,n.C,r,r,1):(h=i(u.i,o.i)?u.h.O:o,h=s.A.connect(n.C.h,h),y(s,e,h,h.C,h.C,0),h.h.N.I=1,C(s,e));})(s,h,o):y(s,h,o.C,l,l,1);}function m(t,i,s,e){const n=new Z;let h=t.A.F();h.i.s=s,h.i.t=e,h.h.i.s=i,h.h.i.t=e,t.event=h.h.i,n.l=h,n.G=0,n.p=0,n.I=0,n.k=1,n.T=0,t._.P(n);}function v(t,i){const s=t.Y;let e=s.next,n=e.coords[0],h=e.coords[1],r=e.coords[2],l=n,o=h,u=r,c=e,a=e,f=e,d=e,w=e,E=e;for(e=s.next;e!==s;e=e.next){const t=e.coords[0],i=e.coords[1],s=e.coords[2];n>t&&(n=t,c=e),t>l&&(l=t,d=e),h>i&&(h=i,a=e),i>o&&(o=i,w=e),r>s&&(r=s,f=e),s>u&&(u=s,E=e);}let N=0,_=l-n;const A=o-h;let I,g;if(A>_&&(N=1,_=A),u-r>_&&(N=2),0===N){if(n>=l)return i[0]=0,i[1]=0,void(i[2]=1);I=c,g=d;}else if(1===N){if(h>=o)return i[0]=0,i[1]=0,void(i[2]=1);I=a,g=w;}else {if(r>=u)return i[0]=0,i[1]=0,void(i[2]=1);I=f,g=E;}const O=I.coords[0]-g.coords[0],k=I.coords[1]-g.coords[1],y=I.coords[2]-g.coords[2];let T=0;for(e=s.next;e!==s;e=e.next){const t=e.coords[0]-g.coords[0],s=e.coords[1]-g.coords[1],n=e.coords[2]-g.coords[2],h=k*n-y*s,r=y*t-O*n,l=O*s-k*t,o=h*h+r*r+l*l;o>T&&(T=o,i[0]=h,i[1]=r,i[2]=l);}T>0||(i[0]=i[1]=i[2]=0,Math.abs(k)>Math.abs(O)?i[Math.abs(y)>Math.abs(k)?2:1]=1:i[Math.abs(y)>Math.abs(O)?2:0]=1);}function x(t,i){let s,e,n,h=t.j,r=t.Y,l=0;for(s=h.next;s!==h;s=s.next)if(n=s.L,n.u>0)do{l+=(n.i.s-n.h.i.s)*(n.i.t+n.h.i.t),n=n.O;}while(n!==s.L);if(0>l){for(e=r.next;e!==r;e=e.next)e.t=-e.t;i[0]=-i[0],i[1]=-i[1],i[2]=-i[2];}}function U(t,i){let s=0;for(let e=i.j.next;e!==i.j;e=e.next)e.p&&(s||(t.H(4),s=1),B(e,t));s&&t.q();}function S(t,i,s,e){0>i.s*(s.t-e.t)+s.s*(e.t-i.t)+e.s*(i.t-s.t)?(t.W(i.data),t.W(e.data),t.W(s.data)):(t.W(i.data),t.W(s.data),t.W(e.data));}function B(t,s){let e=0,n=t.L;do{ot[e++]=n.i,n=n.O;}while(n!==t.L);if(3>e)return;if(3===e)return void S(s,ot[0],ot[1],ot[2]);(t=>{if(t>ut.length){const i=2*t;ut=new Int8Array(i),ct=new Int32Array(i),at=new Int32Array(i);}})(e);let h=0,r=0;for(let t=1;e>t;t++)i(ot[t],ot[h])||(h=t),i(ot[t],ot[r])&&(r=t);if(h===r)return;let l=0;ct[l]=h,ut[l]=1,l++;let o=(h+1)%e,u=(h+e-1)%e;for(;o!==r||u!==r;){let t;t=o===r?0:u===r?1:!i(ot[o],ot[u]),t?(ct[l]=o,ut[l]=1,l++,o=(o+1)%e):(ct[l]=u,ut[l]=0,l++,u=(u+e-1)%e);}ct[l]=r,ut[l]=1,l++;let c=0;at[c++]=0,at[c++]=1;for(let t=2;l-1>t;t++)if(ut[t]!==ut[at[c-1]]){for(;c>1;){const i=at[--c];S(s,ot[ct[t]],ot[ct[i]],ot[ct[at[c-1]]]);}--c,at[c++]=t-1,at[c++]=t;}else {let i=at[--c];for(;c>0;){const e=ot[ct[t]],n=ot[ct[i]],h=ot[ct[at[c-1]]],r=e.s*(n.t-h.t)+n.s*(h.t-e.t)+h.s*(e.t-n.t);if(!(1===ut[t]?0>=r:r>=0))break;S(s,e,n,h),i=at[--c];}at[c++]=i,at[c++]=t;}for(;c>1;){const t=at[--c];S(s,ot[ct[l-1]],ot[ct[t]],ot[ct[at[c-1]]]);}}function V(t,i){let s;for(let e=t.Z.next;e!==t.Z;e=s)s=e.next,e.h.D.p!==e.D.p?e.u=e.D.p?i:-i:t.delete(e);}function P(t,i){let s=0,e=-1;for(let n=i.j.o;n!==i.j;n=n.o){if(!n.p)continue;s||(t.H(4),s=1);let i=n.L;do{{const s=i.h&&i.h.D&&i.h.D.p?0:1;e!==s&&(e=s,t.K(!!e));}t.W(i.i.data),i=i.O;}while(i!==n.L)}s&&t.q();}function F(t,i){for(let s=i.j.next;s!==i.j;s=s.next){if(!s.p)continue;t.H(2);let i=s.L;do{t.W(i.i.data),i=i.O;}while(i!==s.L);t.q();}}var Y,j,H,z;(t=>{t[t.ODD=0]="ODD",t[t.NONZERO=1]="NONZERO",t[t.POSITIVE=2]="POSITIVE",t[t.NEGATIVE=3]="NEGATIVE",t[t.ABS_GEQ_TWO=4]="ABS_GEQ_TWO";})(Y||(Y={})),(t=>{t[t.X=0]="POLYGONS",t[t.J=1]="CONNECTED_POLYGONS",t[t.$=2]="BOUNDARY_CONTOURS";})(j||(j={})),(t=>{t[t.BEGIN=100100]="BEGIN",t[t.EDGE_FLAG=100104]="EDGE_FLAG",t[t.VERTEX=100101]="VERTEX",t[t.END=100102]="END",t[t.ERROR=100103]="ERROR",t[t.COMBINE=100105]="COMBINE",t[t.BEGIN_DATA=100106]="BEGIN_DATA",t[t.EDGE_FLAG_DATA=100110]="EDGE_FLAG_DATA",t[t.VERTEX_DATA=100107]="VERTEX_DATA",t[t.END_DATA=100108]="END_DATA",t[t.ERROR_DATA=100109]="ERROR_DATA",t[t.COMBINE_DATA=100111]="COMBINE_DATA",t[t.WINDING_RULE=100140]="WINDING_RULE",t[t.BOUNDARY_ONLY=100141]="BOUNDARY_ONLY",t[t.TOLERANCE=100142]="TOLERANCE";})(H||(H={})),(t=>{t[t.tt=100151]="MISSING_BEGIN_POLYGON",t[t.it=100152]="MISSING_BEGIN_CONTOUR",t[t.st=100153]="MISSING_END_POLYGON",t[t.et=100154]="MISSING_END_CONTOUR",t[t.nt=100155]="COORD_TOO_LARGE",t[t.ht=100156]="NEED_COMBINE_CALLBACK";})(z||(z={}));class Z{next;o;l=null;G=0;p=0;k=0;T=0;I=0}class K{next;i;h;C;O;D;N=null;u=0}class X{next;o;L;coords=[0,0,0];s=0;t=0;B=0;data=null}class Q{next;o;L;p=0}class J{Y;j;Z;rt;vertexCount=0;constructor(){const t=new X,i=new Q,s=new K,e=new K;t.next=t.o=t,i.next=i.o=i,s.next=s,s.h=e,e.next=e,e.h=s,this.Y=t,this.j=i,this.Z=s,this.rt=e;}lt(t){const i=new K,s=new K,e=t.h.next;return s.next=e,e.h.next=i,i.next=t,t.h.next=s,i.h=s,i.C=i,i.O=s,i.u=0,i.N=null,s.h=i,s.C=s,s.O=i,s.u=0,s.N=null,i}ot(t,i){const s=t.C,e=i.C;s.h.O=i,e.h.O=t,t.C=e,i.C=s;}ut(t,i,s){const e=t,n=s.o;e.o=n,n.next=e,e.next=s,s.o=e,e.L=i,++this.vertexCount;let h=i;do{h.i=e,h=h.C;}while(h!==i)}ct(t,i,s){const e=t,n=s.o;e.o=n,n.next=e,e.next=s,s.o=e,e.L=i,e.p=s.p;let h=i;do{h.D=e,h=h.O;}while(h!==i)}ft(t){const i=t.next,s=t.h.next;i.h.next=s,s.h.next=i;}dt(t,i){const s=t.L;let e=s;do{e.i=i,e=e.C;}while(e!==s);const n=t.o,h=t.next;h.o=n,n.next=h,--this.vertexCount;}wt(t,i){const s=t.L;let e=s;do{e.D=i,e=e.O;}while(e!==s);const n=t.o,h=t.next;h.o=n,n.next=h;}F(){const t=new X,i=new X,s=new Q,e=this.lt(this.Z);return this.ut(t,e,this.Y),this.ut(i,e.h,this.Y),this.ct(s,e,this.j),e}splice(t,i){let s=0,e=0;if(t!==i){if(i.i!==t.i&&(e=1,this.dt(i.i,t.i)),i.D!==t.D&&(s=1,this.wt(i.D,t.D)),this.ot(i,t),!e){const s=new X;this.ut(s,i,t.i),t.i.L=t;}if(!s){const s=new Q;this.ct(s,i,t.D),t.D.L=t;}}}delete(t){const i=t.h;let s=0;if(t.D!==t.h.D&&(s=1,this.wt(t.D,t.h.D)),t.C===t)this.dt(t.i,null);else if(t.h.D.L=t.h.O,t.i.L=t.C,this.ot(t,t.h.O),!s){const i=new Q;this.ct(i,t,t.D);}i.C===i?(this.dt(i.i,null),this.wt(i.D,null)):(t.D.L=i.h.O,i.i.L=i.C,this.ot(i,i.h.O)),this.ft(t);}Et(t){const i=this.lt(t),s=i.h;this.ot(i,t.O),i.i=t.h.i;const e=new X;return this.ut(e,s,i.i),i.D=s.D=t.D,i}V(t){const i=this.Et(t).h;return this.ot(t.h,t.h.h.O),this.ot(t.h,i),t.h.i=i.i,i.h.i.L=i.h,i.h.D=t.h.D,i.u=t.u,i.h.u=t.h.u,i}connect(t,i){let s=0;const e=this.lt(t),n=e.h;if(i.D!==t.D&&(s=1,this.wt(i.D,t.D)),this.ot(e,t.O),this.ot(n,i),e.i=t.h.i,n.i=i.i,e.D=n.D=t.D,t.D.L=n,!s){const i=new Q;this.ct(i,e,t.D);}return e}Nt(t){const i=t.L;let s,e,n,h,r;e=i.O;do{s=e,e=s.O,s.D=null,s.h.D||(s.C===s?this.dt(s.i,null):(s.i.L=s.C,this.ot(s,s.h.O)),n=s.h,n.C===n?this.dt(n.i,null):(n.i.L=n.C,this.ot(n,n.h.O)),this.ft(s));}while(s!=i);h=t.o,r=t.next,r.o=h,h.next=r;}_t(t){let i=t.L,s=0;do{s++,i=i.O;}while(i!==t.L);return s}check(){}}class ${max=0;At;It;gt;Ot=0;kt=0;size=0;constructor(t){this.max=t,this.At=new Int32Array(t+1),this.It=Array(t+1).fill(null),this.gt=new Int32Array(t+1),this.Ot=0,this.At[1]=1,this.It[1]=null;}reset(t){if(t+1>this.max)this.max=t,this.At=new Int32Array(t+1),this.It=Array(t+1).fill(null),this.gt=new Int32Array(t+1);else {const t=this.It;for(let i=1;this.size>=i;i++)t[i]=null;}this.size=0,this.kt=0,this.Ot=0,this.At[1]=1,this.It[1]=null;}yt(t){const i=this.At,s=this.It,e=this.gt;let n=i[t];for(;;){let h=t<<1;if(h>this.size)break;let r=h,l=i[h];if(this.size>=h+1){const t=i[h+1],e=s[t],n=s[l];(n.s>e.s||e.s===n.s&&n.t>=e.t)&&(r=h+1,l=t);}const o=s[n],u=s[l];if(u.s>o.s||o.s===u.s&&u.t>=o.t)break;i[t]=l,e[l]=t,t=r;}i[t]=n,e[n]=t;}Tt(t){const i=this.At,s=this.It,e=this.gt;let n=i[t];for(;;){const h=t>>1;if(0===h)break;const r=i[h],l=s[r],o=s[n];if(o.s>l.s||l.s===o.s&&o.t>=l.t)break;i[t]=r,e[r]=t,t=h;}i[t]=n,e[n]=t;}init(){for(let t=this.size>>1;t>=1;--t)this.yt(t);this.Ot=1;}bt(){return 0===this.size}min(){return 0===this.size?null:this.It[this.At[1]]}P(t){let i,s;if(i=++this.size,2*i>this.max){this.max*=2;const t=new Int32Array(this.max+1),i=new Int32Array(this.max+1),s=Array(this.max+1).fill(null);t.set(this.At),i.set(this.gt);for(let t=0;this.It.length>t;t++)s[t]=this.It[t];this.At=t,this.gt=i,this.It=s;}return 0===this.kt?s=i:(s=this.kt,this.kt=this.gt[s]),this.At[i]=s,this.gt[s]=i,this.It[s]=t,this.Ot&&this.Tt(i),s}Mt(){const t=this.At,i=this.It,s=this.gt;let e=t[1],n=i[e];return this.size>0&&(t[1]=t[this.size],s[t[1]]=1,i[e]=null,s[e]=this.kt,this.kt=e,--this.size,this.size>0&&this.yt(1)),n}delete(t){const i=this.At,s=this.It,e=this.gt;let n;if(n=e[t],i[n]=i[this.size],e[i[n]]=n,--this.size,this.size>=n)if(n>1){const t=s[i[n>>1]],e=s[i[n]];e.s>t.s||t.s===e.s&&e.t>=t.t?this.yt(n):this.Tt(n);}else this.yt(n);s[t]=null,e[t]=this.kt,this.kt=t;}}class tt{Dt;keys;order=null;size=0;max=0;Ot=0;Lt;constructor(t){this.max=t,this.size=0,this.Ot=0,this.Lt=128>=t,this.Dt=new $(t),this.Lt||(this.keys=Array(t).fill(null));}reset(t){this.Dt.reset(t),this.Lt=128>=t,this.Lt||this.keys&&this.max>=t||(this.keys=Array(t).fill(null)),t>this.max&&(this.max=t),this.size=0,this.Ot=0,this.order=null;}P(t){if(this.Lt||this.Ot)return this.Dt.P(t);const i=this.size;if(++this.size>=this.max){const t=this.max;this.max*=2;const i=Array(this.max).fill(null);for(let s=0;t>s;s++)i[s]=this.keys[s];this.keys=i;}return this.keys[i]=t,-(i+1)}init(){if(this.Lt)return this.Ot=1,this.Dt.init(),1;this.order=Array(this.size);for(let t=0;this.size>t;t++)this.order[t]=t;const t=this.keys;return this.order.sort((i,s)=>{const e=t[i],n=t[s];return n.s>e.s?1:e.s>n.s||e.t>n.t?-1:1}),this.max=this.size,this.Ot=1,this.Dt.init(),1}Mt(){if(this.Lt||0===this.size)return this.Dt.Mt();const t=this.keys[this.order[this.size-1]];if(!this.Dt.bt()){const s=this.Dt.min();if(s&&i(s,t))return this.Dt.Mt()}do{--this.size;}while(this.size>0&&null===this.keys[this.order[this.size-1]]);return t}min(){if(this.Lt||0===this.size)return this.Dt.min();const t=this.keys[this.order[this.size-1]];if(!this.Dt.bt()){const s=this.Dt.min();if(s&&i(s,t))return s}return t}delete(t){0>t?this.keys[-(t+1)]=null:this.Dt.delete(t);}bt(){return (this.Lt||0===this.size)&&this.Dt.bt()}}class it{head=new Z;frame;constructor(t){this.frame=t,this.head.next=this.head,this.head.o=this.head;}min(){return this.head.next}max(){return this.head.o}P(t){return this.insertBefore(this.head,t)}search(t){let i=this.head;do{i=i.next;}while(null!==i.l&&!a(this.frame,t,i));return i}insertBefore(t,i){do{t=t.o;}while(null!==t.l&&!a(this.frame,t,i));return i.next=t.next,t.next.o=i,i.o=t,t.next=i,i}delete(t){t.next.o=t.o,t.o.next=t.next;}}let st=null,et=null;const nt=[0,0,0,0],ht=[null,null,null,null],rt=[0,0,0];class lt{static Ct(t,i){t.u+=i.u,t.h.u+=i.h.u;}static Gt(t,s){let h,r,o;if(h=s.L,h.O===h||h.O.O===h)throw Error("Monotone region has degenerate topology");for(;i(h.h.i,h.i);h=h.C.h);for(;i(h.i,h.h.i);h=h.O);for(r=h.C.h;h.O!==r;)if(i(h.h.i,r.i)){for(;r.O!==h&&(e(r.O)||0>=l(r.i,r.h.i,r.O.h.i));)o=t.connect(r.O,r),r=o.h;r=r.C.h;}else {for(;r.O!==h&&(n(h.C.h)||l(h.h.i,h.i,h.C.h.i)>=0);)o=t.connect(h,h.C.h),h=o.h;h=h.O;}if(r.O===h)throw Error("Monotone region has insufficient vertices");for(;r.O.O!==h;)o=t.connect(r.O,r),r=o.h;return 1}static tessellateInterior(t){let i;for(let s=t.j.next;s!==t.j;s=i)i=s.next,s.p&<.Gt(t,s);return 1}}let ot=[],ut=new Int8Array(64),ct=new Int32Array(64),at=new Int32Array(64);var ft;(t=>{t[t.Rt=0]="T_DORMANT",t[t.vt=1]="T_IN_POLYGON",t[t.xt=2]="T_IN_CONTOUR";})(ft||(ft={}));class dt{state=ft.Rt;Ut=null;St=0;Bt=0;Vt=1;Pt=0;Ft=0;Yt=0;jt=0;A;Ht=[0,0,0];zt;qt;Wt;Zt;M=Y.ODD;Kt=Y.ODD;_;S;event;Xt;Qt;Jt;$t;ti;ii;R;si;m=null;U=0;gluTessCallback(t,i){const s=i||null;switch(t){case 100100:case 100106:this.Xt=s;break;case 100104:case 100110:this.$t=s,this.flagBoundary=1;break;case 100101:case 100107:this.Qt=s;break;case 100102:case 100108:this.Jt=s;break;case 100103:this.ti=s;break;case 100109:this.ii=s;break;case 100105:case 100111:this.R=s;break;case 100112:this.si=s;break;default:throw Error("GLU_INVALID_ENUM")}}gluTessProperty(t,i){switch(t){case 100140:{const t=i,s=100130>t?t:t-100130;if(0>s||s>4)throw Error("GLU_INVALID_VALUE");this.Kt=t,this.M=s;break}case 100141:this.ei=!!i;break;case 100142:break;default:throw Error("GLU_INVALID_ENUM")}}gluGetTessProperty(t){switch(t){case 100140:return this.Kt;case 100141:return this.ei;case 100142:return 0;default:throw Error("GLU_INVALID_ENUM")}}gluTessNormal(t,i,s){this.Ht[0]=t,this.Ht[1]=i,this.Ht[2]=s,0===s||t||i||(this.Vt=s>0?1:-1);}H(t){this.Xt&&this.Xt(t,this.m);}W(t){this.Qt&&this.Qt(t,this.m);}q(){this.Jt&&this.Jt(this.m);}K(t){this.$t&&this.$t(t,this.m);}v(t){this.ii?this.ii(t,this.m):this.ti&&this.ti(t);}ni(t){if(this.state!==t)for(;this.state!==t;)t>this.state?this.state===ft.Rt?(this.v(100151),this.gluTessBeginPolygon()):this.state===ft.vt&&(this.v(100152),this.gluTessBeginContour()):this.state===ft.xt?(this.v(100154),this.gluTessEndContour()):this.state===ft.vt&&(this.v(100153),this.gluTessEndPolygon());}ei=0;flagBoundary=0;hi(){const t=this.A,i=t.Y,s=this.Ht[0],e=this.Ht[1],n=this.Ht[2];let h,r;if(this.zt||(this.zt=[0,0,0]),this.qt||(this.qt=[0,0,0]),this.Wt||(this.Wt=[0,0]),this.Zt||(this.Zt=[0,0]),h=this.zt,r=this.qt,this.Bt){h[0]=1,h[1]=0,h[2]=0;const t=n>0?1:-1;return r[0]=0,r[1]=t,r[2]=0,this.Wt[0]=this.Pt,this.Wt[1]=this.Yt,this.Zt[0]=this.Ft,void(this.Zt[1]=this.jt)}if(!this.St&&!s&&!e){let s;h[0]=1,h[1]=0,h[2]=0;let e=0;if(n)s=n>0?1:-1;else {const i=[0,0,0];v(t,i),s=i[2]>0?1:-1,e=1;}r[0]=0,r[1]=s,r[2]=0;let l=i.next,o=l.coords[0],u=l.coords[1]*s;l.s=o,l.t=u;let c=o,a=o,f=u,d=u;for(l=l.next;l!==i;l=l.next)o=l.coords[0],u=l.coords[1]*s,l.s=o,l.t=u,c>o?c=o:o>a&&(a=o),f>u?f=u:u>d&&(d=u);return this.Wt[0]=c,this.Zt[0]=a,void(e?(x(t,this.qt),r[1]!==s?(this.Wt[1]=-d,this.Zt[1]=-f):(this.Wt[1]=f,this.Zt[1]=d)):(this.Wt[1]=f,this.Zt[1]=d))}let l=0;const o=[s,e,n];s||e||n||(v(t,o),l=1);const u=(t=>{let i=0;return Math.abs(t[1])>Math.abs(t[0])&&(i=1),Math.abs(t[2])>Math.abs(t[i])&&(i=2),i})(o);h[u]=0,h[(u+1)%3]=1,h[(u+2)%3]=0,r[u]=0,r[(u+1)%3]=0,r[(u+2)%3]=o[u]>0?1:-1;let c=i.next;c.s=c.coords[0]*h[0]+c.coords[1]*h[1]+c.coords[2]*h[2],c.t=c.coords[0]*r[0]+c.coords[1]*r[1]+c.coords[2]*r[2];let a=c.s,f=c.s,d=c.t,w=c.t;for(c=c.next;c!==i;c=c.next){const t=c.coords[0]*h[0]+c.coords[1]*h[1]+c.coords[2]*h[2],i=c.coords[0]*r[0]+c.coords[1]*r[1]+c.coords[2]*r[2];c.s=t,c.t=i,a>t?a=t:t>f&&(f=t),d>i?d=i:i>w&&(w=i);}l&&x(t,this.qt),l&&r[(u+2)%3]!==(o[u]>0?1:-1)?(this.Wt[0]=a,this.Zt[0]=f,this.Wt[1]=-w,this.Zt[1]=-d):(this.Wt[0]=a,this.Zt[0]=f,this.Wt[1]=d,this.Zt[1]=w);}gluTessBeginPolygon(t){this.ni(ft.Rt),this.state=ft.vt,this.U=0,this.A=new J,this.St=0,this.Bt=0!==this.Ht[2]&&!this.Ht[0]&&!this.Ht[1],this.Pt=1/0,this.Ft=-1/0,this.Yt=1/0,this.jt=-1/0,this.m=t;}gluTessBeginContour(){this.ni(ft.vt),this.state=ft.xt,this.Ut=null;}gluTessVertex(t,i){this.ni(ft.xt);let s=t[0],e=t[1],n=t.length>2?t[2]:0,h=0;-1e150>s?(s=-1e150,h=1):s>1e150&&(s=1e150,h=1),-1e150>e?(e=-1e150,h=1):e>1e150&&(e=1e150,h=1),-1e150>n?(n=-1e150,h=1):n>1e150&&(n=1e150,h=1),h&&this.v(100155);let r=this.Ut;if(null===r?(r=this.A.F(),this.A.splice(r,r.h)):(this.A.V(r),r=r.O),r.i.data=i||null,r.i.coords[0]=s,r.i.coords[1]=e,0!==n?(r.i.coords[2]=n,this.St=1,this.Bt=0):r.i.coords[2]=0,this.Bt){r.i.s=s;const t=e*this.Vt;r.i.t=t,this.Pt>s&&(this.Pt=s),s>this.Ft&&(this.Ft=s),this.Yt>t&&(this.Yt=t),t>this.jt&&(this.jt=t);}r.u=1,r.h.u=-1,this.Ut=r;}gluTessEndContour(){this.ni(ft.xt),this.state=ft.vt;}gluTessEndPolygon(){this.ni(ft.vt),this.state=ft.Rt,this.compute(this.M,void 0,0);const t=this.A;this.U||(this.ei?(V(t,1),F(this,t)):this.flagBoundary?(lt.tessellateInterior(t),P(this,t)):U(this,t)),this.si&&this.si(t),this.A=null,this.Ut=null,this.event=null,this.m=null,this._=null;}gluDeleteTess(){this.ni(ft.Rt);}compute(i=Y.ODD,s,e=0){this.state!==ft.Rt&&this.state===ft.vt&&(this.state=ft.Rt),this.A||(this.A=new J),s&&(this.Ht[0]=s[0],this.Ht[1]=s[1],this.Ht[2]=s[2]),this.M=i,this.hi(),function(i,s=1){let e,n;if((i=>{let s,e,n,h=i.A.Z;for(s=h.next;s!==h;s=e)e=s.next,n=s.O,t(s.i,s.h.i)&&s.O.O!==s&&(b(i,n,s),i.A.delete(s),s=n,n=s.O),n.O===s&&(n!==s&&(n!==e&&n!==e.h||(e=e.next),i.A.delete(n)),s!==e&&s!==e.h||(e=e.next),i.A.delete(s));})(i),!(t=>{let i,s,e,n=t.A.vertexCount+8;for(t.S?(t.S.reset(n),i=t.S):i=t.S=new tt(n),e=t.A.Y,s=e.next;s!==e;s=s.next)s.B=i.P(s);return s!==e?0:(i.init(),1)})(i))return 0;for((t=>{t._=new it(t);let i=t.Zt[0]-t.Wt[0],s=t.Zt[1]-t.Wt[1],e=t.Wt[0]-i,n=t.Zt[0]+i,h=t.Zt[1]+s;m(t,e,n,t.Wt[1]-s),m(t,e,n,h);})(i);null!==(e=i.S.Mt());){for(;n=i.S.min(),null!==n&&t(n,e);)n=i.S.Mt(),b(i,e.L,n.L);R(i,e);}i.event=i._.min().l.i,(t=>{let i;for(;null!==(i=t._.min()).l;)E(t,i);})(i),((t,i)=>{let s,e,n;for(s=i.j.next;s!==i.j;s=e)e=s.next,n=s.L,n.O.O===n&&(w(n.C,n),t.A.delete(n));})(i,i.A),s&&i.A.check();}(this,e);}renderBoundary(){this.A&&(V(this.A,1),F(this,this.A));}renderTriangles(t=0){this.A&&(t?(lt.tessellateInterior(this.A),P(this,this.A)):U(this,this.A));}}
|
|
2533
2448
|
|
|
2534
2449
|
class Tessellator {
|
|
2535
2450
|
process(paths, removeOverlaps = true, isCFF = false, needsExtrusionContours = true) {
|
|
@@ -2744,49 +2659,49 @@ class Tessellator {
|
|
|
2744
2659
|
return reversed;
|
|
2745
2660
|
}
|
|
2746
2661
|
performTessellation(contours, mode) {
|
|
2747
|
-
const tess = new
|
|
2748
|
-
tess.gluTessProperty(
|
|
2662
|
+
const tess = new dt();
|
|
2663
|
+
tess.gluTessProperty(H.WINDING_RULE, Y.NONZERO);
|
|
2749
2664
|
const vertices = [];
|
|
2750
2665
|
const indices = [];
|
|
2751
2666
|
const contourIndices = [];
|
|
2752
2667
|
let currentContour = [];
|
|
2753
2668
|
if (mode === 'boundary') {
|
|
2754
|
-
tess.gluTessProperty(
|
|
2669
|
+
tess.gluTessProperty(H.BOUNDARY_ONLY, 1);
|
|
2755
2670
|
}
|
|
2756
2671
|
if (mode === 'triangles') {
|
|
2757
|
-
tess.gluTessCallback(
|
|
2672
|
+
tess.gluTessCallback(H.VERTEX_DATA, (data) => {
|
|
2758
2673
|
indices.push(data);
|
|
2759
2674
|
});
|
|
2760
2675
|
}
|
|
2761
2676
|
else {
|
|
2762
|
-
tess.gluTessCallback(
|
|
2677
|
+
tess.gluTessCallback(H.BEGIN, () => {
|
|
2763
2678
|
currentContour = [];
|
|
2764
2679
|
});
|
|
2765
|
-
tess.gluTessCallback(
|
|
2680
|
+
tess.gluTessCallback(H.VERTEX_DATA, (data) => {
|
|
2766
2681
|
currentContour.push(data);
|
|
2767
2682
|
});
|
|
2768
|
-
tess.gluTessCallback(
|
|
2683
|
+
tess.gluTessCallback(H.END, () => {
|
|
2769
2684
|
if (currentContour.length > 0) {
|
|
2770
2685
|
contourIndices.push(currentContour);
|
|
2771
2686
|
}
|
|
2772
2687
|
});
|
|
2773
2688
|
}
|
|
2774
|
-
tess.gluTessCallback(
|
|
2689
|
+
tess.gluTessCallback(H.COMBINE, (coords) => {
|
|
2775
2690
|
const idx = vertices.length / 2;
|
|
2776
2691
|
vertices.push(coords[0], coords[1]);
|
|
2777
2692
|
return idx;
|
|
2778
2693
|
});
|
|
2779
|
-
tess.gluTessCallback(
|
|
2694
|
+
tess.gluTessCallback(H.ERROR, (errno) => {
|
|
2780
2695
|
logger.warn(`libtess error: ${errno}`);
|
|
2781
2696
|
});
|
|
2782
2697
|
tess.gluTessNormal(0, 0, 1);
|
|
2783
|
-
tess.gluTessBeginPolygon(
|
|
2698
|
+
tess.gluTessBeginPolygon();
|
|
2784
2699
|
for (const contour of contours) {
|
|
2785
2700
|
tess.gluTessBeginContour();
|
|
2786
2701
|
for (let i = 0; i < contour.length; i += 2) {
|
|
2787
2702
|
const idx = vertices.length / 2;
|
|
2788
2703
|
vertices.push(contour[i], contour[i + 1]);
|
|
2789
|
-
tess.gluTessVertex([contour[i], contour[i + 1]
|
|
2704
|
+
tess.gluTessVertex([contour[i], contour[i + 1]], idx);
|
|
2790
2705
|
}
|
|
2791
2706
|
tess.gluTessEndContour();
|
|
2792
2707
|
}
|
|
@@ -3212,117 +3127,33 @@ class BoundaryClusterer {
|
|
|
3212
3127
|
}
|
|
3213
3128
|
}
|
|
3214
3129
|
|
|
3215
|
-
class MinHeap {
|
|
3216
|
-
constructor(compare) {
|
|
3217
|
-
this.heap = [];
|
|
3218
|
-
this.itemIndex = new Map();
|
|
3219
|
-
this.compare = compare;
|
|
3220
|
-
}
|
|
3221
|
-
insert(value) {
|
|
3222
|
-
const existingIndex = this.itemIndex.get(value);
|
|
3223
|
-
if (existingIndex !== undefined) {
|
|
3224
|
-
// Already exists - update in place
|
|
3225
|
-
this.siftUp(existingIndex);
|
|
3226
|
-
this.siftDown(existingIndex);
|
|
3227
|
-
return;
|
|
3228
|
-
}
|
|
3229
|
-
const index = this.heap.length;
|
|
3230
|
-
this.heap.push(value);
|
|
3231
|
-
this.itemIndex.set(value, index);
|
|
3232
|
-
this.siftUp(index);
|
|
3233
|
-
}
|
|
3234
|
-
extractMin() {
|
|
3235
|
-
const heapLength = this.heap.length;
|
|
3236
|
-
if (!heapLength)
|
|
3237
|
-
return undefined;
|
|
3238
|
-
if (heapLength === 1) {
|
|
3239
|
-
const min = this.heap.pop();
|
|
3240
|
-
this.itemIndex.clear();
|
|
3241
|
-
return min;
|
|
3242
|
-
}
|
|
3243
|
-
const min = this.heap[0];
|
|
3244
|
-
const last = this.heap.pop();
|
|
3245
|
-
this.heap[0] = last;
|
|
3246
|
-
this.itemIndex.delete(min);
|
|
3247
|
-
this.itemIndex.set(last, 0);
|
|
3248
|
-
this.siftDown(0);
|
|
3249
|
-
return min;
|
|
3250
|
-
}
|
|
3251
|
-
update(value) {
|
|
3252
|
-
const index = this.itemIndex.get(value);
|
|
3253
|
-
if (index === undefined) {
|
|
3254
|
-
this.insert(value);
|
|
3255
|
-
return;
|
|
3256
|
-
}
|
|
3257
|
-
// Percolate in both directions - one will terminate immediately
|
|
3258
|
-
this.siftUp(index);
|
|
3259
|
-
this.siftDown(index);
|
|
3260
|
-
}
|
|
3261
|
-
isEmpty() {
|
|
3262
|
-
return !this.heap.length;
|
|
3263
|
-
}
|
|
3264
|
-
swap(i, j) {
|
|
3265
|
-
const itemI = this.heap[i];
|
|
3266
|
-
const itemJ = this.heap[j];
|
|
3267
|
-
this.heap[i] = itemJ;
|
|
3268
|
-
this.heap[j] = itemI;
|
|
3269
|
-
this.itemIndex.set(itemI, j);
|
|
3270
|
-
this.itemIndex.set(itemJ, i);
|
|
3271
|
-
}
|
|
3272
|
-
siftUp(i) {
|
|
3273
|
-
const item = this.heap[i];
|
|
3274
|
-
while (i > 0) {
|
|
3275
|
-
const parentIndex = (i - 1) >> 1; // Bit shift for fast division by 2
|
|
3276
|
-
const parent = this.heap[parentIndex];
|
|
3277
|
-
// Early exit if heap property satisfied
|
|
3278
|
-
if (this.compare(item, parent) >= 0)
|
|
3279
|
-
break;
|
|
3280
|
-
// Move parent down
|
|
3281
|
-
this.heap[i] = parent;
|
|
3282
|
-
this.itemIndex.set(parent, i);
|
|
3283
|
-
i = parentIndex;
|
|
3284
|
-
}
|
|
3285
|
-
this.heap[i] = item;
|
|
3286
|
-
this.itemIndex.set(item, i);
|
|
3287
|
-
}
|
|
3288
|
-
siftDown(i) {
|
|
3289
|
-
const item = this.heap[i];
|
|
3290
|
-
const heapLength = this.heap.length;
|
|
3291
|
-
const halfLength = heapLength >> 1; // Only nodes in first half can have children
|
|
3292
|
-
while (i < halfLength) {
|
|
3293
|
-
const leftIndex = (i << 1) + 1; // Bit shift for fast multiplication by 2
|
|
3294
|
-
const rightIndex = leftIndex + 1;
|
|
3295
|
-
let smallestIndex = i;
|
|
3296
|
-
let smallest = item;
|
|
3297
|
-
const left = this.heap[leftIndex];
|
|
3298
|
-
if (this.compare(left, smallest) < 0) {
|
|
3299
|
-
smallestIndex = leftIndex;
|
|
3300
|
-
smallest = left;
|
|
3301
|
-
}
|
|
3302
|
-
if (rightIndex < heapLength) {
|
|
3303
|
-
const right = this.heap[rightIndex];
|
|
3304
|
-
if (this.compare(right, smallest) < 0) {
|
|
3305
|
-
smallestIndex = rightIndex;
|
|
3306
|
-
smallest = right;
|
|
3307
|
-
}
|
|
3308
|
-
}
|
|
3309
|
-
// Early exit if heap property satisfied
|
|
3310
|
-
if (smallestIndex === i)
|
|
3311
|
-
break;
|
|
3312
|
-
// Move smallest child up
|
|
3313
|
-
this.heap[i] = smallest;
|
|
3314
|
-
this.itemIndex.set(smallest, i);
|
|
3315
|
-
i = smallestIndex;
|
|
3316
|
-
}
|
|
3317
|
-
this.heap[i] = item;
|
|
3318
|
-
this.itemIndex.set(item, i);
|
|
3319
|
-
}
|
|
3320
|
-
}
|
|
3321
|
-
|
|
3322
3130
|
const DEFAULT_OPTIMIZATION_CONFIG = {
|
|
3323
3131
|
enabled: true,
|
|
3324
|
-
areaThreshold: 1.0
|
|
3132
|
+
areaThreshold: 1.0
|
|
3325
3133
|
};
|
|
3134
|
+
// Scratch buffers reused across calls. Grown on demand, never shrunk
|
|
3135
|
+
let _cap = 1024;
|
|
3136
|
+
let _px = new Float64Array(_cap);
|
|
3137
|
+
let _py = new Float64Array(_cap);
|
|
3138
|
+
let _area = new Float64Array(_cap);
|
|
3139
|
+
let _prev = new Int32Array(_cap);
|
|
3140
|
+
let _next = new Int32Array(_cap);
|
|
3141
|
+
let _heap = new Int32Array(_cap);
|
|
3142
|
+
let _hpos = new Int32Array(_cap);
|
|
3143
|
+
function ensureCap(n) {
|
|
3144
|
+
if (n <= _cap)
|
|
3145
|
+
return;
|
|
3146
|
+
_cap = 1;
|
|
3147
|
+
while (_cap < n)
|
|
3148
|
+
_cap <<= 1;
|
|
3149
|
+
_px = new Float64Array(_cap);
|
|
3150
|
+
_py = new Float64Array(_cap);
|
|
3151
|
+
_area = new Float64Array(_cap);
|
|
3152
|
+
_prev = new Int32Array(_cap);
|
|
3153
|
+
_next = new Int32Array(_cap);
|
|
3154
|
+
_heap = new Int32Array(_cap);
|
|
3155
|
+
_hpos = new Int32Array(_cap);
|
|
3156
|
+
}
|
|
3326
3157
|
class PathOptimizer {
|
|
3327
3158
|
constructor(config) {
|
|
3328
3159
|
this.stats = {
|
|
@@ -3335,85 +3166,26 @@ class PathOptimizer {
|
|
|
3335
3166
|
this.config = config;
|
|
3336
3167
|
}
|
|
3337
3168
|
optimizePath(path) {
|
|
3338
|
-
if (path.points.length <= 2) {
|
|
3339
|
-
return path;
|
|
3340
|
-
}
|
|
3341
|
-
if (!this.config.enabled) {
|
|
3342
|
-
return path;
|
|
3343
|
-
}
|
|
3344
|
-
this.stats.originalPointCount += path.points.length;
|
|
3345
|
-
// Most paths are already immutable after collection; avoid copying large point arrays
|
|
3346
|
-
// The optimizers below never mutate the input `points` array
|
|
3347
3169
|
const points = path.points;
|
|
3348
|
-
|
|
3170
|
+
const n = points.length;
|
|
3171
|
+
if (n < 5 || !this.config.enabled) {
|
|
3172
|
+
if (this.config.enabled)
|
|
3173
|
+
this.stats.originalPointCount += n;
|
|
3349
3174
|
return path;
|
|
3350
3175
|
}
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
if (optimized.length < 3) {
|
|
3176
|
+
this.stats.originalPointCount += n;
|
|
3177
|
+
const removed = simplifyVW(points, n, this.config.areaThreshold);
|
|
3178
|
+
if (removed === 0)
|
|
3355
3179
|
return path;
|
|
3180
|
+
this.stats.pointsRemovedByVisvalingam += removed;
|
|
3181
|
+
const result = new Array(n - removed);
|
|
3182
|
+
let idx = 0;
|
|
3183
|
+
let out = 0;
|
|
3184
|
+
while (idx >= 0) {
|
|
3185
|
+
result[out++] = points[idx];
|
|
3186
|
+
idx = _next[idx];
|
|
3356
3187
|
}
|
|
3357
|
-
return {
|
|
3358
|
-
...path,
|
|
3359
|
-
points: optimized
|
|
3360
|
-
};
|
|
3361
|
-
}
|
|
3362
|
-
// Visvalingam-Whyatt algorithm
|
|
3363
|
-
simplifyPathVW(points, areaThreshold) {
|
|
3364
|
-
if (points.length <= 3)
|
|
3365
|
-
return points;
|
|
3366
|
-
const originalLength = points.length;
|
|
3367
|
-
const minPoints = 3;
|
|
3368
|
-
const pointList = points.map((p, i) => ({
|
|
3369
|
-
index: i,
|
|
3370
|
-
area: Infinity,
|
|
3371
|
-
prev: null,
|
|
3372
|
-
next: null
|
|
3373
|
-
}));
|
|
3374
|
-
for (let i = 0; i < pointList.length; i++) {
|
|
3375
|
-
pointList[i].prev = pointList[i - 1] || null;
|
|
3376
|
-
pointList[i].next = pointList[i + 1] || null;
|
|
3377
|
-
}
|
|
3378
|
-
const heap = new MinHeap((a, b) => a.area - b.area);
|
|
3379
|
-
for (let i = 1; i < pointList.length - 1; i++) {
|
|
3380
|
-
const p = pointList[i];
|
|
3381
|
-
p.area = this.calculateTriangleArea(points[p.prev.index], points[p.index], points[p.next.index]);
|
|
3382
|
-
heap.insert(p);
|
|
3383
|
-
}
|
|
3384
|
-
let remainingPoints = originalLength;
|
|
3385
|
-
while (!heap.isEmpty() && remainingPoints > minPoints) {
|
|
3386
|
-
const p = heap.extractMin();
|
|
3387
|
-
if (!p || p.area > areaThreshold) {
|
|
3388
|
-
break;
|
|
3389
|
-
}
|
|
3390
|
-
if (p.prev)
|
|
3391
|
-
p.prev.next = p.next;
|
|
3392
|
-
if (p.next)
|
|
3393
|
-
p.next.prev = p.prev;
|
|
3394
|
-
remainingPoints--;
|
|
3395
|
-
if (p.prev && p.prev.prev) {
|
|
3396
|
-
p.prev.area = this.calculateTriangleArea(points[p.prev.prev.index], points[p.prev.index], points[p.next.index]);
|
|
3397
|
-
heap.update(p.prev);
|
|
3398
|
-
}
|
|
3399
|
-
if (p.next && p.next.next) {
|
|
3400
|
-
p.next.area = this.calculateTriangleArea(points[p.prev.index], points[p.next.index], points[p.next.next.index]);
|
|
3401
|
-
heap.update(p.next);
|
|
3402
|
-
}
|
|
3403
|
-
}
|
|
3404
|
-
const simplifiedPoints = [];
|
|
3405
|
-
let current = pointList[0];
|
|
3406
|
-
while (current) {
|
|
3407
|
-
simplifiedPoints.push(points[current.index]);
|
|
3408
|
-
current = current.next;
|
|
3409
|
-
}
|
|
3410
|
-
const pointsRemoved = originalLength - simplifiedPoints.length;
|
|
3411
|
-
this.stats.pointsRemovedByVisvalingam += pointsRemoved;
|
|
3412
|
-
return simplifiedPoints;
|
|
3413
|
-
}
|
|
3414
|
-
// Shoelace formula
|
|
3415
|
-
calculateTriangleArea(p1, p2, p3) {
|
|
3416
|
-
return Math.abs((p1.x * (p2.y - p3.y) + p2.x * (p3.y - p1.y) + p3.x * (p1.y - p2.y)) / 2);
|
|
3188
|
+
return { ...path, points: result };
|
|
3417
3189
|
}
|
|
3418
3190
|
getStats() {
|
|
3419
3191
|
return { ...this.stats };
|
|
@@ -3425,6 +3197,158 @@ class PathOptimizer {
|
|
|
3425
3197
|
};
|
|
3426
3198
|
}
|
|
3427
3199
|
}
|
|
3200
|
+
// Visvalingam-Whyatt simplification. Iteratively removes the point
|
|
3201
|
+
// whose removal causes the smallest change in contour area (measured
|
|
3202
|
+
// as the triangle formed with its two neighbors) until all remaining
|
|
3203
|
+
// triangles exceed areaThreshold
|
|
3204
|
+
//
|
|
3205
|
+
// Uses parallel typed arrays for the linked list and a binary min-heap
|
|
3206
|
+
// with an index-based position map for O(log n) extract and update.
|
|
3207
|
+
// Coordinates are flattened into Float64Array to keep area computation
|
|
3208
|
+
// on contiguous memory. Areas are stored as 2x actual (skipping the
|
|
3209
|
+
// shoelace /2) and the threshold is doubled to match
|
|
3210
|
+
//
|
|
3211
|
+
// Returns the number of points removed. The caller reads _next[] to
|
|
3212
|
+
// walk the surviving linked list
|
|
3213
|
+
function simplifyVW(points, n, areaThreshold) {
|
|
3214
|
+
if (n <= 3)
|
|
3215
|
+
return 0;
|
|
3216
|
+
ensureCap(n);
|
|
3217
|
+
const px = _px;
|
|
3218
|
+
const py = _py;
|
|
3219
|
+
const area = _area;
|
|
3220
|
+
const prev = _prev;
|
|
3221
|
+
const next = _next;
|
|
3222
|
+
const heap = _heap;
|
|
3223
|
+
const hpos = _hpos;
|
|
3224
|
+
// Flatten coordinates and initialize doubly-linked list
|
|
3225
|
+
for (let i = 0; i < n; i++) {
|
|
3226
|
+
const p = points[i];
|
|
3227
|
+
px[i] = p.x;
|
|
3228
|
+
py[i] = p.y;
|
|
3229
|
+
prev[i] = i - 1;
|
|
3230
|
+
next[i] = i + 1;
|
|
3231
|
+
}
|
|
3232
|
+
next[n - 1] = -1;
|
|
3233
|
+
// Compute triangle areas for interior points and seed the heap
|
|
3234
|
+
const heapLen0 = n - 2;
|
|
3235
|
+
area[0] = Infinity;
|
|
3236
|
+
area[n - 1] = Infinity;
|
|
3237
|
+
for (let i = 1; i < n - 1; i++) {
|
|
3238
|
+
area[i] = area2x(px, py, i - 1, i, i + 1);
|
|
3239
|
+
heap[i - 1] = i;
|
|
3240
|
+
hpos[i] = i - 1;
|
|
3241
|
+
}
|
|
3242
|
+
hpos[0] = -1;
|
|
3243
|
+
hpos[n - 1] = -1;
|
|
3244
|
+
// Bottom-up heapify, O(n)
|
|
3245
|
+
let heapLen = heapLen0;
|
|
3246
|
+
for (let i = (heapLen >> 1) - 1; i >= 0; i--) {
|
|
3247
|
+
siftDown(heap, hpos, area, i, heapLen);
|
|
3248
|
+
}
|
|
3249
|
+
const threshold2x = areaThreshold * 2;
|
|
3250
|
+
const maxRemovals = n - 3;
|
|
3251
|
+
let removed = 0;
|
|
3252
|
+
while (heapLen > 0 && removed < maxRemovals) {
|
|
3253
|
+
const minIdx = heap[0];
|
|
3254
|
+
if (area[minIdx] > threshold2x)
|
|
3255
|
+
break;
|
|
3256
|
+
// Extract min
|
|
3257
|
+
heapLen--;
|
|
3258
|
+
if (heapLen > 0) {
|
|
3259
|
+
const last = heap[heapLen];
|
|
3260
|
+
heap[0] = last;
|
|
3261
|
+
hpos[last] = 0;
|
|
3262
|
+
siftDown(heap, hpos, area, 0, heapLen);
|
|
3263
|
+
}
|
|
3264
|
+
hpos[minIdx] = -1;
|
|
3265
|
+
// Unlink
|
|
3266
|
+
const pi = prev[minIdx];
|
|
3267
|
+
const ni = next[minIdx];
|
|
3268
|
+
if (pi >= 0)
|
|
3269
|
+
next[pi] = ni;
|
|
3270
|
+
if (ni >= 0)
|
|
3271
|
+
prev[ni] = pi;
|
|
3272
|
+
removed++;
|
|
3273
|
+
// Recompute prev neighbor's area and update heap position
|
|
3274
|
+
if (pi >= 0 && prev[pi] >= 0) {
|
|
3275
|
+
const oldArea = area[pi];
|
|
3276
|
+
const newArea = area2x(px, py, prev[pi], pi, ni);
|
|
3277
|
+
area[pi] = newArea;
|
|
3278
|
+
const pos = hpos[pi];
|
|
3279
|
+
if (pos >= 0) {
|
|
3280
|
+
if (newArea < oldArea)
|
|
3281
|
+
siftUp(heap, hpos, area, pos);
|
|
3282
|
+
else if (newArea > oldArea)
|
|
3283
|
+
siftDown(heap, hpos, area, pos, heapLen);
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
// Same for next neighbor
|
|
3287
|
+
if (ni >= 0 && next[ni] >= 0) {
|
|
3288
|
+
const oldArea = area[ni];
|
|
3289
|
+
const newArea = area2x(px, py, pi, ni, next[ni]);
|
|
3290
|
+
area[ni] = newArea;
|
|
3291
|
+
const pos = hpos[ni];
|
|
3292
|
+
if (pos >= 0) {
|
|
3293
|
+
if (newArea < oldArea)
|
|
3294
|
+
siftUp(heap, hpos, area, pos);
|
|
3295
|
+
else if (newArea > oldArea)
|
|
3296
|
+
siftDown(heap, hpos, area, pos, heapLen);
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3299
|
+
}
|
|
3300
|
+
return removed;
|
|
3301
|
+
}
|
|
3302
|
+
function siftUp(heap, hpos, area, i) {
|
|
3303
|
+
const idx = heap[i];
|
|
3304
|
+
const val = area[idx];
|
|
3305
|
+
while (i > 0) {
|
|
3306
|
+
const parent = (i - 1) >> 1;
|
|
3307
|
+
const pidx = heap[parent];
|
|
3308
|
+
if (area[pidx] <= val)
|
|
3309
|
+
break;
|
|
3310
|
+
heap[i] = pidx;
|
|
3311
|
+
hpos[pidx] = i;
|
|
3312
|
+
i = parent;
|
|
3313
|
+
}
|
|
3314
|
+
heap[i] = idx;
|
|
3315
|
+
hpos[idx] = i;
|
|
3316
|
+
}
|
|
3317
|
+
function siftDown(heap, hpos, area, i, len) {
|
|
3318
|
+
const idx = heap[i];
|
|
3319
|
+
const val = area[idx];
|
|
3320
|
+
const half = len >> 1;
|
|
3321
|
+
while (i < half) {
|
|
3322
|
+
let child = (i << 1) + 1;
|
|
3323
|
+
let childIdx = heap[child];
|
|
3324
|
+
let childVal = area[childIdx];
|
|
3325
|
+
const right = child + 1;
|
|
3326
|
+
if (right < len) {
|
|
3327
|
+
const rIdx = heap[right];
|
|
3328
|
+
const rVal = area[rIdx];
|
|
3329
|
+
if (rVal < childVal) {
|
|
3330
|
+
child = right;
|
|
3331
|
+
childIdx = rIdx;
|
|
3332
|
+
childVal = rVal;
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
if (childVal >= val)
|
|
3336
|
+
break;
|
|
3337
|
+
heap[i] = childIdx;
|
|
3338
|
+
hpos[childIdx] = i;
|
|
3339
|
+
i = child;
|
|
3340
|
+
}
|
|
3341
|
+
heap[i] = idx;
|
|
3342
|
+
hpos[idx] = i;
|
|
3343
|
+
}
|
|
3344
|
+
// Doubled triangle area via the shoelace formula. Skipping the /2
|
|
3345
|
+
// means callers compare against a doubled threshold instead
|
|
3346
|
+
function area2x(px, py, i1, i2, i3) {
|
|
3347
|
+
const v = px[i1] * (py[i2] - py[i3]) +
|
|
3348
|
+
px[i2] * (py[i3] - py[i1]) +
|
|
3349
|
+
px[i3] * (py[i1] - py[i2]);
|
|
3350
|
+
return v < 0 ? -v : v;
|
|
3351
|
+
}
|
|
3428
3352
|
|
|
3429
3353
|
/**
|
|
3430
3354
|
* @license
|
|
@@ -3465,23 +3389,314 @@ class PathOptimizer {
|
|
|
3465
3389
|
*/
|
|
3466
3390
|
const DEFAULT_CURVE_FIDELITY = {
|
|
3467
3391
|
distanceTolerance: 0.5,
|
|
3468
|
-
angleTolerance: 0.2
|
|
3392
|
+
angleTolerance: 0.2,
|
|
3393
|
+
cuspLimit: 0,
|
|
3394
|
+
collinearityEpsilon: 1e-6,
|
|
3395
|
+
recursionLimit: 16
|
|
3469
3396
|
};
|
|
3470
|
-
const COLLINEARITY_EPSILON =
|
|
3471
|
-
|
|
3397
|
+
const COLLINEARITY_EPSILON = DEFAULT_CURVE_FIDELITY.collinearityEpsilon;
|
|
3398
|
+
// Module-level state for the recursive subdivision functions,
|
|
3399
|
+
// set from instance config before each polygonize call
|
|
3400
|
+
// Output array, reset before each polygonize call
|
|
3401
|
+
let _out;
|
|
3402
|
+
// Cached tolerance state
|
|
3403
|
+
let _distTolSq = 0;
|
|
3404
|
+
let _colEps = 0;
|
|
3405
|
+
let _maxLvl = 0;
|
|
3406
|
+
let _angleTol = 0;
|
|
3407
|
+
let _tanAngSq = 0;
|
|
3408
|
+
let _cuspLim = 0;
|
|
3409
|
+
let _tanCuspSq = 0;
|
|
3410
|
+
// Collinearity checks in the recursive core prevent near-duplicate points
|
|
3411
|
+
function emit(x, y) {
|
|
3412
|
+
_out.push(new Vec2(x, y));
|
|
3413
|
+
}
|
|
3414
|
+
// Quadratic recursive subdivision (AGG curve3_div)
|
|
3415
|
+
function quadRec(x1, y1, x2, y2, x3, y3, level) {
|
|
3416
|
+
if (level > _maxLvl)
|
|
3417
|
+
return;
|
|
3418
|
+
const x12 = (x1 + x2) * 0.5;
|
|
3419
|
+
const y12 = (y1 + y2) * 0.5;
|
|
3420
|
+
const x23 = (x2 + x3) * 0.5;
|
|
3421
|
+
const y23 = (y2 + y3) * 0.5;
|
|
3422
|
+
const x123 = (x12 + x23) * 0.5;
|
|
3423
|
+
const y123 = (y12 + y23) * 0.5;
|
|
3424
|
+
const dx = x3 - x1;
|
|
3425
|
+
const dy = y3 - y1;
|
|
3426
|
+
let d = Math.abs((x2 - x3) * dy - (y2 - y3) * dx);
|
|
3427
|
+
if (d > _colEps) {
|
|
3428
|
+
if (d * d <= _distTolSq * (dx * dx + dy * dy)) {
|
|
3429
|
+
if (_angleTol > 0) {
|
|
3430
|
+
const v1x = x2 - x1;
|
|
3431
|
+
const v1y = y2 - y1;
|
|
3432
|
+
const v2x = x3 - x2;
|
|
3433
|
+
const v2y = y3 - y2;
|
|
3434
|
+
const cross = v1x * v2y - v1y * v2x;
|
|
3435
|
+
const dot = v1x * v2x + v1y * v2y;
|
|
3436
|
+
if (dot > 0 && cross * cross < _tanAngSq * dot * dot) {
|
|
3437
|
+
emit(x123, y123);
|
|
3438
|
+
return;
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
else {
|
|
3442
|
+
emit(x123, y123);
|
|
3443
|
+
return;
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
else {
|
|
3448
|
+
let da = dx * dx + dy * dy;
|
|
3449
|
+
if (da === 0) {
|
|
3450
|
+
d = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
|
|
3451
|
+
}
|
|
3452
|
+
else {
|
|
3453
|
+
d = ((x2 - x1) * dx + (y2 - y1) * dy) / da;
|
|
3454
|
+
if (d > 0 && d < 1)
|
|
3455
|
+
return;
|
|
3456
|
+
if (d <= 0)
|
|
3457
|
+
d = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
|
|
3458
|
+
else if (d >= 1)
|
|
3459
|
+
d = (x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3);
|
|
3460
|
+
else {
|
|
3461
|
+
const px = x1 + d * dx;
|
|
3462
|
+
const py = y1 + d * dy;
|
|
3463
|
+
d = (x2 - px) * (x2 - px) + (y2 - py) * (y2 - py);
|
|
3464
|
+
}
|
|
3465
|
+
}
|
|
3466
|
+
if (d < _distTolSq) {
|
|
3467
|
+
emit(x2, y2);
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
const nl = level + 1;
|
|
3472
|
+
quadRec(x1, y1, x12, y12, x123, y123, nl);
|
|
3473
|
+
quadRec(x123, y123, x23, y23, x3, y3, nl);
|
|
3474
|
+
}
|
|
3475
|
+
// Cubic recursive subdivision (AGG curve4_div)
|
|
3476
|
+
// cubicBegin handles level 0, which always subdivides
|
|
3477
|
+
function cubicBegin(x1, y1, x2, y2, x3, y3, x4, y4) {
|
|
3478
|
+
const x12 = (x1 + x2) * 0.5;
|
|
3479
|
+
const y12 = (y1 + y2) * 0.5;
|
|
3480
|
+
const x23 = (x2 + x3) * 0.5;
|
|
3481
|
+
const y23 = (y2 + y3) * 0.5;
|
|
3482
|
+
const x34 = (x3 + x4) * 0.5;
|
|
3483
|
+
const y34 = (y3 + y4) * 0.5;
|
|
3484
|
+
const x123 = (x12 + x23) * 0.5;
|
|
3485
|
+
const y123 = (y12 + y23) * 0.5;
|
|
3486
|
+
const x234 = (x23 + x34) * 0.5;
|
|
3487
|
+
const y234 = (y23 + y34) * 0.5;
|
|
3488
|
+
const x1234 = (x123 + x234) * 0.5;
|
|
3489
|
+
const y1234 = (y123 + y234) * 0.5;
|
|
3490
|
+
cubicRec(x1, y1, x12, y12, x123, y123, x1234, y1234, 1);
|
|
3491
|
+
cubicRec(x1234, y1234, x234, y234, x34, y34, x4, y4, 1);
|
|
3492
|
+
}
|
|
3493
|
+
function cubicRec(x1, y1, x2, y2, x3, y3, x4, y4, level) {
|
|
3494
|
+
if (level > _maxLvl)
|
|
3495
|
+
return;
|
|
3496
|
+
const x12 = (x1 + x2) * 0.5;
|
|
3497
|
+
const y12 = (y1 + y2) * 0.5;
|
|
3498
|
+
const x23 = (x2 + x3) * 0.5;
|
|
3499
|
+
const y23 = (y2 + y3) * 0.5;
|
|
3500
|
+
const x34 = (x3 + x4) * 0.5;
|
|
3501
|
+
const y34 = (y3 + y4) * 0.5;
|
|
3502
|
+
const x123 = (x12 + x23) * 0.5;
|
|
3503
|
+
const y123 = (y12 + y23) * 0.5;
|
|
3504
|
+
const x234 = (x23 + x34) * 0.5;
|
|
3505
|
+
const y234 = (y23 + y34) * 0.5;
|
|
3506
|
+
const x1234 = (x123 + x234) * 0.5;
|
|
3507
|
+
const y1234 = (y123 + y234) * 0.5;
|
|
3508
|
+
const dx = x4 - x1;
|
|
3509
|
+
const dy = y4 - y1;
|
|
3510
|
+
let d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx);
|
|
3511
|
+
let d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx);
|
|
3512
|
+
const sc = (d2 > _colEps ? 2 : 0) + (d3 > _colEps ? 1 : 0);
|
|
3513
|
+
switch (sc) {
|
|
3514
|
+
case 0: {
|
|
3515
|
+
let k = dx * dx + dy * dy;
|
|
3516
|
+
if (k === 0) {
|
|
3517
|
+
d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
|
|
3518
|
+
d3 = (x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1);
|
|
3519
|
+
}
|
|
3520
|
+
else {
|
|
3521
|
+
k = 1 / k;
|
|
3522
|
+
let t1 = x2 - x1;
|
|
3523
|
+
let t2 = y2 - y1;
|
|
3524
|
+
d2 = k * (t1 * dx + t2 * dy);
|
|
3525
|
+
t1 = x3 - x1;
|
|
3526
|
+
t2 = y3 - y1;
|
|
3527
|
+
d3 = k * (t1 * dx + t2 * dy);
|
|
3528
|
+
if (d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1)
|
|
3529
|
+
return;
|
|
3530
|
+
if (d2 <= 0)
|
|
3531
|
+
d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
|
|
3532
|
+
else if (d2 >= 1)
|
|
3533
|
+
d2 = (x2 - x4) * (x2 - x4) + (y2 - y4) * (y2 - y4);
|
|
3534
|
+
else {
|
|
3535
|
+
const px = x1 + d2 * dx, py = y1 + d2 * dy;
|
|
3536
|
+
d2 = (x2 - px) * (x2 - px) + (y2 - py) * (y2 - py);
|
|
3537
|
+
}
|
|
3538
|
+
if (d3 <= 0)
|
|
3539
|
+
d3 = (x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1);
|
|
3540
|
+
else if (d3 >= 1)
|
|
3541
|
+
d3 = (x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4);
|
|
3542
|
+
else {
|
|
3543
|
+
const px = x1 + d3 * dx, py = y1 + d3 * dy;
|
|
3544
|
+
d3 = (x3 - px) * (x3 - px) + (y3 - py) * (y3 - py);
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
if (d2 > d3) {
|
|
3548
|
+
if (d2 < _distTolSq) {
|
|
3549
|
+
emit(x2, y2);
|
|
3550
|
+
return;
|
|
3551
|
+
}
|
|
3552
|
+
}
|
|
3553
|
+
else {
|
|
3554
|
+
if (d3 < _distTolSq) {
|
|
3555
|
+
emit(x3, y3);
|
|
3556
|
+
return;
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3559
|
+
break;
|
|
3560
|
+
}
|
|
3561
|
+
case 1:
|
|
3562
|
+
if (d3 * d3 <= _distTolSq * (dx * dx + dy * dy)) {
|
|
3563
|
+
if (_angleTol > 0) {
|
|
3564
|
+
const v1x = x3 - x2, v1y = y3 - y2;
|
|
3565
|
+
const v2x = x4 - x3, v2y = y4 - y3;
|
|
3566
|
+
const cross = v1x * v2y - v1y * v2x;
|
|
3567
|
+
const dot = v1x * v2x + v1y * v2y;
|
|
3568
|
+
if (dot > 0 && cross * cross < _tanAngSq * dot * dot) {
|
|
3569
|
+
emit(x2, y2);
|
|
3570
|
+
emit(x3, y3);
|
|
3571
|
+
return;
|
|
3572
|
+
}
|
|
3573
|
+
if (_cuspLim > 0 &&
|
|
3574
|
+
(dot <= 0 || cross * cross > _tanCuspSq * dot * dot)) {
|
|
3575
|
+
emit(x3, y3);
|
|
3576
|
+
return;
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
else {
|
|
3580
|
+
emit(x23, y23);
|
|
3581
|
+
return;
|
|
3582
|
+
}
|
|
3583
|
+
}
|
|
3584
|
+
break;
|
|
3585
|
+
case 2:
|
|
3586
|
+
if (d2 * d2 <= _distTolSq * (dx * dx + dy * dy)) {
|
|
3587
|
+
if (_angleTol > 0) {
|
|
3588
|
+
const v1x = x2 - x1, v1y = y2 - y1;
|
|
3589
|
+
const v2x = x3 - x2, v2y = y3 - y2;
|
|
3590
|
+
const cross = v1x * v2y - v1y * v2x;
|
|
3591
|
+
const dot = v1x * v2x + v1y * v2y;
|
|
3592
|
+
if (dot > 0 && cross * cross < _tanAngSq * dot * dot) {
|
|
3593
|
+
emit(x2, y2);
|
|
3594
|
+
emit(x3, y3);
|
|
3595
|
+
return;
|
|
3596
|
+
}
|
|
3597
|
+
if (_cuspLim > 0 &&
|
|
3598
|
+
(dot <= 0 || cross * cross > _tanCuspSq * dot * dot)) {
|
|
3599
|
+
emit(x2, y2);
|
|
3600
|
+
return;
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
else {
|
|
3604
|
+
emit(x23, y23);
|
|
3605
|
+
return;
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
break;
|
|
3609
|
+
case 3: {
|
|
3610
|
+
if ((d2 + d3) * (d2 + d3) <= _distTolSq * (dx * dx + dy * dy)) {
|
|
3611
|
+
if (_angleTol > 0) {
|
|
3612
|
+
const a1x = x2 - x1, a1y = y2 - y1;
|
|
3613
|
+
const a2x = x3 - x2, a2y = y3 - y2;
|
|
3614
|
+
const c1 = a1x * a2y - a1y * a2x;
|
|
3615
|
+
const dot1 = a1x * a2x + a1y * a2y;
|
|
3616
|
+
const b2x = x4 - x3, b2y = y4 - y3;
|
|
3617
|
+
const c2 = a2x * b2y - a2y * b2x;
|
|
3618
|
+
const dot2 = a2x * b2x + a2y * b2y;
|
|
3619
|
+
// Sum of unsigned angles via tangent addition identity
|
|
3620
|
+
if (dot1 > 0 && dot2 > 0) {
|
|
3621
|
+
const ac1 = c1 < 0 ? -c1 : c1;
|
|
3622
|
+
const ac2 = c2 < 0 ? -c2 : c2;
|
|
3623
|
+
const cc = ac1 * dot2 + ac2 * dot1;
|
|
3624
|
+
const cd = dot1 * dot2 - ac1 * ac2;
|
|
3625
|
+
if (cd > 0 && cc * cc < _tanAngSq * cd * cd) {
|
|
3626
|
+
emit(x23, y23);
|
|
3627
|
+
return;
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
if (_cuspLim > 0) {
|
|
3631
|
+
if (dot1 <= 0 || c1 * c1 > _tanCuspSq * dot1 * dot1) {
|
|
3632
|
+
emit(x2, y2);
|
|
3633
|
+
return;
|
|
3634
|
+
}
|
|
3635
|
+
if (dot2 <= 0 || c2 * c2 > _tanCuspSq * dot2 * dot2) {
|
|
3636
|
+
emit(x3, y3);
|
|
3637
|
+
return;
|
|
3638
|
+
}
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
else {
|
|
3642
|
+
emit(x23, y23);
|
|
3643
|
+
return;
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
break;
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
const nl = level + 1;
|
|
3650
|
+
cubicRec(x1, y1, x12, y12, x123, y123, x1234, y1234, nl);
|
|
3651
|
+
cubicRec(x1234, y1234, x234, y234, x34, y34, x4, y4, nl);
|
|
3652
|
+
}
|
|
3472
3653
|
class Polygonizer {
|
|
3473
3654
|
constructor(curveFidelityConfig) {
|
|
3474
3655
|
this.curveSteps = null;
|
|
3656
|
+
// Precomputed tolerances
|
|
3657
|
+
this._distTolSq = 0;
|
|
3658
|
+
this._angleTol = 0;
|
|
3659
|
+
this._tanAngSq = 0;
|
|
3660
|
+
this._cuspLim = 0;
|
|
3661
|
+
this._tanCuspSq = 0;
|
|
3662
|
+
this._colEps = 0;
|
|
3663
|
+
this._maxLvl = 0;
|
|
3475
3664
|
this.curveFidelityConfig = {
|
|
3476
3665
|
...DEFAULT_CURVE_FIDELITY,
|
|
3477
3666
|
...curveFidelityConfig
|
|
3478
3667
|
};
|
|
3668
|
+
this.precompute();
|
|
3479
3669
|
}
|
|
3480
3670
|
setCurveFidelityConfig(curveFidelityConfig) {
|
|
3481
3671
|
this.curveFidelityConfig = {
|
|
3482
3672
|
...DEFAULT_CURVE_FIDELITY,
|
|
3483
3673
|
...curveFidelityConfig
|
|
3484
3674
|
};
|
|
3675
|
+
this.precompute();
|
|
3676
|
+
}
|
|
3677
|
+
precompute() {
|
|
3678
|
+
const c = this.curveFidelityConfig;
|
|
3679
|
+
const dt = c.distanceTolerance ?? DEFAULT_CURVE_FIDELITY.distanceTolerance;
|
|
3680
|
+
this._distTolSq = dt * dt;
|
|
3681
|
+
this._angleTol = c.angleTolerance ?? DEFAULT_CURVE_FIDELITY.angleTolerance;
|
|
3682
|
+
this._tanAngSq = this._angleTol > 0
|
|
3683
|
+
? Math.tan(this._angleTol) ** 2 : 0;
|
|
3684
|
+
this._cuspLim = c.cuspLimit ?? 0;
|
|
3685
|
+
this._tanCuspSq = this._cuspLim > 0
|
|
3686
|
+
? Math.tan(this._cuspLim) ** 2 : 0;
|
|
3687
|
+
this._colEps = c.collinearityEpsilon ?? DEFAULT_CURVE_FIDELITY.collinearityEpsilon;
|
|
3688
|
+
this._maxLvl = c.recursionLimit ?? DEFAULT_CURVE_FIDELITY.recursionLimit;
|
|
3689
|
+
}
|
|
3690
|
+
// Set module-level state from instance tolerances
|
|
3691
|
+
activate() {
|
|
3692
|
+
_distTolSq = this._distTolSq;
|
|
3693
|
+
_angleTol = this._angleTol;
|
|
3694
|
+
_tanAngSq = this._tanAngSq;
|
|
3695
|
+
_cuspLim = this._cuspLim;
|
|
3696
|
+
_tanCuspSq = this._tanCuspSq;
|
|
3697
|
+
_colEps = this._colEps;
|
|
3698
|
+
_maxLvl = this._maxLvl;
|
|
3699
|
+
_out = [];
|
|
3485
3700
|
}
|
|
3486
3701
|
// Fixed-step subdivision; overrides adaptive curveFidelity when set
|
|
3487
3702
|
setCurveSteps(curveSteps) {
|
|
@@ -3500,280 +3715,49 @@ class Polygonizer {
|
|
|
3500
3715
|
if (this.curveSteps !== null) {
|
|
3501
3716
|
return this.polygonizeQuadraticFixedSteps(start, control, end, this.curveSteps);
|
|
3502
3717
|
}
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
return
|
|
3718
|
+
this.activate();
|
|
3719
|
+
quadRec(start.x, start.y, control.x, control.y, end.x, end.y, 0);
|
|
3720
|
+
emit(end.x, end.y);
|
|
3721
|
+
return _out;
|
|
3507
3722
|
}
|
|
3508
3723
|
polygonizeCubic(start, control1, control2, end) {
|
|
3509
3724
|
if (this.curveSteps !== null) {
|
|
3510
3725
|
return this.polygonizeCubicFixedSteps(start, control1, control2, end, this.curveSteps);
|
|
3511
3726
|
}
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
return
|
|
3516
|
-
}
|
|
3517
|
-
lerp(a, b, t) {
|
|
3518
|
-
return a + (b - a) * t;
|
|
3727
|
+
this.activate();
|
|
3728
|
+
cubicBegin(start.x, start.y, control1.x, control1.y, control2.x, control2.y, end.x, end.y);
|
|
3729
|
+
emit(end.x, end.y);
|
|
3730
|
+
return _out;
|
|
3519
3731
|
}
|
|
3520
3732
|
polygonizeQuadraticFixedSteps(start, control, end, steps) {
|
|
3521
|
-
|
|
3522
|
-
// Emit intermediate points; caller already has start
|
|
3733
|
+
this.activate();
|
|
3523
3734
|
for (let i = 1; i <= steps; i++) {
|
|
3524
3735
|
const t = i / steps;
|
|
3525
|
-
const x12 =
|
|
3526
|
-
const y12 =
|
|
3527
|
-
const x23 =
|
|
3528
|
-
const y23 =
|
|
3529
|
-
|
|
3530
|
-
const y = this.lerp(y12, y23, t);
|
|
3531
|
-
this.addPoint(x, y, points);
|
|
3736
|
+
const x12 = start.x + (control.x - start.x) * t;
|
|
3737
|
+
const y12 = start.y + (control.y - start.y) * t;
|
|
3738
|
+
const x23 = control.x + (end.x - control.x) * t;
|
|
3739
|
+
const y23 = control.y + (end.y - control.y) * t;
|
|
3740
|
+
emit(x12 + (x23 - x12) * t, y12 + (y23 - y12) * t);
|
|
3532
3741
|
}
|
|
3533
|
-
return
|
|
3742
|
+
return _out;
|
|
3534
3743
|
}
|
|
3535
3744
|
polygonizeCubicFixedSteps(start, control1, control2, end, steps) {
|
|
3536
|
-
|
|
3537
|
-
// Emit intermediate points; caller already has start
|
|
3745
|
+
this.activate();
|
|
3538
3746
|
for (let i = 1; i <= steps; i++) {
|
|
3539
3747
|
const t = i / steps;
|
|
3540
|
-
|
|
3541
|
-
const
|
|
3542
|
-
const
|
|
3543
|
-
const
|
|
3544
|
-
const
|
|
3545
|
-
const
|
|
3546
|
-
const
|
|
3547
|
-
const
|
|
3548
|
-
const
|
|
3549
|
-
const
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
this.addPoint(x, y, points);
|
|
3554
|
-
}
|
|
3555
|
-
return points;
|
|
3556
|
-
}
|
|
3557
|
-
recursiveQuadratic(x1, y1, x2, y2, x3, y3, points, level = 0) {
|
|
3558
|
-
if (level > RECURSION_LIMIT)
|
|
3559
|
-
return;
|
|
3560
|
-
// De Casteljau subdivision: split the curve at t=0.5
|
|
3561
|
-
// First calculate midpoints of the two line segments
|
|
3562
|
-
const x12 = (x1 + x2) / 2;
|
|
3563
|
-
const y12 = (y1 + y2) / 2;
|
|
3564
|
-
const x23 = (x2 + x3) / 2;
|
|
3565
|
-
const y23 = (y2 + y3) / 2;
|
|
3566
|
-
// Then find the midpoint of those midpoints - this is the curve point at t=0.5
|
|
3567
|
-
const x123 = (x12 + x23) / 2;
|
|
3568
|
-
const y123 = (y12 + y23) / 2;
|
|
3569
|
-
const dx = x3 - x1;
|
|
3570
|
-
const dy = y3 - y1;
|
|
3571
|
-
const d = Math.abs((x2 - x3) * dy - (y2 - y3) * dx);
|
|
3572
|
-
const baseTolerance = this.curveFidelityConfig.distanceTolerance ??
|
|
3573
|
-
DEFAULT_CURVE_FIDELITY.distanceTolerance;
|
|
3574
|
-
const distanceTolerance = baseTolerance * baseTolerance;
|
|
3575
|
-
if (d > COLLINEARITY_EPSILON) {
|
|
3576
|
-
// Regular case
|
|
3577
|
-
// Recursion terminates when the curve is flat enough (deviation from straight line is within tolerance)
|
|
3578
|
-
if (d * d <= distanceTolerance * (dx * dx + dy * dy)) {
|
|
3579
|
-
// Angle check
|
|
3580
|
-
const angleTolerance = this.curveFidelityConfig.angleTolerance ??
|
|
3581
|
-
DEFAULT_CURVE_FIDELITY.angleTolerance;
|
|
3582
|
-
if (angleTolerance > 0) {
|
|
3583
|
-
// Angle between segments (p1->p2) and (p2->p3)
|
|
3584
|
-
// atan2(cross, dot) avoids computing 2 separate atan2() values
|
|
3585
|
-
const v1x = x2 - x1;
|
|
3586
|
-
const v1y = y2 - y1;
|
|
3587
|
-
const v2x = x3 - x2;
|
|
3588
|
-
const v2y = y3 - y2;
|
|
3589
|
-
const da = Math.abs(Math.atan2(v1x * v2y - v1y * v2x, v1x * v2x + v1y * v2y));
|
|
3590
|
-
if (da < angleTolerance) {
|
|
3591
|
-
this.addPoint(x2, y2, points);
|
|
3592
|
-
return;
|
|
3593
|
-
}
|
|
3594
|
-
}
|
|
3595
|
-
else {
|
|
3596
|
-
this.addPoint(x2, y2, points);
|
|
3597
|
-
return;
|
|
3598
|
-
}
|
|
3599
|
-
}
|
|
3600
|
-
}
|
|
3601
|
-
else {
|
|
3602
|
-
// Collinear case
|
|
3603
|
-
const da = dx * dx + dy * dy;
|
|
3604
|
-
if (da === 0) {
|
|
3605
|
-
const d2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
|
|
3606
|
-
if (d2 <= distanceTolerance) {
|
|
3607
|
-
this.addPoint(x2, y2, points);
|
|
3608
|
-
return;
|
|
3609
|
-
}
|
|
3610
|
-
}
|
|
3611
|
-
else {
|
|
3612
|
-
const d2 = ((x2 - x1) * dx + (y2 - y1) * dy) / da;
|
|
3613
|
-
if (d2 > 0 && d2 < 1 && d * d <= distanceTolerance * da) {
|
|
3614
|
-
this.addPoint(x2, y2, points);
|
|
3615
|
-
return;
|
|
3616
|
-
}
|
|
3617
|
-
}
|
|
3618
|
-
}
|
|
3619
|
-
// Continue subdividing
|
|
3620
|
-
this.recursiveQuadratic(x1, y1, x12, y12, x123, y123, points, level + 1);
|
|
3621
|
-
this.recursiveQuadratic(x123, y123, x23, y23, x3, y3, points, level + 1);
|
|
3622
|
-
}
|
|
3623
|
-
recursiveCubic(x1, y1, x2, y2, x3, y3, x4, y4, points, level = 0) {
|
|
3624
|
-
if (level > RECURSION_LIMIT)
|
|
3625
|
-
return;
|
|
3626
|
-
// De Casteljau subdivision for cubic curves
|
|
3627
|
-
const x12 = (x1 + x2) / 2;
|
|
3628
|
-
const y12 = (y1 + y2) / 2;
|
|
3629
|
-
const x23 = (x2 + x3) / 2;
|
|
3630
|
-
const y23 = (y2 + y3) / 2;
|
|
3631
|
-
const x34 = (x3 + x4) / 2;
|
|
3632
|
-
const y34 = (y3 + y4) / 2;
|
|
3633
|
-
const x123 = (x12 + x23) / 2;
|
|
3634
|
-
const y123 = (y12 + y23) / 2;
|
|
3635
|
-
const x234 = (x23 + x34) / 2;
|
|
3636
|
-
const y234 = (y23 + y34) / 2;
|
|
3637
|
-
const x1234 = (x123 + x234) / 2;
|
|
3638
|
-
const y1234 = (y123 + y234) / 2;
|
|
3639
|
-
const dx = x4 - x1;
|
|
3640
|
-
const dy = y4 - y1;
|
|
3641
|
-
const d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx);
|
|
3642
|
-
const d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx);
|
|
3643
|
-
const baseTolerance = this.curveFidelityConfig.distanceTolerance ??
|
|
3644
|
-
DEFAULT_CURVE_FIDELITY.distanceTolerance;
|
|
3645
|
-
const distanceTolerance = baseTolerance * baseTolerance;
|
|
3646
|
-
let switchCondition = 0;
|
|
3647
|
-
if (d2 > COLLINEARITY_EPSILON)
|
|
3648
|
-
switchCondition |= 1;
|
|
3649
|
-
if (d3 > COLLINEARITY_EPSILON)
|
|
3650
|
-
switchCondition |= 2;
|
|
3651
|
-
switch (switchCondition) {
|
|
3652
|
-
case 0:
|
|
3653
|
-
// All collinear OR p1==p4
|
|
3654
|
-
const k = dx * dx + dy * dy;
|
|
3655
|
-
if (k === 0) {
|
|
3656
|
-
const d2_sq = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
|
|
3657
|
-
const d3_sq = (x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1);
|
|
3658
|
-
if (d2_sq <= distanceTolerance && d3_sq <= distanceTolerance) {
|
|
3659
|
-
this.addPoint(x2, y2, points);
|
|
3660
|
-
this.addPoint(x3, y3, points);
|
|
3661
|
-
return;
|
|
3662
|
-
}
|
|
3663
|
-
}
|
|
3664
|
-
else {
|
|
3665
|
-
const da1 = ((x2 - x1) * dx + (y2 - y1) * dy) / k;
|
|
3666
|
-
const da2 = ((x3 - x1) * dx + (y3 - y1) * dy) / k;
|
|
3667
|
-
if (da1 > 0 &&
|
|
3668
|
-
da1 < 1 &&
|
|
3669
|
-
da2 > 0 &&
|
|
3670
|
-
da2 < 1 &&
|
|
3671
|
-
(d2 + d3) * (d2 + d3) <= distanceTolerance * k) {
|
|
3672
|
-
this.addPoint(x2, y2, points);
|
|
3673
|
-
this.addPoint(x3, y3, points);
|
|
3674
|
-
return;
|
|
3675
|
-
}
|
|
3676
|
-
}
|
|
3677
|
-
break;
|
|
3678
|
-
case 1:
|
|
3679
|
-
// p1,p2,p4 are collinear, p3 is not
|
|
3680
|
-
if (d3 * d3 <= distanceTolerance * (dx * dx + dy * dy)) {
|
|
3681
|
-
const angleTolerance = this.curveFidelityConfig.angleTolerance ??
|
|
3682
|
-
DEFAULT_CURVE_FIDELITY.angleTolerance;
|
|
3683
|
-
if (angleTolerance > 0) {
|
|
3684
|
-
// Angle between segments (p2->p3) and (p3->p4)
|
|
3685
|
-
const v1x = x3 - x2;
|
|
3686
|
-
const v1y = y3 - y2;
|
|
3687
|
-
const v2x = x4 - x3;
|
|
3688
|
-
const v2y = y4 - y3;
|
|
3689
|
-
const da1 = Math.abs(Math.atan2(v1x * v2y - v1y * v2x, v1x * v2x + v1y * v2y));
|
|
3690
|
-
if (da1 < angleTolerance) {
|
|
3691
|
-
this.addPoint(x2, y2, points);
|
|
3692
|
-
this.addPoint(x3, y3, points);
|
|
3693
|
-
return;
|
|
3694
|
-
}
|
|
3695
|
-
}
|
|
3696
|
-
else {
|
|
3697
|
-
this.addPoint(x2, y2, points);
|
|
3698
|
-
this.addPoint(x3, y3, points);
|
|
3699
|
-
return;
|
|
3700
|
-
}
|
|
3701
|
-
}
|
|
3702
|
-
break;
|
|
3703
|
-
case 2:
|
|
3704
|
-
// p1,p3,p4 are collinear, p2 is not
|
|
3705
|
-
if (d2 * d2 <= distanceTolerance * (dx * dx + dy * dy)) {
|
|
3706
|
-
const angleTolerance = this.curveFidelityConfig.angleTolerance ??
|
|
3707
|
-
DEFAULT_CURVE_FIDELITY.angleTolerance;
|
|
3708
|
-
if (angleTolerance > 0) {
|
|
3709
|
-
// Angle between segments (p1->p2) and (p2->p3)
|
|
3710
|
-
const v1x = x2 - x1;
|
|
3711
|
-
const v1y = y2 - y1;
|
|
3712
|
-
const v2x = x3 - x2;
|
|
3713
|
-
const v2y = y3 - y2;
|
|
3714
|
-
const da1 = Math.abs(Math.atan2(v1x * v2y - v1y * v2x, v1x * v2x + v1y * v2y));
|
|
3715
|
-
if (da1 < angleTolerance) {
|
|
3716
|
-
this.addPoint(x2, y2, points);
|
|
3717
|
-
this.addPoint(x3, y3, points);
|
|
3718
|
-
return;
|
|
3719
|
-
}
|
|
3720
|
-
}
|
|
3721
|
-
else {
|
|
3722
|
-
this.addPoint(x2, y2, points);
|
|
3723
|
-
this.addPoint(x3, y3, points);
|
|
3724
|
-
return;
|
|
3725
|
-
}
|
|
3726
|
-
}
|
|
3727
|
-
break;
|
|
3728
|
-
case 3:
|
|
3729
|
-
// Regular case
|
|
3730
|
-
if ((d2 + d3) * (d2 + d3) <= distanceTolerance * (dx * dx + dy * dy)) {
|
|
3731
|
-
const angleTolerance = this.curveFidelityConfig.angleTolerance ??
|
|
3732
|
-
DEFAULT_CURVE_FIDELITY.angleTolerance;
|
|
3733
|
-
if (angleTolerance > 0) {
|
|
3734
|
-
// da1: angle between (p1->p2) and (p2->p3)
|
|
3735
|
-
const a1x = x2 - x1;
|
|
3736
|
-
const a1y = y2 - y1;
|
|
3737
|
-
const a2x = x3 - x2;
|
|
3738
|
-
const a2y = y3 - y2;
|
|
3739
|
-
const da1 = Math.abs(Math.atan2(a1x * a2y - a1y * a2x, a1x * a2x + a1y * a2y));
|
|
3740
|
-
// da2: angle between (p2->p3) and (p3->p4)
|
|
3741
|
-
const b1x = a2x;
|
|
3742
|
-
const b1y = a2y;
|
|
3743
|
-
const b2x = x4 - x3;
|
|
3744
|
-
const b2y = y4 - y3;
|
|
3745
|
-
const da2 = Math.abs(Math.atan2(b1x * b2y - b1y * b2x, b1x * b2x + b1y * b2y));
|
|
3746
|
-
if (da1 + da2 < angleTolerance) {
|
|
3747
|
-
this.addPoint(x2, y2, points);
|
|
3748
|
-
this.addPoint(x3, y3, points);
|
|
3749
|
-
return;
|
|
3750
|
-
}
|
|
3751
|
-
}
|
|
3752
|
-
else {
|
|
3753
|
-
this.addPoint(x2, y2, points);
|
|
3754
|
-
this.addPoint(x3, y3, points);
|
|
3755
|
-
return;
|
|
3756
|
-
}
|
|
3757
|
-
}
|
|
3758
|
-
break;
|
|
3759
|
-
}
|
|
3760
|
-
// Continue subdividing
|
|
3761
|
-
this.recursiveCubic(x1, y1, x12, y12, x123, y123, x1234, y1234, points, level + 1);
|
|
3762
|
-
this.recursiveCubic(x1234, y1234, x234, y234, x34, y34, x4, y4, points, level + 1);
|
|
3763
|
-
}
|
|
3764
|
-
addPoint(x, y, points) {
|
|
3765
|
-
const newPoint = new Vec2(x, y);
|
|
3766
|
-
if (points.length === 0) {
|
|
3767
|
-
points.push(newPoint);
|
|
3768
|
-
return;
|
|
3769
|
-
}
|
|
3770
|
-
const lastPoint = points[points.length - 1];
|
|
3771
|
-
const dx = newPoint.x - lastPoint.x;
|
|
3772
|
-
const dy = newPoint.y - lastPoint.y;
|
|
3773
|
-
const distanceSquared = dx * dx + dy * dy;
|
|
3774
|
-
if (distanceSquared > COLLINEARITY_EPSILON * COLLINEARITY_EPSILON) {
|
|
3775
|
-
points.push(newPoint);
|
|
3776
|
-
}
|
|
3748
|
+
const x12 = start.x + (control1.x - start.x) * t;
|
|
3749
|
+
const y12 = start.y + (control1.y - start.y) * t;
|
|
3750
|
+
const x23 = control1.x + (control2.x - control1.x) * t;
|
|
3751
|
+
const y23 = control1.y + (control2.y - control1.y) * t;
|
|
3752
|
+
const x34 = control2.x + (end.x - control2.x) * t;
|
|
3753
|
+
const y34 = control2.y + (end.y - control2.y) * t;
|
|
3754
|
+
const x123 = x12 + (x23 - x12) * t;
|
|
3755
|
+
const y123 = y12 + (y23 - y12) * t;
|
|
3756
|
+
const x234 = x23 + (x34 - x23) * t;
|
|
3757
|
+
const y234 = y23 + (y34 - y23) * t;
|
|
3758
|
+
emit(x123 + (x234 - x123) * t, y123 + (y234 - y123) * t);
|
|
3759
|
+
}
|
|
3760
|
+
return _out;
|
|
3777
3761
|
}
|
|
3778
3762
|
}
|
|
3779
3763
|
|
|
@@ -4862,6 +4846,35 @@ async function loadBinary(filePath) {
|
|
|
4862
4846
|
}
|
|
4863
4847
|
}
|
|
4864
4848
|
|
|
4849
|
+
function getDefaultExportFromCjs (x) {
|
|
4850
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
4851
|
+
}
|
|
4852
|
+
|
|
4853
|
+
function getAugmentedNamespace(n) {
|
|
4854
|
+
if (n.__esModule) return n;
|
|
4855
|
+
var f = n.default;
|
|
4856
|
+
if (typeof f == "function") {
|
|
4857
|
+
var a = function a () {
|
|
4858
|
+
if (this instanceof a) {
|
|
4859
|
+
return Reflect.construct(f, arguments, this.constructor);
|
|
4860
|
+
}
|
|
4861
|
+
return f.apply(this, arguments);
|
|
4862
|
+
};
|
|
4863
|
+
a.prototype = f.prototype;
|
|
4864
|
+
} else a = {};
|
|
4865
|
+
Object.defineProperty(a, '__esModule', {value: true});
|
|
4866
|
+
Object.keys(n).forEach(function (k) {
|
|
4867
|
+
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
4868
|
+
Object.defineProperty(a, k, d.get ? d : {
|
|
4869
|
+
enumerable: true,
|
|
4870
|
+
get: function () {
|
|
4871
|
+
return n[k];
|
|
4872
|
+
}
|
|
4873
|
+
});
|
|
4874
|
+
});
|
|
4875
|
+
return a;
|
|
4876
|
+
}
|
|
4877
|
+
|
|
4865
4878
|
var hb = {exports: {}};
|
|
4866
4879
|
|
|
4867
4880
|
var fs = {};
|