Comparing version 1.0.0-beta.16 to 1.0.0-beta.17
@@ -34,12 +34,14 @@ import { vec2 } from 'gl-matrix'; | ||
/** | ||
* ### Gets the distance from a given point to the bezier curve. | ||
* 设定切点 p 则 p-p0 表述为 关于参数 t 的 3 阶方程,p 点切线表述为关于参数 t 的 2 阶方程, | ||
* 满足垂直时,即内积为 0,两个方程的内积表述为关于参数t 的 5 阶方程,5 阶方程没有解析解,所以无法直接求解切点 | ||
* @param pos | ||
* @returns | ||
* @inheritdoc | ||
* 设定垂足点 p0 则 p0 -> pos 表述为 关于参数 t 的 3 阶方程,p0 点切线表述为关于参数 t 的 2 阶方程, | ||
* 满足垂直时,即内积为 0,两个方程的内积表述为关于参数t 的 5 阶方程,5 阶方程没有解析解,所以无法用解析法求解垂足 | ||
*/ | ||
getDisToPos(pos: vec2): number; | ||
getDisToPos2(pos: vec2): number; | ||
getDerivative(t: number): vec2; | ||
getSecondDerivative(t: number): vec2; | ||
applyFn(fn: PointFn): void; | ||
/** | ||
* ### Apply a free form deformation (FFD) to the curve. | ||
* @param fn | ||
*/ | ||
applyFFDFn(fn: PointFn): void; | ||
@@ -46,0 +48,0 @@ reverse(): void; |
@@ -56,6 +56,7 @@ import { vec2 } from 'gl-matrix'; | ||
/** | ||
* Gets the length of the curve. | ||
* @param coordData | ||
abstract get len(): number; | ||
* ### get the max curvature of this curve | ||
* curvature = 1 / r, curvature > 0 means the curve is turning right, otherwise, turning left | ||
* @returns | ||
*/ | ||
abstract getMaxCurvature(): number; | ||
/** | ||
@@ -62,0 +63,0 @@ * Gets the position on the curve at the given parameter value. |
@@ -32,2 +32,7 @@ import { vec2 } from 'gl-matrix'; | ||
/** | ||
* ### get the max curvature of this curve | ||
* @returns | ||
*/ | ||
getMaxCurvature(): number; | ||
/** | ||
* Gets the position on the line curve at a given parameter value. | ||
@@ -34,0 +39,0 @@ * @param t The parameter value. |
@@ -31,6 +31,7 @@ import { vec2 } from 'gl-matrix'; | ||
getNormal(t: number): vec2; | ||
getMaxCurvature(): number; | ||
getSplitT(data: CoordData): number[]; | ||
getLineIntersects(line: LineCurve): vec2[]; | ||
/** | ||
* Gets the distance from a given point to the quadratic curve. | ||
* ### Gets the distance from a given point to the quadratic curve by numerical method. | ||
* @param pos | ||
@@ -40,6 +41,12 @@ * @returns | ||
getDisToPos(pos: vec2): number; | ||
/** | ||
* Gets the distance from a given point to the quadratic curve by Analytical method | ||
* @param pos | ||
* @returns | ||
*/ | ||
getDisToPos2(pos: vec2): number; | ||
getDerivative(t: number): vec2; | ||
getSecondDerivative(_?: number): vec2; | ||
/** | ||
* 计算曲率半径 | ||
* ### 计算曲率半径 | ||
*/ | ||
@@ -46,0 +53,0 @@ getCurvature(t: number): number; |
@@ -7,2 +7,3 @@ export * from './base'; | ||
export * from './shape'; | ||
export * from './transform'; | ||
export * from './utils'; |
@@ -10,1 +10,10 @@ import { vec2 } from 'gl-matrix'; | ||
export declare function calRadius(pointA: vec2, pointB: vec2, pointC: vec2): number; | ||
/** | ||
* ### calculate the curvature of a circle(with sign) | ||
* curvature = sign * 1 / r | ||
* @param pointA | ||
* @param pointB | ||
* @param pointC | ||
* @returns | ||
*/ | ||
export declare function getCurvature(pointA: vec2, pointB: vec2, pointC: vec2): number; |
@@ -5,2 +5,3 @@ export * from './circle'; | ||
export * from './statistics'; | ||
export * from './triangle'; | ||
export * from './utils'; |
@@ -1,10 +0,2 @@ | ||
import { vec2 } from 'gl-matrix'; | ||
export declare function getRandomGenerate(x?: number): () => number; | ||
/** | ||
* ### get the area of a triangle | ||
* 目前使用的是海伦公式,后续可以考虑使用叉积 | ||
* @param points | ||
* @returns | ||
*/ | ||
export declare function getTriangleArea(points: vec2[]): number; | ||
export declare function getEaseElasticOut(t: number): number; | ||
@@ -11,0 +3,0 @@ export declare function getEaseElasticInOut(t: number): number; |
@@ -50,3 +50,4 @@ import { vec2 } from 'gl-matrix'; | ||
export declare function getDistMark(x: number, k: number): number; | ||
export declare function getAngleMark(val: number, limit: number): number; | ||
export declare function getConnectMark(polyline0: Polyline, polyline1: Polyline, angleLimit?: number): number; | ||
export declare function connectPolyline(polyline0: Polyline, polyline1: Polyline): Polyline; |
@@ -1,1 +0,1 @@ | ||
(function(f,B){typeof exports=="object"&&typeof module<"u"?B(exports):typeof define=="function"&&define.amd?define(["exports"],B):(f=typeof globalThis<"u"?globalThis:f||self,B(f.geometry={}))})(this,function(f){"use strict";var Bn=Object.defineProperty;var In=(f,B,N)=>B in f?Bn(f,B,{enumerable:!0,configurable:!0,writable:!0,value:N}):f[B]=N;var m=(f,B,N)=>In(f,typeof B!="symbol"?B+"":B,N);function B(){return{xMin:1/0,xMax:-1/0,yMin:1/0,yMax:-1/0}}function N(o,e,t,n){const{x:i,y:s}=o,{x:r,y:c}=e,{x:a,y:h}=t,{x:l,y:u}=n,P=c-s,d=i-r,p=r*s-i*c,y=u-h,x=a-l,C=l*h-a*u,v=P*x-y*d,b=(d*C-x*p)/v,S=(y*p-P*C)/v;return{x:b,y:S}}var Pt=1e-6,H=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var o=0,e=arguments.length;e--;)o+=arguments[e]*arguments[e];return Math.sqrt(o)});function g(){var o=new H(2);return H!=Float32Array&&(o[0]=0,o[1]=0),o}function I(o){var e=new H(2);return e[0]=o[0],e[1]=o[1],e}function M(o,e){var t=new H(2);return t[0]=o,t[1]=e,t}function Nt(o,e,t){return o[0]=e[0]+t[0],o[1]=e[1]+t[1],o}function Qt(o,e,t){return o[0]=e[0]-t[0],o[1]=e[1]-t[1],o}function jt(o,e,t){return o[0]=e[0]*t,o[1]=e[1]*t,o}function nt(o,e,t,n){return o[0]=e[0]+t[0]*n,o[1]=e[1]+t[1]*n,o}function E(o,e){var t=e[0]-o[0],n=e[1]-o[1];return Math.hypot(t,n)}function Ot(o){var e=o[0],t=o[1];return Math.hypot(e,t)}function Q(o,e){var t=e[0],n=e[1],i=t*t+n*n;return i>0&&(i=1/Math.sqrt(i)),o[0]=e[0]*i,o[1]=e[1]*i,o}function et(o,e){return o[0]*e[0]+o[1]*e[1]}function A(o,e,t,n){var i=e[0],s=e[1];return o[0]=i+n*(t[0]-i),o[1]=s+n*(t[1]-s),o}function j(o,e){var t=o[0],n=o[1],i=e[0],s=e[1],r=Math.sqrt(t*t+n*n)*Math.sqrt(i*i+s*s),c=r&&(t*i+n*s)/r;return Math.acos(Math.min(Math.max(c,-1),1))}function U(o,e){return o[0]===e[0]&&o[1]===e[1]}function dt(o,e){var t=o[0],n=o[1],i=e[0],s=e[1];return Math.abs(t-i)<=Pt*Math.max(1,Math.abs(t),Math.abs(i))&&Math.abs(n-s)<=Pt*Math.max(1,Math.abs(n),Math.abs(s))}var pt=Ot,R=Qt,O=E;(function(){var o=g();return function(e,t,n,i,s,r){var c,a;for(t||(t=2),n||(n=0),i?a=Math.min(i*t+n,e.length):a=e.length,c=n;c<a;c+=t)o[0]=e[c],o[1]=e[c+1],s(o,o,r),e[c]=o[0],e[c+1]=o[1];return e}})();class gt{constructor(e,t){m(this,"type","curve");m(this,"_isDirty",!0);m(this,"_SPoint",g());m(this,"_EPoint",g());m(this,"_bbox");m(this,"_len");m(this,"inDir",g());m(this,"ouDir",g());this.SPoint=e,this.EPoint=t,this._isDirty=!1}set SPoint(e){this._isDirty||(this._isDirty=!U(this._SPoint,e)),this._SPoint=e}get SPoint(){return this._SPoint}set EPoint(e){this._isDirty||(this._isDirty=!U(this._EPoint,e)),this._EPoint=e}get EPoint(){return this._EPoint}get bbox(){return(this._isDirty||!this._bbox)&&this.update(),this._bbox}get len(){return(this._isDirty||!this._len&&this._len!==0)&&this.update(),this._len}update(){this._bbox=this._getBBox(),this._len=this._getLen(),this._isDirty=!1}divideAtArray(e){e.sort((s,r)=>s-r);let t=this;const n=new Array(e.length+1);let i=0;for(let s=0;s<e.length;s++){let r=e[s];r=(r-i)/(1-i),i=e[s];const c=t.divideAt(r);n[s]=c[0],t=c[1]}return n[e.length]=t,n}splitByCoord(e){const t=this.getSplitT(e);return this.divideAtArray(t)}}const W="curve-line";class T extends gt{constructor(t,n){super(t,n);m(this,"tangent");m(this,"normal");this.type=W,this.tangent=Q(g(),R(g(),n,t)),this.normal=M(-this.tangent[1],this.tangent[0]),this.inDir=this.tangent,this.ouDir=this.tangent}update(){super.update(),this.tangent=Q(g(),R(g(),this.EPoint,this.SPoint)),this.normal=M(-this.tangent[1],this.tangent[0]),this.inDir=this.tangent,this.ouDir=this.tangent}_getBBox(){const{SPoint:t,EPoint:n}=this,i=Math.min(t[0],n[0]),s=Math.min(t[1],n[1]),r=Math.abs(t[0]-n[0]),c=Math.abs(t[1]-n[1]);return{x:i,y:s,width:r,height:c}}_getLen(){return E(this.SPoint,this.EPoint)}getNormal(t){return this.normal}getTangent(t){return this.tangent}getPosition(t){return A(g(),this.SPoint,this.EPoint,t)}getPosDataByPer(t){const n=this.getPosition(t),i=this.tangent;return{pos:n,tan:i}}getSplitT(t){const{x:n,y:i,width:s,height:r}=this.bbox,{SPoint:c,EPoint:a}=this,{mode:h,val:l}=t,u=[];return h==="x"&&l>=n&&l<=n+s?u.push((l-c[0])/(a[0]-c[0])):h==="y"&&l>=i&&l<=i+r&&u.push((l-c[1])/(a[1]-c[1])),u}getLineIntersects(t){const[n,i]=this.SPoint,[s,r]=this.EPoint,[c,a]=t.SPoint,[h,l]=t.EPoint,u=[],P=(n-s)*(a-l)-(i-r)*(c-h);if(Math.abs(P)>1e-10){const d=n*r-i*s,p=c*l-a*h,y=(d*(c-h)-p*(n-s))/P,x=(d*(a-l)-p*(i-r))/P,{x:C,y:v,width:b,height:S}=this.bbox;y>=C&&y<=y+b&&x>=v&&x<=v+S&&u.push(M(y,x))}return u}getDisToPos(t){const{SPoint:n,EPoint:i,tangent:s}=this,r=R(g(),t,n),c=et(r,s);if(c<0)return E(n,t);const a=E(n,i);if(c>a)return E(i,t);const h=M(-s[1],s[0]);return Math.abs(et(h,r))}applyFn(t){t(this.SPoint),t(this.EPoint)}applyFFDFn(t){this.applyFn(t)}reverse(){[this.SPoint,this.EPoint]=[this.EPoint,this.SPoint],this.update()}divideAt(t){const{SPoint:n,EPoint:i}=this,s=this.getPosition(t);return[new T(n,s),new T(I(s),i)]}isPointOnCurve(t){const{SPoint:n,EPoint:i}=this,s=E(n,t),r=E(i,t),c=E(n,i);return Math.abs(s+r-c)<1e-10}toPathString(t=0){const[n,i]=this.EPoint;return`L ${n.toFixed(t)} ${i.toFixed(t)}`}toDebugPathString(t){return this.toPathString(t)}clone(){return new T(I(this.SPoint),I(this.EPoint))}}function xt(o,e){const[t,n]=o.SPoint,[i,s]=o.EPoint,[r,c]=e.SPoint,[a,h]=e.EPoint,l=(t-r)*(h-c)-(n-c)*(a-r),u=(i-r)*(h-c)-(s-c)*(a-r);if(l*u>0)return!1;const P=(r-t)*(s-n)-(c-n)*(i-t),d=(a-t)*(s-n)-(h-n)*(i-t);return!(P*d>0)}const X=1e-12;function F(o){switch(o.length){case 0:return[];case 1:return[0];case 2:return Math.abs(o[0])<X?[]:[-o[1]/o[0]];case 3:return Math.abs(o[0])<X?F(o.slice(1)):Zt(o);case 4:return Math.abs(o[0])<X?F(o.slice(1)):Yt(o);default:throw new Error("Not implemented")}}function Zt(o){const e=o[0],t=o[1],n=o[2],i=t*t-4*e*n;if(i<0)return[];{const s=Math.sqrt(i);return[(-t+s)/(2*e),(-t-s)/(2*e)]}}function Yt(o){const e=o[0],t=o[1],n=o[2],i=o[3],s=t/e,r=n/e,c=i/e,a=(3*r-s*s)/9,h=(9*s*r-27*c-2*s*s*s)/54,l=a*a*a+h*h;if(l>=0){const u=Math.sqrt(l),P=Math.cbrt(h+u),d=Math.cbrt(h-u),p=[-s/3+(P+d)];return l===0&&p.push(-P/2),p}else{const u=Math.acos(h/Math.sqrt(-a*a*a)),P=Math.sqrt(-a);return[2*P*Math.cos(u/3)-s/3,2*P*Math.cos((u+2*Math.PI)/3)-s/3,2*P*Math.cos((u+4*Math.PI)/3)-s/3]}}function Xt(o,e,t){[o[e],o[t]]=[o[t],o[e]]}function Gt(o){const{length:e}=o;for(let n=0;n<e;n++){let i=n;for(let s=n+1;s<e;s++)Math.abs(o[s][n])>Math.abs(o[i][n])&&(i=s);Xt(o,n,i);for(let s=n+1;s<e;s++){if(Math.abs(o[n][n])<X)continue;const r=o[s][n]/o[n][n];for(let c=n;c<e+1;c++)o[s][c]-=r*o[n][c]}}const t=new Array(e).fill(0);for(let n=e-1;n>=0;n--)if(!(Math.abs(o[n][n])<X)){t[n]=o[n][e]/o[n][n];for(let i=n-1;i>=0;i--)o[i][e]-=o[i][n]*t[n]}return console.log(o),t}const J=100,yt="curve-quadratic";class k extends T{constructor(t,n,i){super(t,i);m(this,"_CPoint1",g());m(this,"_lenArr",new Array(J).fill(0));this.type=yt,this.CPoint1=n,this.inDir=Q(g(),R(g(),n,t)),this.ouDir=Q(g(),R(g(),i,n))}set CPoint1(t){this._isDirty||(this._isDirty=!U(this._CPoint1,t)),this._CPoint1=t}get CPoint1(){return this._CPoint1}update(){super.update(),this.inDir=this.getTangent(0),this.ouDir=this.getTangent(1)}getRoughBBox(){const[t,n]=this.SPoint,[i,s]=this.CPoint1,[r,c]=this.EPoint,a=Math.min(t,i,r),h=Math.max(t,i,r),l=Math.min(n,s,c),u=Math.max(n,s,c);return{x:a,y:l,width:h-a,height:u-l}}_getBBox(){const t=this.SPoint[0],n=this.SPoint[1],i=this.CPoint1[0],s=this.CPoint1[1],r=this.EPoint[0],c=this.EPoint[1],a=[2*(t-2*i+r),2*(i-r)],h=[2*(n-2*s+c),2*(s-c)],l=F(a),u=F(h),P=l.filter(S=>S>0&&S<1).concat([0,1]),d=u.filter(S=>S>0&&S<1).concat([0,1]),p=P.map(S=>this.getPosition(S)[0]),y=d.map(S=>this.getPosition(S)[1]),x=Math.min(...p),C=Math.max(...p),v=Math.min(...y),b=Math.max(...y);return{x,y:v,width:C-x,height:b-v}}_getLen(){let t=0,n=this.getPosition(0);for(let i=1;i<=J;i++){let s=this.getPosition(i/100);t+=E(n,s),n=s,this._lenArr[i-1]=t}return t}getPosition(t){const n=(1-t)**2,i=2*t*(1-t),s=t**2,r=n*this.SPoint[0]+i*this.CPoint1[0]+s*this.EPoint[0],c=n*this.SPoint[1]+i*this.CPoint1[1]+s*this.EPoint[1];return M(r,c)}getPosDataByPer(t){let n=0,i=this._lenArr.length-1,s;const r=this.len*t;for(;n<i;)s=Math.floor((n+i)/2),this._lenArr[s]<r?n=s+1:i=s;const c=this._lenArr[n-1]||0;let a=n/J;a+=(r-c)/(this._lenArr[n]-c)/J;const h=this.getPosition(a),l=this.getTangent(a);return{pos:h,tan:l}}getTangent(t){const n=this.getDerivative(t);return Q(n,n)}getNormal(t){const[n,i]=this.getTangent(t);return M(i,-n)}getSplitT(t){const{x:n,y:i,width:s,height:r}=this.bbox,{mode:c,val:a}=t;if(c==="x"){if(a>=n&&a<=n+s){const h=[this.SPoint[0]-2*this.CPoint1[0]+this.EPoint[0],2*(this.CPoint1[0]-this.EPoint[0]),this.EPoint[0]-a];return F(h).filter(u=>u>0&&u<1)}}else if(a>=i&&a<=i+r){const h=[this.SPoint[1]-2*this.CPoint1[1]+this.EPoint[1],2*(this.CPoint1[1]-this.EPoint[1]),this.EPoint[1]-a];return F(h).filter(u=>u>0&&u<1)}return[]}getLineIntersects(t){const n=[],[i,s]=this.SPoint,[r,c]=this.CPoint1,[a,h]=this.EPoint,[l,u]=t.SPoint,P=i-2*r+a,d=s-2*c+h,p=2*(r-i),y=2*(c-s),x=i,C=s,[v,b]=R(g(),t.EPoint,t.SPoint),S=v*d-b*P,D=v*y-b*p,w=v*C-b*x-v*u+b*l,_=F([S,D,w]);for(const L of _)if(L>=0&&L<=1){const ut=(1-L)**2*i+2*L*(1-L)*r+L**2*a,ft=(1-L)**2*s+2*L*(1-L)*c+L**2*h;n.push(M(ut,ft))}return n}getDisToPos(t){const[n,i]=this.SPoint,[s,r]=this.CPoint1,[c,a]=this.EPoint,[h,l]=t,u=n-2*s+c,P=i-2*r+a,d=2*(s-n),p=2*(r-i),y=n,x=i,C=u**2+P**2,v=2*(u*d+P*p),b=d**2+p**2,S=2*(u*(y-h)+P*(x-l)),D=2*(d*(y-h)+p*(x-l)),w=(C*D-v*S)/(v**2-4*C*b),_=this.getPosition(w);return E(t,_)}getDerivative(t){const n=2*(1-t)*(this.CPoint1[0]-this.SPoint[0])+2*t*(this.EPoint[0]-this.CPoint1[0]),i=2*(1-t)*(this.CPoint1[1]-this.SPoint[1])+2*t*(this.EPoint[1]-this.CPoint1[1]);return M(n,i)}getSecondDerivative(t){const n=2*(this.EPoint[0]-2*this.CPoint1[0]+this.SPoint[0]),i=2*(this.EPoint[1]-2*this.CPoint1[1]+this.SPoint[1]);return M(n,i)}getCurvature(t){const[n,i]=this.getDerivative(t),[s,r]=this.getSecondDerivative(t),c=n**2+i**2;return c<1e-20?1/0:(n*r-i*s)/c**1.5}getCusps(t=.01){const i=new Array(101);for(let r=0;r<=100;r++){const c=r/100;i[r]=this.getCurvature(c)}const s=[];for(let r=1;r<100;r++)(i[r]-i[r-1])*(i[r]-i[r+1])>0&&Math.abs(i[r])>t&&s.push(r/100);return s}applyFn(t){t(this.SPoint),t(this.EPoint),t(this.CPoint1)}applyFFDFn(t){this.applyFn(t);const n=M(this.CPoint1[0]-.5*(this.SPoint[0]+this.EPoint[0]),this.CPoint1[1]-.5*(this.SPoint[1]+this.EPoint[1]));Nt(this.CPoint1,this.CPoint1,n)}divideAt(t){const n=this.SPoint,i=this.EPoint,s=this.CPoint1,r=A(g(),n,s,t),c=A(g(),s,i,t),a=A(g(),r,c,t),h=new k(n,r,a),l=new k(I(a),c,i);return[h,l]}divideAtArray(t){return super.divideAtArray.call(this,t)}pathOffset(t){const i=[0,.5,1].map(c=>{const a=this.getPosition(c),h=this.getNormal(c);return nt(g(),a,h,t)}),s=A(g(),i[0],i[2],.5),r=A(s,s,i[1],2);return new k(i[0],r,i[2])}splitByCoord(t){const n=this.getSplitT(t);return this.divideAtArray(n)}toPathString(t=0){return`Q ${this.CPoint1[0].toFixed(t)} ${this.CPoint1[1].toFixed(t)} ${this.EPoint[0].toFixed(t)} ${this.EPoint[1].toFixed(t)}`}toDebugPathString(t){return`L ${this.CPoint1[0].toFixed(t)} ${this.CPoint1[1].toFixed(t)} L ${this.EPoint[0].toFixed(t)} ${this.EPoint[1].toFixed(t)}`}toPoints(t=10){const n=new Array(t),i=1/t;for(let s=1;s<=t;s++){const r=this.getPosition(s*i);n[s-1]=r}return n.reverse()}clone(){return new k(I(this.SPoint),I(this.CPoint1),I(this.EPoint))}}function Ht(o){const e=o.SPoint,t=o.EPoint,n=M((e[0]+t[0])/2,(e[1]+t[1])/2);return new k(e,n,t)}const mt="curve-bezier";class V extends k{constructor(t,n,i,s){super(t,n,s);m(this,"_CPoint2",g());this.type=mt,this.CPoint2=i}set CPoint2(t){this._isDirty||(this._isDirty=!U(this._CPoint2,t)),this._CPoint2=t}get CPoint2(){return this._CPoint2}_getBBox(){const[t,n]=this.SPoint,[i,s]=this.CPoint1,[r,c]=this.CPoint2,[a,h]=this.EPoint,l=[-3*t+9*i-9*r+3*a,6*t-12*i+6*r,3*i-3*t],u=[-3*n+9*s-9*c+3*h,6*n-12*s+6*c,3*s-3*n],P=F(l),d=F(u),p=P.filter(w=>w>0&&w<1).concat([0,1]),y=d.filter(w=>w>0&&w<1).concat([0,1]),x=p.map(w=>this.getPosition(w)[0]),C=y.map(w=>this.getPosition(w)[1]),v=Math.min(...x),b=Math.max(...x),S=Math.min(...C),D=Math.max(...C);return{x:v,y:S,width:b-v,height:D-S}}getSplitT(t){const{x:n,y:i,width:s,height:r}=this.bbox,{mode:c,val:a}=t,h=c==="y"?1:0;if(a<[n,i][h]||a>[n+s,i+r][h])return[];{const l=[-this.SPoint[h]+3*this.CPoint1[h]-3*this.CPoint2[h]+this.EPoint[h],3*this.SPoint[h]-6*this.CPoint1[h]+3*this.CPoint2[h],-3*this.SPoint[h]+3*this.CPoint1[h],this.SPoint[h]-a],u=F(l),P=1e-8;return u.filter(d=>d>P&&d<1-P)}}getPosition(t){let n=(1-t)**3,i=3*t*(1-t)*(1-t),s=3*t*t*(1-t),r=t**3,c=n*this.SPoint[0]+i*this.CPoint1[0]+s*this.CPoint2[0]+r*this.EPoint[0],a=n*this.SPoint[1]+i*this.CPoint1[1]+s*this.CPoint2[1]+r*this.EPoint[1];return M(c,a)}getTangent(t){const n=this.getDerivative(t);return Q(n,n)}getNormal(t){const[n,i]=this.getTangent(t);return M(i,-n)}getDisToPos(t){let i=1/0;for(let s=0;s<=100;s++){const r=s/100,c=this.getPosition(r),a=O(c,t);i=Math.min(i,a)}return i}getDerivative(t){let n=-3*(1-t)**2,i=3*(1-4*t+3*t**2),s=3*(2*t-3*t**2),r=3*t**2,c=n*this.SPoint[0]+i*this.CPoint1[0]+s*this.CPoint2[0]+r*this.EPoint[0],a=n*this.SPoint[1]+i*this.CPoint1[1]+s*this.CPoint2[1]+r*this.EPoint[1];return M(c,a)}getSecondDerivative(t){let n=6*(1-t),i=6*(3*t-2),s=6*(1-3*t),r=6*t,c=n*this.SPoint[0]+i*this.CPoint1[0]+s*this.CPoint2[0]+r*this.EPoint[0],a=n*this.SPoint[1]+i*this.CPoint1[1]+s*this.CPoint2[1]+r*this.EPoint[1];return M(c,a)}applyFn(t){t(this.SPoint),t(this.EPoint),t(this.CPoint1),t(this.CPoint2)}applyFFDFn(t){I(this.CPoint1),I(this.CPoint2),this.applyFn(t)}reverse(){[this.CPoint1,this.CPoint2]=[this.CPoint2,this.CPoint1],super.reverse()}getLineIntersects(t){const{bbox:n}=this;if(n.x>t.bbox.x+t.bbox.width||n.x+n.width<t.bbox.x||n.y>t.bbox.y+t.bbox.height||n.y+n.height<t.bbox.y)return[];const i=[],[s,r]=this.SPoint,[c,a]=this.CPoint1,[h,l]=this.CPoint2,[u,P]=this.EPoint,[d,p]=t.SPoint,y=-s+3*c-3*h+u,x=-r+3*a-3*l+P,C=3*s-6*c+3*h,v=3*r-6*a+3*l,b=-3*s+3*c,S=-3*r+3*a,D=s,w=r,[_,L]=R(g(),t.EPoint,t.SPoint),ut=_*x-L*y,ft=_*v-L*C,wn=_*S-L*b,En=_*w-L*D-(_*p-L*d),Dn=F([ut,ft,wn,En]);for(const $ of Dn)if($>=0&&$<=1){const An=y*$**3+C*$**2+b*$+D,Ln=x*$**3+v*$**2+S*$+w;i.push(M(An,Ln))}return i}divideAt(t){const n=this.SPoint,i=this.EPoint,s=this.CPoint1,r=this.CPoint2,c=A(g(),n,s,t),a=A(g(),s,r,t),h=A(g(),r,i,t),l=A(g(),c,a,t),u=A(g(),a,h,t),P=this.getPosition(t),d=new V(n,c,l,P),p=new V(I(P),u,h,i);return[d,p]}divideAtArray(t){return super.divideAtArray.call(this,t)}splitByCoord(t){const n=this.getSplitT(t);return this.divideAtArray(n)}toPathString(t=0){return`C ${this.CPoint1[0].toFixed(t)} ${this.CPoint1[1].toFixed(t)} ${this.CPoint2[0].toFixed(t)} ${this.CPoint2[1].toFixed(t)} ${this.EPoint[0].toFixed(t)} ${this.EPoint[1].toFixed(t)}`}toDebugPathString(t){return` L ${this.CPoint1[0].toFixed(t)} ${this.CPoint1[1].toFixed(t)} L ${this.CPoint2[0].toFixed(t)} ${this.CPoint2[1].toFixed(t)} L ${this.EPoint[0].toFixed(t)} ${this.EPoint[1].toFixed(t)}`}clone(){return new V(I(this.SPoint),I(this.CPoint1),I(this.CPoint2),I(this.EPoint))}}function Mt(o){if(o instanceof V)return o;if(o instanceof T)return Ct(o);if(o instanceof k)return St(o);throw new Error("Unsupported curve type.")}function Ct(o){const{SPoint:e,EPoint:t}=o,n=A(g(),e,t,1/3),i=A(g(),e,t,2/3);return new V(e,n,i,t)}function St(o){const{SPoint:e,CPoint1:t,EPoint:n}=o,i=A(g(),e,t,2/3),s=A(g(),n,t,2/3);return new V(e,i,s,n)}class vt{constructor(e){m(this,"curves",[]);m(this,"points",[]);m(this,"_isClockwise");m(this,"_len");m(this,"_lenArr",[]);m(this,"_bounds");this.curves=e,this.initPoints()}initPoints(){const{length:e}=this.curves;if(e!==0){this.points=new Array(e),this.points[0]=this.curves[0].SPoint;for(let t=0;t<e;t++)this.points[t+1]=this.curves[t].EPoint}}get isClockwise(){return this._isClockwise===void 0&&(this._isClockwise=this.getIsClockwise()),this._isClockwise}get bounds(){return this._bounds||(this._bounds=this.getBBox2()),this._bounds}get len(){return this._len||(this._len=this._getLen()),this._len}get SPoint(){return this.curves[0].SPoint}get EPoint(){return this.curves[this.curves.length-1].EPoint}get inDir(){return this.curves[0].inDir}get outDir(){return this.curves[this.curves.length-1].ouDir}getIsClockwise(){const{points:e}=this,{length:t}=e;let n=0;for(let i=0;i<t;i++){const s=e[i],r=e[(i+1)%t];n+=(r[0]-s[0])*(r[1]+s[1])}return n>0}_getLen(){this._lenArr=this.curves.map(t=>t.len);const{length:e}=this.curves;for(let t=1;t<e;t++)this._lenArr[t]+=this._lenArr[t-1];return this._lenArr[e-1]}getBBox2(e=B()){for(const{bbox:t}of this.curves){const{x:n,y:i,width:s,height:r}=t;e.xMin=Math.min(e.xMin,n),e.xMax=Math.max(e.xMax,n+s),e.yMin=Math.min(e.yMin,i),e.yMax=Math.max(e.yMax,i+r)}return e}getLineIntersects(e){const{curves:t}=this,{length:n}=t,i=new Array(n);for(let s=0;s<n;s++){const c=t[s].getLineIntersects(e);i[s]=c}return i.flat()}getPosDataByPer(e,t=!1){const{len:n}=this;t&&(e=(e+1)%1);const i=e*n;if(e<=0){const u=this.curves[0],P=e*i/this.curves[0].len;return u.getPosDataByPer(P)}if(e>=1){const u=this.curves[this.curves.length-1],P=(e-1)*i/u.len+1;return u.getPosDataByPer(P)}let s=0,r=this._lenArr.length-1,c;for(;s<r;)c=Math.floor((s+r)/2),this._lenArr[c]<i?s=c+1:r=c;const a=this.curves[s],h=s===0?0:this._lenArr[s-1],l=(i-h)/a.len;return a.getPosDataByPer(l)}splitByCoord(e){const t=[];for(const n of this.curves){const i=n.splitByCoord(e);t.push(...i)}return this.curves=t,this.curves}divideAtByNum(e=100){const t=new Array(e-1);for(let s=1;s<e;s++)t[s-1]=s/e;const{length:n}=this.curves,i=new Array(n*e);for(let s=0;s<n;s++){const c=this.curves[s].divideAtArray(t);i.splice(s*e,e,...c)}this.curves=i}reverse(){this.curves.reverse();for(const e of this.curves)e.reverse();this.points.reverse(),this._getLen()}toPathString(e=0){let t=this.curves[0].SPoint,n=`M ${t[0].toFixed(e)} ${t[1].toFixed(e)} `,i=t;for(const r of this.curves){if(!(E(i,r.SPoint)<1)){const{SPoint:a}=r;n+=`M ${a[0].toFixed(e)} ${a[1].toFixed(e)} `,t=a}n+=r.toPathString(e)+" ",i=r.EPoint}return E(i,t)<1&&(n+="Z"),n}toPoints(e=100){let t=new Array(e+1);for(let n=0;n<=e;n++){const i=n/e,{pos:s}=this.getPosDataByPer(i);t[n]=s}return t}}function Ut(o){const e=E(o[0].SPoint,o[o.length-1].EPoint)<1;let t=0;if(e){let s=0;for(let r=0;r<o.length;r++){const a=o[r].len;a>s&&(s=a,t=r)}}let n=[o[t]];for(let s=1;s<o.length;s++){const r=(s+t)%o.length,c=o[r],a=n[n.length-1];c.type===W&&a.type===W&&et(c.inDir,a.ouDir)>.99?a.EPoint=c.EPoint:n.push(c)}o=n,n=[o[0]];const i=(s,r,c)=>{const{len:a}=s,{len:h}=r,{len:l}=c,u=20;if(a>u*h&&l>u*h){const d=j(s.ouDir,r.inDir),p=j(r.ouDir,c.inDir);if(d<p)s.EPoint=r.EPoint;else return c.SPoint=r.SPoint,!0}else n.push(r)};for(let s=1;s<o.length-1;s++){const r=n[n.length-1],c=o[s],a=o[s+1];i(r,c,a)&&(n.push(a),s++)}return e?i(n[n.length-1],o[o.length-1],o[0]):n.push(o[o.length-1]),n}function Wt(o){const e=document.createElementNS("http://www.w3.org/2000/svg","svg"),t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("d",o),e.appendChild(t),e}function bt(o,e=1){const t=o[0].SPoint;let n=`M ${t[0].toFixed(e)} ${t[1].toFixed(e)} `;return o.forEach(i=>{n+=i.toPathString(e)+" "}),n+="Z",n}function Jt(o,e=1){const t=o[0].SPoint;let n=`M ${t[0].toFixed(e)} ${t[1].toFixed(e)} `;return o.forEach(i=>{n+=i.toDebugPathString(e)+" "}),n}function st(o){const e=[];let t="",n=[];function i(s,r){e.push({type:s,args:r})}for(let s=0;s<o.length;s++){const r=o[s];if(r.match(/[A-Z]/))t&&i(t,n),t=r,n=[];else{if(r===" "||r===",")continue;if(r==="-"||r==="."||!isNaN(parseInt(r,10))){const c=s;for(;s<o.length&&(o[s]==="-"||o[s]==="."||!isNaN(parseInt(o[s],10)));)s++;const a=o.substring(c,s);n.push(parseFloat(a)),s--}}}return i(t,n),e}function Kt(o,e,t){const n=[],i=o.length,s=e.length;for(let r=0;r<s;r++){const c=A(g(),o[r%i],e[r],t);n.push(c)}return n}class q extends vt{constructor(t){super(t);m(this,"currentPos",g())}get isClosed(){return this.curves.length>0&&O(this.curves[0].SPoint,this.curves[this.curves.length-1].EPoint)<.001}moveTo(t,n){this.currentPos=M(t,n)}lineTo(t,n){const i=new T(this.currentPos,M(t,n));this.curves.push(i),this.currentPos=M(t,n)}bezierCurveTo(t,n,i,s,r,c){const a=new V(this.currentPos,M(t,n),M(i,s),M(r,c));this.curves.push(a),this.currentPos=M(r,c)}quadraticCurveTo(t,n,i,s){const r=new k(this.currentPos,M(t,n),M(i,s));this.curves.push(r),this.currentPos=M(i,s)}closePath(){const t=this.curves[0].SPoint;if(dt(this.currentPos,t))return;const n=new T(this.currentPos,this.curves[0].SPoint);this.curves.push(n)}static fromCommands(t){const n=new q([]);let i=0;for(let s=0;s<t.length;s++){const r=t[s],{type:c,args:a=[]}=r,h=a.length,{x:l=a[h-2],y:u=a[h-1],x1:P=a[0],y1:d=a[1],x2:p=a[2],y2:y=a[3]}=r;switch(c){case"M":n.moveTo(l,u),i++,i>1&&console.error("SimpleShape can only have one start point");break;case"L":dt(n.currentPos,M(l,u))||n.lineTo(l,u);break;case"H":n.lineTo(l,n.currentPos[1]);break;case"V":n.lineTo(n.currentPos[0],u);break;case"C":n.bezierCurveTo(P,d,p,y,l,u);break;case"Q":n.quadraticCurveTo(P,d,l,u);break;case"Z":n.closePath();break}}return n}static fromPathString(t){const n=st(t);return q.fromCommands(n)}}class wt extends q{constructor(t){super(t);m(this,"curves");this.curves=t}}function tn(o){const e=o.curves.map(t=>Mt(t));return new wt(e)}class nn{constructor(e){m(this,"points");m(this,"bbox");this.points=e,this.bbox={xMin:1/0,xMax:-1/0,yMin:1/0,yMax:-1/0};for(let t of this.points)this.bbox.xMin=Math.min(this.bbox.xMin,t[0]),this.bbox.xMax=Math.max(this.bbox.xMax,t[0]),this.bbox.yMin=Math.min(this.bbox.yMin,t[1]),this.bbox.yMax=Math.max(this.bbox.yMax,t[1])}getArea(){return Math.abs(this.getSignArea())}getSignArea(){return it(this.points)}getCentroid(){let e=this.getSignArea(),t=0,n=0;for(let i=0;i<this.points.length;i++){let[s,r]=this.points[i],[c,a]=this.points[(i+1)%this.points.length];t+=(s+c)*(s*a-c*r),n+=(r+a)*(s*a-c*r)}return[t/6/e,n/6/e]}includePoint(e){return e[0]<this.bbox.xMin||e[0]>this.bbox.xMax||e[1]<this.bbox.yMin||e[1]>this.bbox.yMax?!1:ot(e,this.points)}includePolygon(e){if(e.bbox.xMin<this.bbox.xMin||e.bbox.xMax>this.bbox.xMax||e.bbox.yMin<this.bbox.yMin||e.bbox.yMax>this.bbox.yMax)return!1;for(let t of e.points)if(!this.includePoint(t))return!1;return!0}intersectPolygon(e){for(let t of e.points)if(this.includePoint(t))return!0;return!1}}function it(o){let e=0;const{length:t}=o;for(let n=0;n<t;n++){let[i,s]=o[n],[r,c]=o[(n+1)%t];e+=i*c-r*s}return e/2}function en(o,e){let[t,n]=o,[[i,s],[r,c]]=e;return(t-i)*(c-s)-(n-s)*(r-i)>0}function ot(o,e){let[t,n]=o,i=!1;for(let s=0,r=e.length-1;s<e.length;r=s++){let[c,a]=e[s],[h,l]=e[r];a>n!=l>n&&t-c<(h-c)*(n-a)/(l-a)&&(i=!i)}return i}class Et{constructor(e,t,n){m(this,"angle");this.point=e,this.inVec=t,this.outVec=n,this.angle=j(this.inVec,this.outVec)}}class G extends q{constructor(t){super(t);m(this,"nodes",[]);this.curves=t,this.initNodes()}initNodes(){let{curves:t}=this;const{length:n}=t;for(let i=0;i<n;i++){const s=t[i],r=t[(i-1+n)%n],c=s.SPoint;this.nodes[i]=new Et(c,r.ouDir,s.inDir)}this.curves=t,this.initPoints()}includePoint(t){const{xMin:n,xMax:i,yMin:s,yMax:r}=this.bounds;return t[0]<n||t[0]>i||t[1]<s||t[1]>r?!1:ot(t,this.points)}splitInAngle(t=60){t*=Math.PI/180;const{curves:n,nodes:i}=this,{length:s}=n,r=[];let c=[];for(let h=0;h<s;h++){const l=n[h],{angle:u}=i[h];u>t?(c.length&&r.push(c),c=[l]):c.push(l)}if(c.length){const{angle:h}=i[0];h<=t&&r.length?r[0]=c.concat(r[0]):r.push(c)}return r.map(h=>new q(h))}static fromCommands(t){const{length:n}=t;(t[0].type!=="M"||t[n-1].type!=="Z")&&console.error("ClosedShape must start with M and end with Z");const i=super.fromCommands(t);return new G(i.curves)}}function Dt(o,e,t){const n=E(o,e),i=E(e,t),s=E(t,o),r=(n+i+s)/2;return n*i*s/4/Math.sqrt(r*(r-n)*(r-i)*(r-s))}function At(o){return new Array(o).fill(0).map(()=>new Array(o))}function sn(o){return o.map(e=>e.slice())}function on(o){return Math.max(...o)}function rn(o){return Math.min(...o)}function z(o){return o.reduce((e,t)=>e+t,0)}function K(o){return z(o)/o.length}function cn(o){return K(o),Math.sqrt(Lt(o))}function Lt(o){const e=K(o);return K(o.map(t=>Math.pow(t-e,2)))}function an(o){const e=o.slice().sort((n,i)=>n-i),t=Math.floor(o.length/2);return o.length%2!==0?e[t]:(e[t-1]+e[t])/2}function Bt(o,e){const t=o.length,n=z(o),i=z(e),s=i/t,r=z(o.map((p,y)=>p*e[y])),c=z(o.map(p=>p*p)),a=1e-10;if(t*c-n*n<a)return{k:1/0,b:n/t,R2:1};const h=(t*r-n*i)/(t*c-n*n),l=(i-h*n)/t,u=Math.max(a,z(e.map(p=>Math.pow(p-s,2)))),d=Math.max(a,z(o.map(p=>Math.pow(h*p+l-s,2))))/u;return{k:h,b:l,R2:d}}const It=1103515245,Tt=12345,rt=2147483647;function Ft(o=.314){let e=(It*o+Tt)%rt;return()=>(e=(It*e+Tt)%rt,e/rt)}function hn(o){const e=E(o[0],o[1]),t=E(o[1],o[2]),n=E(o[2],o[0]),i=(e+t+n)/2;return Math.sqrt(i*(i-e)*(i-t)*(i-n))}function ln(o){return Math.pow(2,-10*o)*Math.sin((o-.2/4)*(2*Math.PI)/.2)+1}function un(o){return o<.5?.5*Math.pow(2,20*o-10)*Math.sin((20*o-11.125)*(2*Math.PI)/.9):.5*(2-Math.pow(2,-20*o+10)*Math.sin((20*o-11.125)*(2*Math.PI)/.9))}function fn(o,e=4){return Math.max(e-Math.floor(Math.log10(o)),0)}function Pn(o){if(o.length<=1)return o;const e=new Map,t=new Map;for(const s of o){if(s.length<2)throw new Error("couple length must be greater than 1");const[r,c]=[s[0],s[s.length-1]];e.set(r,c),t.set(c,r)}const n=[];let i=o.length**2;for(;(e.size||t.size)&&i-- >0;){let s=e.keys().next().value;const r=[s];let c=e.get(s);for(;c!==void 0&&c!==s&&i-- >0;)r.push(c),e.delete(s),t.delete(c),s=c,c=e.get(c);for(s=r[0],c=t.get(s);c!==void 0&&c!==s&&i-- >0;)r.unshift(c),e.delete(c),t.delete(s),s=c,c=t.get(c);n.push(r)}return n}class Z extends q{constructor(t){super(t);m(this,"curves");this.curves=t}static fromPoints(t){let n=[];for(let i=0;i<t.length-1;i++)n.push(new T(t[i],t[i+1]));return new Z(n)}getDistance(t){let n=1/0;for(let i of this.points)n=Math.min(n,O(i,t));return n}getClosestPoint(t){let n=1/0,i=g();for(let s of this.points){let r=O(s,t);r<n&&(n=r,i=s)}return i}split(t=100){const{points:n}=this,i=pn(n,t),s=Rt(n,i);let r=[];return s.forEach(c=>{const a=dn(c),h=Rt(c,a);r.push(...h)}),r.filter(c=>c.length>=2).map(c=>Z.fromPoints(c))}}function dn(o,e=[2,4,8,16,32]){const{length:t}=o;let n=0,i=0,s=new Set;for(let a=0;a<e.length;a++){const h=e[a];if(t<2*h)break;for(let l=h;l<t-h;l++){const u=o[l-h],P=o[l],d=o[l+h],p=R(g(),P,u),y=R(g(),d,P),x=Math.max(j(p,y)*180/Math.PI,0);n<x&&(n=x,i=l),x>120&&s.add(l)}}const r=Array.from(s).sort((a,h)=>a-h);return r.length<=1?r:[i]}function pn(o,e=100){const{length:t}=o,n=new Array(t-2);for(let s=1;s<t-1;s++){const r=o[s-1],c=o[s],a=o[s+1];n[s-1]=Dt(r,c,a)}const i=[];for(let s=1;s<n.length-1;s++){const r=n[s-1],c=n[s],a=n[s+1];c<r&&c<a&&c<e&&i.push(s+1)}return i}function Rt(o,e){const{length:t}=e,n=new Array(t+1);let i=0;for(let s=0;s<t;s++){const r=e[s],c=o.slice(i,r+1);n[s]=c,i=r}return i<o.length&&(n[t]=o.slice(i)),n}function ct(o,e){const{points:t}=o,{points:n}=e,{length:i}=t,{length:s}=n,r={datas:[],min:1/0,max:1/0,mean:1/0,std:1/0},c=new T(o.EPoint,e.SPoint),a=new T(e.EPoint,o.SPoint);if(xt(c,a))return[r,r];const l=[...t,...n];if(!tt(l))return[r,r];const P=new Array(i).fill({dis:1/0,index:-1}),d=new Array(s).fill({dis:1/0,index:-1});for(let y=0;y<i;y++)for(let x=0;x<s;x++){const C=O(t[y],n[x]);C<P[y].dis&&(P[y]={dis:C,index:x}),C<d[x].dis&&(d[x]={dis:C,index:y})}return[P,d].map(y=>{const x=y.map(({dis:D})=>D),C=Math.min(...x),v=Math.max(...x),b=x.reduce((D,w)=>D+w,0)/x.length,S=Math.sqrt(x.map(D=>Math.pow(D-b,2)).reduce((D,w)=>D+w,0)/x.length);return{datas:y,min:C,max:v,mean:b,std:S}})}function gn(o){const{points:e,bounds:t}=o,n=Math.min(e.length,5),i=e.slice(-n),s=i.map(([l])=>l),r=i.map(([,l])=>l),{k:c,b:a,R2:h}=Bt(s,r);return{k:c,b:a,R2:h}}function at(o,e){return Math.exp(-(o-1)/e)}function xn(o,e,t=30){if(o.isClosed||e.isClosed)return 0;const{EPoint:n,outDir:i}=o,{SPoint:s,inDir:r}=e,c=R(g(),s,n),a=pt(c),h=at(a,100),l=j(c,i)*180/Math.PI,u=j(c,r)*180/Math.PI,P=(d,p)=>Math.max(1-d/p,0);return h*P(l,t)*P(u,t)}function yn(o,e){const t=O(o.EPoint,e.SPoint)<.001,n=[...o.points,...e.points.slice(t?1:0)];return Z.fromPoints(n)}class kt extends Z{constructor(e){super(e)}}function mn(o,e=100,t=1e3){console.time("getRailCouples");const{length:n}=o,i=At(n);for(let a=0;a<n;a++)for(let h=a+1;h<n;h++){const[l,u]=ct(o[a],o[h]);i[a][h]=l,i[h][a]=u}const s=new Array(n);for(let a=0;a<n;a++){o[a];let h=-1/0,l=-1;for(let u=0;u<n;u++){if(a===u)continue;const{std:P,min:d,mean:p,max:y}=i[a][u],x=P>1e10?0:(.9-P/t)*at(p,e);x>h&&(h=x,l=u)}s[a]=l}const r=new Set;for(let a=0;a<s.length;a++)r.has(a)||s[s[a]]===a&&(r.add(a),r.add(s[a]));const c=r.size>>1;new Array(c);for(let a=0;a<s.length;a++)r.has(a)||console.log("配对不成功",a);return console.timeEnd("getRailCouples"),{successIndex:r,minStdIndexArr:s}}function Mn(o,e=1){const t=o.len,n=Math.ceil(t/e),i=o.toPoints(n);return kt.fromPoints(i)}class Cn{constructor(e,t){m(this,"rail0");m(this,"rail1");this.rail0=e,this.rail1=t}createRungs(e){const{rail0:t,rail1:n}=this;this.checkDirection();const i=t.isClosed,s=n.isClosed,r=t.len,c=n.len,{length:a,width:h}=e,[l,u]=ct(t,n);let[P,d,p,y]=[r,l,t,n];r>c||(P=c,p=n,y=t,d=u);const x=i&&s?d.datas[0].index/y.curves.length:0,C=Math.floor(P/h),v=new Array(C);for(let b=0;b<C;b+=1){const S=b/C,{pos:D}=p.getPosDataByPer(S),{pos:w}=y.getPosDataByPer(S+x,!0),_=new T(D,w);v[b]=_}return v}checkDirection(){const{rail0:e,rail1:t}=this;tt(e.points),tt(t.points),t.reverse()}}function tt(o){return it(o)>0}class Sn{constructor(e,t,n=.3,i=Math.SQRT2){m(this,"length");m(this,"width");this.minRatio=n,this.maxRatio=i,this.length=e,this.width=t}fillLine(e,t){const{length:n}=this,i=R(g(),t,e),s=pt(i);if(s<this.minRatio*n)return[];const r=[e];let c=Math.floor(s/n);const a=jt(g(),i,n/s);for(let u=1;u<c;u++){const P=nt(g(),e,a,u);r.push(P)}const h=s/n%1;if(!(h+1<this.maxRatio)&&c>0){const u=(h+1)/2,P=nt(g(),r[r.length-1]||e,a,u);r.push(P)}return r.push(t),r}}class Y{constructor(e,t="NONZERO"){this.shapes=e,this.windingRule=t}static fromCommands(e){const t=[];let n=[];for(const s of e)s.type==="M"?(n.length>0&&t.push(n),n=[s]):n.push(s);n.length>0&&t.push(n);const i=t.map(s=>G.fromCommands(s));return new Y(i)}static fromPathString(e){const t=st(e);return Y.fromCommands(t)}getBBox2(e=B()){for(const t of this.shapes)t.getBBox2(e);return e}includePoint(e){let t=!0;for(const n of this.shapes){const{isClockwise:i}=n,s=n.includePoint(e);if(t&&(t=i?!s:s),!t)return!1}return t}applyFn(e){for(const t of this.shapes)for(const n of t.curves)n.applyFn(e)}applyFFDFn(e){for(const t of this.shapes)for(const n of t.curves)n.applyFFDFn(e)}intersectLine(e){let t=[];for(const n of this.shapes)t=t.concat(n.getLineIntersects(e));return t}split(){const{shapes:e}=this,t=[];for(let i=0;i<e.length;i++){const s=e[i],{bounds:r,isClockwise:c}=s;if(!c)t.push([s]);else{const a=t.find(h=>{const l=h[0].bounds;return l.xMin<=r.xMin&&l.xMax>=r.xMax&&l.yMin<=r.yMin&&l.yMax>=r.yMax});a?a.push(s):console.error("can't find the path for the shape",s)}}return t.map(i=>new Y(i))}splitByCoord(e){for(const t of this.shapes)t.splitByCoord(e)}toPathString(e=0){let t="";for(const n of this.shapes)t+=n.toPathString(e)+" ";return t=t.slice(0,-1),t}toPoints(e){let t=[];for(const n of this.shapes)t=t.concat(n.toPoints(e));return t}clone(){const e=this.shapes.map(t=>{const n=t.curves.map(i=>i.clone());return new G(n)});return new Y(e,this.windingRule)}}function vn(o,e){const{length:t}=o;if(e<1)throw new Error("degree must be at least 1 (linear)");if(e>t-1)throw new Error(`degree:${e} must be less than or equal to point count - 1(${t-1})`);const n=new Array(t),i=new Array(t);for(let s=0;s<t;s++)n[s]=o[s][0],i[s]=o[s][1];return s=>{if(s<0||s>1)throw new Error("out of bounds");s=s*t+e;const r=_t(n,e,s),c=_t(i,e,s);return M(r,c)}}function _t(o,e,t){const{length:n}=o,i=n+e,s=Math.floor(t),r=new Array(i);for(let c=0;c<i;c++)r[c]=o[c%n];for(let c=0;c<e;c++)for(let a=s;a>s-e+c;a--){const h=(t-a)/(e-c);r[a]=h*r[a]+(1-h)*r[a-1]}return r[s]}function Vt(o,e,t,n=0,i=0,s=.1){const r=[],c=o/2,a=e/2,h=Ft(s);let l=u=>{const d=h()*n+(1-n);let p=(d*Math.cos(u)+1)*c,y=(d*Math.sin(u)+1)*a;return M(p,y)};for(let u=0;u<t;u++){let P=l(2*Math.PI*(u/t+i));r.push(P)}return r}function qt(o){let e=1/0,t=1/0,n=-1/0,i=-1/0;for(const s of o){const{bbox:r}=s;e=Math.min(e,r.x),t=Math.min(t,r.y),n=Math.max(n,r.x+r.width),i=Math.max(i,r.y+r.height)}return{x:e,y:t,width:n-e,height:i-t}}function zt(o,e){const t=qt(o),n=e.width/t.width,i=e.height/t.height;for(const s of o)s.applyFn(r=>{r[0]=(r[0]-t.x)*n+e.x,r[1]=(r[1]-t.y)*i+e.y})}function $t(o,e=3){const t=[],i=new Array(100),s=vn(o,Number(e)),r=performance.now();for(let a=0;a<100;a++)i[a]=s(a/100);performance.now()-r;const c=new Array(100);for(let a=0;a<100;a++){const h=M(i[a][0],i[a][1]),l=M(i[(a+1)%100][0],i[(a+1)%100][1]),u=A(g(),h,l,.5);c[a]=u}for(let a=0;a<100;a++){const h=I(c[a]),l=c[(a+1)%100],u=i[(a+1)%100];t.push(new k(h,u,l))}return t}function bn(o=100,e=100,t=6,n=.5,i=Math.random(),s=3){const r=Vt(o,e,t,n,i),c=$t(r,s);return zt(c,{x:0,y:0,width:o,height:e}),bt(c)}class ht{constructor(e){m(this,"value");m(this,"next",null);this.value=e}}class lt{constructor(){m(this,"head",null);m(this,"tail",null);m(this,"size",0)}static fromArray(e){const t=new lt;return e.forEach(n=>t.append(n)),t}toArray(){let e=this.head;const t=[];for(;e;)t.push(e.value),e=e.next;return t}append(e){const t=new ht(e);this.tail&&(this.tail.next=t),this.tail=t,this.head||(this.head=t),this.size++}prepend(e){const t=new ht(e);this.head&&(t.next=this.head),this.head=t,this.tail||(this.tail=t),this.size++}delete(e){var n;if(!this.head)return;for(;this.head&&this.head.value===e;)this.head=this.head.next,this.size--;let t=this.head;for(;t&&t.next;)t.next.value===e?(t.next=t.next.next,this.size--):t=t.next;((n=this.tail)==null?void 0:n.value)===e&&(this.tail=t)}find(e){let t=this.head;for(;t;){if(t.value===e)return t;t=t.next}return null}toString(){let e=this.head;const t=[];for(;e;)t.push(e.value),e=e.next;return t.join(" -> ")}getSize(){return this.size}clear(){this.head=null,this.tail=null,this.size=0}}f.BezierCurve=V,f.BezierCurveType=mt,f.BezierShape=wt,f.ClosedShape=G,f.Curve=gt,f.LineCurve=T,f.LineCurveType=W,f.LineToQuadratic=Ht,f.LinkedList=lt,f.Node=ht,f.Path=Y,f.PointNode=Et,f.Polygon=nn,f.Polyline=Z,f.QuadraticCurve=k,f.QuadraticCurveType=yt,f.Rail=Cn,f.Shape=vt,f.SingleRail=kt,f.SingleShape=q,f.Stitch=Sn,f.calDisData=ct,f.calExtendCurve=gn,f.calPointsArea=it,f.calRadius=Dt,f.checkLineCurveIntersect=xt,f.connectPolyline=yn,f.copyMatrix=sn,f.createBBox2=B,f.createMatrix=At,f.createSingleRailFromSingleShape=Mn,f.createSvgByPath=Wt,f.gaussElimination=Gt,f.getBezierCurvesBBox=qt,f.getBezierFromCurve=Mt,f.getBezierShapeFormSingleShape=tn,f.getConnectMark=xn,f.getCurvesByPolygon=$t,f.getDebugPathStr=Jt,f.getDigit=fn,f.getDistMark=at,f.getEaseElasticInOut=un,f.getEaseElasticOut=ln,f.getPathStr=bt,f.getPointsClockwise=tt,f.getPolygon=Vt,f.getRailCouples=mn,f.getRandomGenerate=Ft,f.getRandomPathStr=bn,f.getRoots=F,f.getTriangleArea=hn,f.interpolatePolygon=Kt,f.isInLeft=en,f.isPointInPoints=ot,f.lineInterSect=N,f.lineToBezier=Ct,f.linearRegression=Bt,f.max=on,f.mean=K,f.median=an,f.mergeCouple=Pn,f.min=rn,f.pathStringToPathCommands=st,f.quadraticToBezier=St,f.resizeCurvesByBBox=zt,f.simplyCurves=Ut,f.std=cn,f.sum=z,f.variance=Lt,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})}); | ||
(function(f,B){typeof exports=="object"&&typeof module<"u"?B(exports):typeof define=="function"&&define.amd?define(["exports"],B):(f=typeof globalThis<"u"?globalThis:f||self,B(f.geometry={}))})(this,function(f){"use strict";var zn=Object.defineProperty;var Nn=(f,B,j)=>B in f?zn(f,B,{enumerable:!0,configurable:!0,writable:!0,value:j}):f[B]=j;var C=(f,B,j)=>Nn(f,typeof B!="symbol"?B+"":B,j);function B(){return{xMin:1/0,xMax:-1/0,yMin:1/0,yMax:-1/0}}function j(o,e,t,n){const{x:i,y:s}=o,{x:r,y:c}=e,{x:a,y:h}=t,{x:l,y:u}=n,P=c-s,p=i-r,d=r*s-i*c,g=u-h,x=a-l,M=l*h-a*u,v=P*x-g*p,m=(p*M-x*d)/v,b=(g*d-P*M)/v;return{x:m,y:b}}var gt=1e-6,W=typeof Float32Array<"u"?Float32Array:Array;Math.hypot||(Math.hypot=function(){for(var o=0,e=arguments.length;e--;)o+=arguments[e]*arguments[e];return Math.sqrt(o)});function y(){var o=new W(2);return W!=Float32Array&&(o[0]=0,o[1]=0),o}function T(o){var e=new W(2);return e[0]=o[0],e[1]=o[1],e}function S(o,e){var t=new W(2);return t[0]=o,t[1]=e,t}function Xt(o,e){return o[0]=e[0],o[1]=e[1],o}function Gt(o,e,t){return o[0]=e[0]+t[0],o[1]=e[1]+t[1],o}function Ht(o,e,t){return o[0]=e[0]-t[0],o[1]=e[1]-t[1],o}function yt(o,e,t){return o[0]=e[0]*t,o[1]=e[1]*t,o}function J(o,e,t,n){return o[0]=e[0]+t[0]*n,o[1]=e[1]+t[1]*n,o}function E(o,e){var t=e[0]-o[0],n=e[1]-o[1];return Math.hypot(t,n)}function Ut(o){var e=o[0],t=o[1];return Math.hypot(e,t)}function Q(o,e){var t=e[0],n=e[1],i=t*t+n*n;return i>0&&(i=1/Math.sqrt(i)),o[0]=e[0]*i,o[1]=e[1]*i,o}function ot(o,e){return o[0]*e[0]+o[1]*e[1]}function A(o,e,t,n){var i=e[0],s=e[1];return o[0]=i+n*(t[0]-i),o[1]=s+n*(t[1]-s),o}function N(o,e){var t=o[0],n=o[1],i=e[0],s=e[1],r=Math.sqrt(t*t+n*n)*Math.sqrt(i*i+s*s),c=r&&(t*i+n*s)/r;return Math.acos(Math.min(Math.max(c,-1),1))}function K(o,e){return o[0]===e[0]&&o[1]===e[1]}function xt(o,e){var t=o[0],n=o[1],i=e[0],s=e[1];return Math.abs(t-i)<=gt*Math.max(1,Math.abs(t),Math.abs(i))&&Math.abs(n-s)<=gt*Math.max(1,Math.abs(n),Math.abs(s))}var mt=Ut,R=Ht,X=E;(function(){var o=y();return function(e,t,n,i,s,r){var c,a;for(t||(t=2),n||(n=0),i?a=Math.min(i*t+n,e.length):a=e.length,c=n;c<a;c+=t)o[0]=e[c],o[1]=e[c+1],s(o,o,r),e[c]=o[0],e[c+1]=o[1];return e}})();class Mt{constructor(e,t){C(this,"type","curve");C(this,"_isDirty",!0);C(this,"_SPoint",y());C(this,"_EPoint",y());C(this,"_bbox");C(this,"_len");C(this,"inDir",y());C(this,"ouDir",y());this.SPoint=e,this.EPoint=t,this._isDirty=!1}set SPoint(e){this._isDirty||(this._isDirty=!K(this._SPoint,e)),this._SPoint=e}get SPoint(){return this._SPoint}set EPoint(e){this._isDirty||(this._isDirty=!K(this._EPoint,e)),this._EPoint=e}get EPoint(){return this._EPoint}get bbox(){return(this._isDirty||!this._bbox)&&this.update(),this._bbox}get len(){return(this._isDirty||!this._len&&this._len!==0)&&this.update(),this._len}update(){this._bbox=this._getBBox(),this._len=this._getLen(),this._isDirty=!1}divideAtArray(e){e.sort((s,r)=>s-r);let t=this;const n=new Array(e.length+1);let i=0;for(let s=0;s<e.length;s++){let r=e[s];r=(r-i)/(1-i),i=e[s];const c=t.divideAt(r);n[s]=c[0],t=c[1]}return n[e.length]=t,n}splitByCoord(e){const t=this.getSplitT(e);return this.divideAtArray(t)}}const tt="curve-line";class I extends Mt{constructor(t,n){super(t,n);C(this,"tangent");C(this,"normal");this.type=tt,this.tangent=Q(y(),R(y(),n,t)),this.normal=S(-this.tangent[1],this.tangent[0]),this.inDir=this.tangent,this.ouDir=this.tangent}update(){super.update(),this.tangent=Q(y(),R(y(),this.EPoint,this.SPoint)),this.normal=S(-this.tangent[1],this.tangent[0]),this.inDir=this.tangent,this.ouDir=this.tangent}_getBBox(){const{SPoint:t,EPoint:n}=this,i=Math.min(t[0],n[0]),s=Math.min(t[1],n[1]),r=Math.abs(t[0]-n[0]),c=Math.abs(t[1]-n[1]);return{x:i,y:s,width:r,height:c}}_getLen(){return E(this.SPoint,this.EPoint)}getNormal(t){return this.normal}getTangent(t){return this.tangent}getMaxCurvature(){return 0}getPosition(t){return A(y(),this.SPoint,this.EPoint,t)}getPosDataByPer(t){const n=this.getPosition(t),i=this.tangent;return{pos:n,tan:i}}getSplitT(t){const{x:n,y:i,width:s,height:r}=this.bbox,{SPoint:c,EPoint:a}=this,{mode:h,val:l}=t,u=[];return h==="x"&&l>=n&&l<=n+s?u.push((l-c[0])/(a[0]-c[0])):h==="y"&&l>=i&&l<=i+r&&u.push((l-c[1])/(a[1]-c[1])),u}getLineIntersects(t){const[n,i]=this.SPoint,[s,r]=this.EPoint,[c,a]=t.SPoint,[h,l]=t.EPoint,u=[],P=(n-s)*(a-l)-(i-r)*(c-h);if(Math.abs(P)>1e-10){const p=n*r-i*s,d=c*l-a*h,g=(p*(c-h)-d*(n-s))/P,x=(p*(a-l)-d*(i-r))/P,{x:M,y:v,width:m,height:b}=this.bbox;g>=M&&g<=g+m&&x>=v&&x<=v+b&&u.push(S(g,x))}return u}getDisToPos(t){const{SPoint:n,EPoint:i,tangent:s}=this,r=R(y(),t,n),c=ot(r,s);if(c<0)return E(n,t);const a=E(n,i);if(c>a)return E(i,t);const h=S(-s[1],s[0]);return Math.abs(ot(h,r))}applyFn(t){t(this.SPoint),t(this.EPoint)}applyFFDFn(t){this.applyFn(t)}reverse(){[this.SPoint,this.EPoint]=[this.EPoint,this.SPoint],this.update()}divideAt(t){const{SPoint:n,EPoint:i}=this,s=this.getPosition(t);return[new I(n,s),new I(T(s),i)]}isPointOnCurve(t){const{SPoint:n,EPoint:i}=this,s=E(n,t),r=E(i,t),c=E(n,i);return Math.abs(s+r-c)<1e-10}toPathString(t=0){const[n,i]=this.EPoint;return`L ${n.toFixed(t)} ${i.toFixed(t)}`}toDebugPathString(t){return this.toPathString(t)}clone(){return new I(T(this.SPoint),T(this.EPoint))}}function Ct(o,e){const[t,n]=o.SPoint,[i,s]=o.EPoint,[r,c]=e.SPoint,[a,h]=e.EPoint,l=(t-r)*(h-c)-(n-c)*(a-r),u=(i-r)*(h-c)-(s-c)*(a-r);if(l*u>0)return!1;const P=(r-t)*(s-n)-(c-n)*(i-t),p=(a-t)*(s-n)-(h-n)*(i-t);return!(P*p>0)}const G=1e-12;function F(o){switch(o.length){case 0:return[];case 1:return[0];case 2:return Math.abs(o[0])<G?[]:[-o[1]/o[0]];case 3:return Math.abs(o[0])<G?F(o.slice(1)):Wt(o);case 4:return Math.abs(o[0])<G?F(o.slice(1)):Jt(o);default:throw new Error("Not implemented")}}function Wt(o){const e=o[0],t=o[1],n=o[2],i=t*t-4*e*n;if(i<0)return[];{const s=Math.sqrt(i);return[(-t+s)/(2*e),(-t-s)/(2*e)]}}function Jt(o){const e=o[0],t=o[1],n=o[2],i=o[3],s=t/e,r=n/e,c=i/e,a=(3*r-s*s)/9,h=(9*s*r-27*c-2*s*s*s)/54,l=a*a*a+h*h;if(l>=0){const u=Math.sqrt(l),P=Math.cbrt(h+u),p=Math.cbrt(h-u),d=[-s/3+(P+p)];return l===0&&d.push(-P/2),d}else{const u=Math.acos(h/Math.sqrt(-a*a*a)),P=Math.sqrt(-a);return[2*P*Math.cos(u/3)-s/3,2*P*Math.cos((u+2*Math.PI)/3)-s/3,2*P*Math.cos((u+4*Math.PI)/3)-s/3]}}function Kt(o,e,t){[o[e],o[t]]=[o[t],o[e]]}function tn(o){const{length:e}=o;for(let n=0;n<e;n++){let i=n;for(let s=n+1;s<e;s++)Math.abs(o[s][n])>Math.abs(o[i][n])&&(i=s);Kt(o,n,i);for(let s=n+1;s<e;s++){if(Math.abs(o[n][n])<G)continue;const r=o[s][n]/o[n][n];for(let c=n;c<e+1;c++)o[s][c]-=r*o[n][c]}}const t=new Array(e).fill(0);for(let n=e-1;n>=0;n--)if(!(Math.abs(o[n][n])<G)){t[n]=o[n][e]/o[n][n];for(let i=n-1;i>=0;i--)o[i][e]-=o[i][n]*t[n]}return console.log(o),t}const nt=100,vt="curve-quadratic";class V extends I{constructor(t,n,i){super(t,i);C(this,"_CPoint1",y());C(this,"_lenArr",new Array(nt).fill(0));this.type=vt,this.CPoint1=n,this.inDir=Q(y(),R(y(),n,t)),this.ouDir=Q(y(),R(y(),i,n))}set CPoint1(t){this._isDirty||(this._isDirty=!K(this._CPoint1,t)),this._CPoint1=t}get CPoint1(){return this._CPoint1}update(){super.update(),this.inDir=this.getTangent(0),this.ouDir=this.getTangent(1)}getRoughBBox(){const[t,n]=this.SPoint,[i,s]=this.CPoint1,[r,c]=this.EPoint,a=Math.min(t,i,r),h=Math.max(t,i,r),l=Math.min(n,s,c),u=Math.max(n,s,c);return{x:a,y:l,width:h-a,height:u-l}}_getBBox(){const t=this.SPoint[0],n=this.SPoint[1],i=this.CPoint1[0],s=this.CPoint1[1],r=this.EPoint[0],c=this.EPoint[1],a=[2*(t-2*i+r),2*(i-r)],h=[2*(n-2*s+c),2*(s-c)],l=F(a),u=F(h),P=l.filter(b=>b>0&&b<1).concat([0,1]),p=u.filter(b=>b>0&&b<1).concat([0,1]),d=P.map(b=>this.getPosition(b)[0]),g=p.map(b=>this.getPosition(b)[1]),x=Math.min(...d),M=Math.max(...d),v=Math.min(...g),m=Math.max(...g);return{x,y:v,width:M-x,height:m-v}}_getLen(){let t=0,n=this.getPosition(0);for(let i=1;i<=nt;i++){let s=this.getPosition(i/100);t+=E(n,s),n=s,this._lenArr[i-1]=t}return t}getPosition(t){const n=(1-t)**2,i=2*t*(1-t),s=t**2,r=n*this.SPoint[0]+i*this.CPoint1[0]+s*this.EPoint[0],c=n*this.SPoint[1]+i*this.CPoint1[1]+s*this.EPoint[1];return S(r,c)}getPosDataByPer(t){let n=0,i=this._lenArr.length-1,s;const r=this.len*t;for(;n<i;)s=Math.floor((n+i)/2),this._lenArr[s]<r?n=s+1:i=s;const c=this._lenArr[n-1]||0;let a=n/nt;a+=(r-c)/(this._lenArr[n]-c)/nt;const h=this.getPosition(a),l=this.getTangent(a);return{pos:h,tan:l}}getTangent(t){const n=this.getDerivative(t);return Q(n,n)}getNormal(t){const[n,i]=this.getTangent(t);return S(i,-n)}getMaxCurvature(){const t=this.getCusps();let n=0;for(const i of t){const s=this.getCurvature(i);Math.abs(s)>Math.abs(n)&&(n=s)}return n}getSplitT(t){const{x:n,y:i,width:s,height:r}=this.bbox,{mode:c,val:a}=t;if(c==="x"){if(a>=n&&a<=n+s){const h=[this.SPoint[0]-2*this.CPoint1[0]+this.EPoint[0],2*(this.CPoint1[0]-this.EPoint[0]),this.EPoint[0]-a];return F(h).filter(u=>u>0&&u<1)}}else if(a>=i&&a<=i+r){const h=[this.SPoint[1]-2*this.CPoint1[1]+this.EPoint[1],2*(this.CPoint1[1]-this.EPoint[1]),this.EPoint[1]-a];return F(h).filter(u=>u>0&&u<1)}return[]}getLineIntersects(t){const n=[],[i,s]=this.SPoint,[r,c]=this.CPoint1,[a,h]=this.EPoint,[l,u]=t.SPoint,P=i-2*r+a,p=s-2*c+h,d=2*(r-i),g=2*(c-s),x=i,M=s,[v,m]=R(y(),t.EPoint,t.SPoint),b=v*p-m*P,L=v*g-m*d,w=v*M-m*x-v*u+m*l,k=F([b,L,w]);for(const D of k)if(D>=0&&D<=1){const U=(1-D)**2*i+2*D*(1-D)*r+D**2*a,Y=(1-D)**2*s+2*D*(1-D)*c+D**2*h;n.push(S(U,Y))}return n}getDisToPos(t){let n=100,i=1/0;for(let s=0;s<=n;s++){const r=s/n,c=this.getPosition(r),a=E(t,c);a<i&&(i=a)}return i}getDisToPos2(t){const[n,i]=this.SPoint,[s,r]=this.CPoint1,[c,a]=this.EPoint,[h,l]=t,u=[[-(n-2*s+c),-2*(s-n),h-n],[-(i-2*r+a),-2*(r-i),l-i]],P=[[2*(n-2*s+c),2*(s-n)],[2*(i-2*r+a),2*(r-i)]],p=new Array(4).fill(0);for(let M=0;M<2;M++)for(let v=0;v<2;v++)for(let m=0;m<3;m++)p[v+m]+=P[M][v]*u[M][m]+P[M][v]*u[M][m];const g=[...F(p).filter(M=>M*(M-1)<0),0,1];let x=1/0;for(let M of g){const v=this.getPosition(M),m=E(t,v);m<x&&(x=m)}return x}getDerivative(t){const n=2*(1-t)*(this.CPoint1[0]-this.SPoint[0])+2*t*(this.EPoint[0]-this.CPoint1[0]),i=2*(1-t)*(this.CPoint1[1]-this.SPoint[1])+2*t*(this.EPoint[1]-this.CPoint1[1]);return S(n,i)}getSecondDerivative(t){const n=2*(this.EPoint[0]-2*this.CPoint1[0]+this.SPoint[0]),i=2*(this.EPoint[1]-2*this.CPoint1[1]+this.SPoint[1]);return S(n,i)}getCurvature(t){const[n,i]=this.getDerivative(t),[s,r]=this.getSecondDerivative(t),c=n*r-i*s;if(c<1e-20)return 0;const a=n**2+i**2;return a<1e-20?1/0:c/a**1.5}getCusps(t=1e-6){const i=new Array(21);for(let r=0;r<=20;r++){const c=r/20,a=this.getCurvature(c);i[r]=a}const s=[];for(let r=1;r<20;r++)(i[r]-i[r-1])*(i[r]-i[r+1])>0&&s.push(r/20);return i[0]*(i[0]-i[1])>0&&s.unshift(0),i[20]*(i[20]-i[19])>0&&s.push(1),s}applyFn(t){t(this.SPoint),t(this.EPoint),t(this.CPoint1)}applyFFDFn(t){this.applyFn(t);const n=S(this.CPoint1[0]-.5*(this.SPoint[0]+this.EPoint[0]),this.CPoint1[1]-.5*(this.SPoint[1]+this.EPoint[1]));Gt(this.CPoint1,this.CPoint1,n)}divideAt(t){const n=this.SPoint,i=this.EPoint,s=this.CPoint1,r=A(y(),n,s,t),c=A(y(),s,i,t),a=A(y(),r,c,t),h=new V(n,r,a),l=new V(T(a),c,i);return[h,l]}divideAtArray(t){return super.divideAtArray.call(this,t)}pathOffset(t){const i=[0,.5,1].map(c=>{const a=this.getPosition(c),h=this.getNormal(c);return J(y(),a,h,t)}),s=A(y(),i[0],i[2],.5),r=A(s,s,i[1],2);return new V(i[0],r,i[2])}splitByCoord(t){const n=this.getSplitT(t);return this.divideAtArray(n)}toPathString(t=0){return`Q ${this.CPoint1[0].toFixed(t)} ${this.CPoint1[1].toFixed(t)} ${this.EPoint[0].toFixed(t)} ${this.EPoint[1].toFixed(t)}`}toDebugPathString(t){return`L ${this.CPoint1[0].toFixed(t)} ${this.CPoint1[1].toFixed(t)} L ${this.EPoint[0].toFixed(t)} ${this.EPoint[1].toFixed(t)}`}toPoints(t=10){const n=new Array(t),i=1/t;for(let s=1;s<=t;s++){const r=this.getPosition(s*i);n[s-1]=r}return n.reverse()}clone(){return new V(T(this.SPoint),T(this.CPoint1),T(this.EPoint))}}function nn(o){const e=o.SPoint,t=o.EPoint,n=S((e[0]+t[0])/2,(e[1]+t[1])/2);return new V(e,n,t)}const St="curve-bezier";class _ extends V{constructor(t,n,i,s){super(t,n,s);C(this,"_CPoint2",y());this.type=St,this.CPoint2=i}set CPoint2(t){this._isDirty||(this._isDirty=!K(this._CPoint2,t)),this._CPoint2=t}get CPoint2(){return this._CPoint2}_getBBox(){const[t,n]=this.SPoint,[i,s]=this.CPoint1,[r,c]=this.CPoint2,[a,h]=this.EPoint,l=[-3*t+9*i-9*r+3*a,6*t-12*i+6*r,3*i-3*t],u=[-3*n+9*s-9*c+3*h,6*n-12*s+6*c,3*s-3*n],P=F(l),p=F(u),d=P.filter(w=>w>0&&w<1).concat([0,1]),g=p.filter(w=>w>0&&w<1).concat([0,1]),x=d.map(w=>this.getPosition(w)[0]),M=g.map(w=>this.getPosition(w)[1]),v=Math.min(...x),m=Math.max(...x),b=Math.min(...M),L=Math.max(...M);return{x:v,y:b,width:m-v,height:L-b}}getSplitT(t){const{x:n,y:i,width:s,height:r}=this.bbox,{mode:c,val:a}=t,h=c==="y"?1:0;if(a<[n,i][h]||a>[n+s,i+r][h])return[];{const l=[-this.SPoint[h]+3*this.CPoint1[h]-3*this.CPoint2[h]+this.EPoint[h],3*this.SPoint[h]-6*this.CPoint1[h]+3*this.CPoint2[h],-3*this.SPoint[h]+3*this.CPoint1[h],this.SPoint[h]-a],u=F(l),P=1e-8;return u.filter(p=>p>P&&p<1-P)}}getPosition(t){let n=(1-t)**3,i=3*t*(1-t)*(1-t),s=3*t*t*(1-t),r=t**3,c=n*this.SPoint[0]+i*this.CPoint1[0]+s*this.CPoint2[0]+r*this.EPoint[0],a=n*this.SPoint[1]+i*this.CPoint1[1]+s*this.CPoint2[1]+r*this.EPoint[1];return S(c,a)}getTangent(t){const n=this.getDerivative(t);return Q(n,n)}getNormal(t){const[n,i]=this.getTangent(t);return S(i,-n)}getDisToPos2(t){return console.error("bezier has no analytical solution for getDisToPos2"),this.getDisToPos(t)}getDerivative(t){let n=-3*(1-t)**2,i=3*(1-4*t+3*t**2),s=3*(2*t-3*t**2),r=3*t**2,c=n*this.SPoint[0]+i*this.CPoint1[0]+s*this.CPoint2[0]+r*this.EPoint[0],a=n*this.SPoint[1]+i*this.CPoint1[1]+s*this.CPoint2[1]+r*this.EPoint[1];return S(c,a)}getSecondDerivative(t){let n=6*(1-t),i=6*(3*t-2),s=6*(1-3*t),r=6*t,c=n*this.SPoint[0]+i*this.CPoint1[0]+s*this.CPoint2[0]+r*this.EPoint[0],a=n*this.SPoint[1]+i*this.CPoint1[1]+s*this.CPoint2[1]+r*this.EPoint[1];return S(c,a)}applyFn(t){t(this.SPoint),t(this.EPoint),t(this.CPoint1),t(this.CPoint2)}applyFFDFn(t){const{SPoint:n,EPoint:i}=this,s=[.4,.6],r=s.map(L=>{const w=this.getPosition(L);return t(w),w});t(n),t(i);const c=(L,w)=>{const k=(1-L)**3,D=3*L*(1-L)**2,U=3*L**2*(1-L),Y=L**3;return[D,U,w[0]-Y*i[0]-k*n[0],w[1]-Y*i[1]-k*n[1]]},[a,h,l,u]=c(s[0],r[0]),[P,p,d,g]=c(s[1],r[1]),x=1/(h*P-a*p),M=(h*d-p*l)*x,v=(h*g-p*u)*x,m=(P*l-a*d)*x,b=(P*u-a*g)*x;this.CPoint1=S(M,v),this.CPoint2=S(m,b)}reverse(){[this.CPoint1,this.CPoint2]=[this.CPoint2,this.CPoint1],super.reverse()}getLineIntersects(t){const{bbox:n}=this;if(n.x>t.bbox.x+t.bbox.width||n.x+n.width<t.bbox.x||n.y>t.bbox.y+t.bbox.height||n.y+n.height<t.bbox.y)return[];const i=[],[s,r]=this.SPoint,[c,a]=this.CPoint1,[h,l]=this.CPoint2,[u,P]=this.EPoint,[p,d]=t.SPoint,g=-s+3*c-3*h+u,x=-r+3*a-3*l+P,M=3*s-6*c+3*h,v=3*r-6*a+3*l,m=-3*s+3*c,b=-3*r+3*a,L=s,w=r,[k,D]=R(y(),t.EPoint,t.SPoint),U=k*x-D*g,Y=k*v-D*M,Rn=k*b-D*m,Vn=k*w-D*L-(k*d-D*p),_n=F([U,Y,Rn,Vn]);for(const z of _n)if(z>=0&&z<=1){const qn=g*z**3+M*z**2+m*z+L,$n=x*z**3+v*z**2+b*z+w;i.push(S(qn,$n))}return i}divideAt(t){const n=this.SPoint,i=this.EPoint,s=this.CPoint1,r=this.CPoint2,c=A(y(),n,s,t),a=A(y(),s,r,t),h=A(y(),r,i,t),l=A(y(),c,a,t),u=A(y(),a,h,t),P=this.getPosition(t),p=new _(n,c,l,P),d=new _(T(P),u,h,i);return[p,d]}divideAtArray(t){return super.divideAtArray.call(this,t)}splitByCoord(t){const n=this.getSplitT(t);return this.divideAtArray(n)}toPathString(t=0){return`C ${this.CPoint1[0].toFixed(t)} ${this.CPoint1[1].toFixed(t)} ${this.CPoint2[0].toFixed(t)} ${this.CPoint2[1].toFixed(t)} ${this.EPoint[0].toFixed(t)} ${this.EPoint[1].toFixed(t)}`}toDebugPathString(t){return` L ${this.CPoint1[0].toFixed(t)} ${this.CPoint1[1].toFixed(t)} L ${this.CPoint2[0].toFixed(t)} ${this.CPoint2[1].toFixed(t)} L ${this.EPoint[0].toFixed(t)} ${this.EPoint[1].toFixed(t)}`}clone(){return new _(T(this.SPoint),T(this.CPoint1),T(this.CPoint2),T(this.EPoint))}}function bt(o){if(o instanceof _)return o;if(o instanceof I)return wt(o);if(o instanceof V)return Et(o);throw new Error("Unsupported curve type.")}function wt(o){const{SPoint:e,EPoint:t}=o,n=A(y(),e,t,1/3),i=A(y(),e,t,2/3);return new _(e,n,i,t)}function Et(o){const{SPoint:e,CPoint1:t,EPoint:n}=o,i=A(y(),e,t,2/3),s=A(y(),n,t,2/3);return new _(e,i,s,n)}class Dt{constructor(e){C(this,"curves",[]);C(this,"points",[]);C(this,"_isClockwise");C(this,"_len");C(this,"_lenArr",[]);C(this,"_bounds");this.curves=e,this.initPoints()}initPoints(){const{length:e}=this.curves;if(e!==0){this.points=new Array(e),this.points[0]=this.curves[0].SPoint;for(let t=0;t<e;t++)this.points[t+1]=this.curves[t].EPoint}}get isClockwise(){return this._isClockwise===void 0&&(this._isClockwise=this.getIsClockwise()),this._isClockwise}get bounds(){return this._bounds||(this._bounds=this.getBBox2()),this._bounds}get len(){return this._len||(this._len=this._getLen()),this._len}get SPoint(){return this.curves[0].SPoint}get EPoint(){return this.curves[this.curves.length-1].EPoint}get inDir(){return this.curves[0].inDir}get outDir(){return this.curves[this.curves.length-1].ouDir}getIsClockwise(){const{points:e}=this,{length:t}=e;let n=0;for(let i=0;i<t;i++){const s=e[i],r=e[(i+1)%t];n+=(r[0]-s[0])*(r[1]+s[1])}return n>0}_getLen(){this._lenArr=this.curves.map(t=>t.len);const{length:e}=this.curves;for(let t=1;t<e;t++)this._lenArr[t]+=this._lenArr[t-1];return this._lenArr[e-1]}getBBox2(e=B()){for(const{bbox:t}of this.curves){const{x:n,y:i,width:s,height:r}=t;e.xMin=Math.min(e.xMin,n),e.xMax=Math.max(e.xMax,n+s),e.yMin=Math.min(e.yMin,i),e.yMax=Math.max(e.yMax,i+r)}return e}getLineIntersects(e){const{curves:t}=this,{length:n}=t,i=new Array(n);for(let s=0;s<n;s++){const c=t[s].getLineIntersects(e);i[s]=c}return i.flat()}getPosDataByPer(e,t=!1){const{len:n}=this;t&&(e=(e+1)%1);const i=e*n;if(e<=0){const u=this.curves[0],P=e*i/this.curves[0].len;return u.getPosDataByPer(P)}if(e>=1){const u=this.curves[this.curves.length-1],P=(e-1)*i/u.len+1;return u.getPosDataByPer(P)}let s=0,r=this._lenArr.length-1,c;for(;s<r;)c=Math.floor((s+r)/2),this._lenArr[c]<i?s=c+1:r=c;const a=this.curves[s],h=s===0?0:this._lenArr[s-1],l=(i-h)/a.len;return a.getPosDataByPer(l)}splitByCoord(e){const t=[];for(const n of this.curves){const i=n.splitByCoord(e);t.push(...i)}return this.curves=t,this.curves}divideAtByNum(e=100){const t=new Array(e-1);for(let s=1;s<e;s++)t[s-1]=s/e;const{length:n}=this.curves,i=new Array(n*e);for(let s=0;s<n;s++){const c=this.curves[s].divideAtArray(t);i.splice(s*e,e,...c)}this.curves=i}reverse(){this.curves.reverse();for(const e of this.curves)e.reverse();this.points.reverse(),this._getLen()}toPathString(e=0){let t=this.curves[0].SPoint,n=`M ${t[0].toFixed(e)} ${t[1].toFixed(e)} `,i=t;for(const r of this.curves){if(!(E(i,r.SPoint)<1)){const{SPoint:a}=r;n+=`M ${a[0].toFixed(e)} ${a[1].toFixed(e)} `,t=a}n+=r.toPathString(e)+" ",i=r.EPoint}return E(i,t)<1&&(n+="Z"),n}toPoints(e=100){let t=new Array(e+1);for(let n=0;n<=e;n++){const i=n/e,{pos:s}=this.getPosDataByPer(i);t[n]=s}return t}}function en(o){const e=E(o[0].SPoint,o[o.length-1].EPoint)<1;let t=0;if(e){let s=0;for(let r=0;r<o.length;r++){const a=o[r].len;a>s&&(s=a,t=r)}}let n=[o[t]];for(let s=1;s<o.length;s++){const r=(s+t)%o.length,c=o[r],a=n[n.length-1];c.type===tt&&a.type===tt&&ot(c.inDir,a.ouDir)>.99?a.EPoint=c.EPoint:n.push(c)}o=n,n=[o[0]];const i=(s,r,c)=>{const{len:a}=s,{len:h}=r,{len:l}=c,u=20;if(a>u*h&&l>u*h){const p=N(s.ouDir,r.inDir),d=N(r.ouDir,c.inDir);if(p<d)s.EPoint=r.EPoint;else return c.SPoint=r.SPoint,!0}else n.push(r)};for(let s=1;s<o.length-1;s++){const r=n[n.length-1],c=o[s],a=o[s+1];i(r,c,a)&&(n.push(a),s++)}return e?i(n[n.length-1],o[o.length-1],o[0]):n.push(o[o.length-1]),n}function sn(o){const e=document.createElementNS("http://www.w3.org/2000/svg","svg"),t=document.createElementNS("http://www.w3.org/2000/svg","path");return t.setAttribute("d",o),e.appendChild(t),e}function At(o,e=1){const t=o[0].SPoint;let n=`M ${t[0].toFixed(e)} ${t[1].toFixed(e)} `;return o.forEach(i=>{n+=i.toPathString(e)+" "}),n+="Z",n}function on(o,e=1){const t=o[0].SPoint;let n=`M ${t[0].toFixed(e)} ${t[1].toFixed(e)} `;return o.forEach(i=>{n+=i.toDebugPathString(e)+" "}),n}function rt(o){const e=[];let t="",n=[];function i(s,r){e.push({type:s,args:r})}for(let s=0;s<o.length;s++){const r=o[s];if(r.match(/[A-Z]/))t&&i(t,n),t=r,n=[];else{if(r===" "||r===",")continue;if(r==="-"||r==="."||!isNaN(parseInt(r,10))){const c=s;for(;s<o.length&&(o[s]==="-"||o[s]==="."||!isNaN(parseInt(o[s],10)));)s++;const a=o.substring(c,s);n.push(parseFloat(a)),s--}}}return i(t,n),e}function rn(o,e,t){const n=[],i=o.length,s=e.length;for(let r=0;r<s;r++){const c=A(y(),o[r%i],e[r],t);n.push(c)}return n}class q extends Dt{constructor(t){super(t);C(this,"currentPos",y())}get isClosed(){return this.curves.length>0&&X(this.curves[0].SPoint,this.curves[this.curves.length-1].EPoint)<.001}moveTo(t,n){this.currentPos=S(t,n)}lineTo(t,n){const i=new I(this.currentPos,S(t,n));this.curves.push(i),this.currentPos=S(t,n)}bezierCurveTo(t,n,i,s,r,c){const a=new _(this.currentPos,S(t,n),S(i,s),S(r,c));this.curves.push(a),this.currentPos=S(r,c)}quadraticCurveTo(t,n,i,s){const r=new V(this.currentPos,S(t,n),S(i,s));this.curves.push(r),this.currentPos=S(i,s)}closePath(){const t=this.curves[0].SPoint;if(xt(this.currentPos,t))return;const n=new I(this.currentPos,this.curves[0].SPoint);this.curves.push(n)}static fromCommands(t){const n=new q([]);let i=0;for(let s=0;s<t.length;s++){const r=t[s],{type:c,args:a=[]}=r,h=a.length,{x:l=a[h-2],y:u=a[h-1],x1:P=a[0],y1:p=a[1],x2:d=a[2],y2:g=a[3]}=r;switch(c){case"M":n.moveTo(l,u),i++,i>1&&console.error("SimpleShape can only have one start point");break;case"L":xt(n.currentPos,S(l,u))||n.lineTo(l,u);break;case"H":n.lineTo(l,n.currentPos[1]);break;case"V":n.lineTo(n.currentPos[0],u);break;case"C":n.bezierCurveTo(P,p,d,g,l,u);break;case"Q":n.quadraticCurveTo(P,p,l,u);break;case"Z":n.closePath();break}}return n}static fromPathString(t){const n=rt(t);return q.fromCommands(n)}}class Lt extends q{constructor(t){super(t);C(this,"curves");this.curves=t}}function cn(o){const e=o.curves.map(t=>bt(t));return new Lt(e)}class an{constructor(e){C(this,"points");C(this,"bbox");this.points=e,this.bbox={xMin:1/0,xMax:-1/0,yMin:1/0,yMax:-1/0};for(let t of this.points)this.bbox.xMin=Math.min(this.bbox.xMin,t[0]),this.bbox.xMax=Math.max(this.bbox.xMax,t[0]),this.bbox.yMin=Math.min(this.bbox.yMin,t[1]),this.bbox.yMax=Math.max(this.bbox.yMax,t[1])}getArea(){return Math.abs(this.getSignArea())}getSignArea(){return ct(this.points)}getCentroid(){let e=this.getSignArea(),t=0,n=0;for(let i=0;i<this.points.length;i++){let[s,r]=this.points[i],[c,a]=this.points[(i+1)%this.points.length];t+=(s+c)*(s*a-c*r),n+=(r+a)*(s*a-c*r)}return[t/6/e,n/6/e]}includePoint(e){return e[0]<this.bbox.xMin||e[0]>this.bbox.xMax||e[1]<this.bbox.yMin||e[1]>this.bbox.yMax?!1:at(e,this.points)}includePolygon(e){if(e.bbox.xMin<this.bbox.xMin||e.bbox.xMax>this.bbox.xMax||e.bbox.yMin<this.bbox.yMin||e.bbox.yMax>this.bbox.yMax)return!1;for(let t of e.points)if(!this.includePoint(t))return!1;return!0}intersectPolygon(e){for(let t of e.points)if(this.includePoint(t))return!0;return!1}}function ct(o){let e=0;const{length:t}=o;for(let n=0;n<t;n++){let[i,s]=o[n],[r,c]=o[(n+1)%t];e+=i*c-r*s}return e/2}function hn(o,e){let[t,n]=o,[[i,s],[r,c]]=e;return(t-i)*(c-s)-(n-s)*(r-i)>0}function at(o,e){let[t,n]=o,i=!1;for(let s=0,r=e.length-1;s<e.length;r=s++){let[c,a]=e[s],[h,l]=e[r];a>n!=l>n&&t-c<(h-c)*(n-a)/(l-a)&&(i=!i)}return i}class Bt{constructor(e,t,n){C(this,"angle");this.point=e,this.inVec=t,this.outVec=n,this.angle=N(this.inVec,this.outVec)}}class H extends q{constructor(t){super(t);C(this,"nodes",[]);this.curves=t,this.initNodes()}initNodes(){let{curves:t}=this;const{length:n}=t;for(let i=0;i<n;i++){const s=t[i],r=t[(i-1+n)%n],c=s.SPoint;this.nodes[i]=new Bt(c,r.ouDir,s.inDir)}this.curves=t,this.initPoints()}includePoint(t){const{xMin:n,xMax:i,yMin:s,yMax:r}=this.bounds;return t[0]<n||t[0]>i||t[1]<s||t[1]>r?!1:at(t,this.points)}splitInAngle(t=60){t*=Math.PI/180;const{curves:n,nodes:i}=this,{length:s}=n,r=[];let c=[],a=n[0];for(let l=0;l<s;l++){const u=n[l],{angle:P}=i[l];P>t||a.type!==u.type?(c.length&&r.push(c),c=[u]):c.push(u),a=u}if(c.length){const{angle:l}=i[0];l<=t&&r.length?r[0]=c.concat(r[0]):r.push(c)}return r.map(l=>new q(l))}static fromCommands(t){const{length:n}=t;(t[0].type!=="M"||t[n-1].type!=="Z")&&console.error("ClosedShape must start with M and end with Z");const i=super.fromCommands(t);return new H(i.curves)}}function ln(o,e,t){return Math.abs(ht(o,e,t))}function ht(o,e,t){return(e[0]-o[0])*(t[1]-o[1])-(t[0]-o[0])*(e[1]-o[1])/2}function un(o,e,t){const n=E(o,e),i=E(e,t),s=E(t,o),r=(n+i+s)/2;return n*i*s/4/Math.sqrt(r*(r-n)*(r-i)*(r-s))}function Tt(o,e,t){const n=E(o,e),i=E(e,t),s=E(t,o);return ht(o,e,t)/(n*i*s)}function It(o){return new Array(o).fill(0).map(()=>new Array(o))}function fn(o){return o.map(e=>e.slice())}function Pn(o){return Math.max(...o)}function dn(o){return Math.min(...o)}function $(o){return o.reduce((e,t)=>e+t,0)}function et(o){return $(o)/o.length}function pn(o){return et(o),Math.sqrt(Ft(o))}function Ft(o){const e=et(o);return et(o.map(t=>Math.pow(t-e,2)))}function gn(o){const e=o.slice().sort((n,i)=>n-i),t=Math.floor(o.length/2);return o.length%2!==0?e[t]:(e[t-1]+e[t])/2}function kt(o,e){const t=o.length,n=$(o),i=$(e),s=i/t,r=$(o.map((d,g)=>d*e[g])),c=$(o.map(d=>d*d)),a=1e-10;if(t*c-n*n<a)return{k:1/0,b:n/t,R2:1};const h=(t*r-n*i)/(t*c-n*n),l=(i-h*n)/t,u=Math.max(a,$(e.map(d=>Math.pow(d-s,2)))),p=Math.max(a,$(o.map(d=>Math.pow(h*d+l-s,2))))/u;return{k:h,b:l,R2:p}}const Rt=1103515245,Vt=12345,lt=2147483647;function _t(o=.314){let e=(Rt*o+Vt)%lt;return()=>(e=(Rt*e+Vt)%lt,e/lt)}function yn(o){return Math.pow(2,-10*o)*Math.sin((o-.2/4)*(2*Math.PI)/.2)+1}function xn(o){return o<.5?.5*Math.pow(2,20*o-10)*Math.sin((20*o-11.125)*(2*Math.PI)/.9):.5*(2-Math.pow(2,-20*o+10)*Math.sin((20*o-11.125)*(2*Math.PI)/.9))}function mn(o,e=4){return Math.max(e-Math.floor(Math.log10(o)),0)}function Mn(o){if(o.length<=1)return o;const e=new Map,t=new Map;for(const s of o){if(s.length<2)throw new Error("couple length must be greater than 1");const[r,c]=[s[0],s[s.length-1]];e.set(r,c),t.set(c,r)}const n=[];let i=o.length**2;for(;(e.size||t.size)&&i-- >0;){let s=e.keys().next().value;const r=[s];let c=e.get(s);for(;c!==void 0&&c!==s&&i-- >0;)r.push(c),e.delete(s),t.delete(c),s=c,c=e.get(c);for(s=r[0],c=t.get(s);c!==void 0&&c!==s&&i-- >0;)r.unshift(c),e.delete(c),t.delete(s),s=c,c=t.get(c);n.push(r)}return n}class O extends q{constructor(t){super(t);C(this,"curves");this.curves=t}static fromPoints(t){let n=[];for(let i=0;i<t.length-1;i++)n.push(new I(t[i],t[i+1]));return new O(n)}getDistance(t){let n=1/0;for(let i of this.points)n=Math.min(n,X(i,t));return n}getClosestPoint(t){let n=1/0,i=y();for(let s of this.points){let r=X(s,t);r<n&&(n=r,i=s)}return i}split(t=100){const{points:n}=this,i=vn(n,t),s=qt(n,i);let r=[];return s.forEach(c=>{const a=Cn(c),h=qt(c,a);r.push(...h)}),r.filter(c=>c.length>=2).map(c=>O.fromPoints(c))}}function Cn(o,e=[2,4,8,16,32]){const{length:t}=o;let n=0,i=0,s=new Set;for(let a=0;a<e.length;a++){const h=e[a];if(t<2*h)break;for(let l=h;l<t-h;l++){const u=o[l-h],P=o[l],p=o[l+h],d=R(y(),P,u),g=R(y(),p,P),x=Math.max(N(d,g)*180/Math.PI,0);n<x&&(n=x,i=l),x>120&&s.add(l)}}const r=Array.from(s).sort((a,h)=>a-h);return r.length<=1?r:[i]}function vn(o,e=100){const{length:t}=o,n=new Array(t-2);for(let s=1;s<t-1;s++){const r=o[s-1],c=o[s],a=o[s+1];n[s-1]=Tt(r,c,a)}const i=[];for(let s=1;s<n.length-1;s++){const[r,c,a]=[n[s-1],n[s],n[s+1]];Math.abs(c)<Math.abs(r)&&Math.abs(c)<Math.abs(a)&&(c>1/e||c<-1/(2*e))&&i.push(s+1)}return i}function qt(o,e){const{length:t}=e,n=new Array(t+1);let i=0;for(let s=0;s<t;s++){const r=e[s],c=o.slice(i,r+1);n[s]=c,i=r}return i<o.length&&(n[t]=o.slice(i)),n}function ut(o,e){const{points:t}=o,{points:n}=e,{length:i}=t,{length:s}=n,r={datas:[],min:1/0,max:1/0,mean:1/0,std:1/0};if(!(o.isClosed||e.isClosed)){const p=new I(o.EPoint,e.SPoint),d=new I(e.EPoint,o.SPoint);if(Ct(p,d))return[r,r]}const a=[...t,...n];if(!it(a))return[r,r];const l=new Array(i).fill({dis:1/0,index:-1}),u=new Array(s).fill({dis:1/0,index:-1});for(let p=0;p<i;p++)for(let d=0;d<s;d++){const g=X(t[p],n[d]);g<l[p].dis&&(l[p]={dis:g,index:d}),g<u[d].dis&&(u[d]={dis:g,index:p})}return[l,u].map(p=>{const d=p.map(({dis:m})=>m),g=Math.min(...d),x=Math.max(...d),M=d.reduce((m,b)=>m+b,0)/d.length,v=Math.sqrt(d.map(m=>Math.pow(m-M,2)).reduce((m,b)=>m+b,0)/d.length);return{datas:p,min:g,max:x,mean:M,std:v}})}function Sn(o){const{points:e,bounds:t}=o,n=Math.min(e.length,5),i=e.slice(-n),s=i.map(([l])=>l),r=i.map(([,l])=>l),{k:c,b:a,R2:h}=kt(s,r);return{k:c,b:a,R2:h}}function ft(o,e){return Math.exp(-(o-1)/e)}function st(o,e){return Math.max(1-o/e,0)}function bn(o,e,t=30){if(o.isClosed||e.isClosed)return 0;const{EPoint:n,outDir:i}=o,{SPoint:s,inDir:r}=e,c=R(y(),s,n),a=mt(c),h=ft(a,100);let l=0;if(a<1){const P=N(i,r)*180/Math.PI;l=st(P,t)}else{const P=N(c,i)*180/Math.PI,p=N(c,r)*180/Math.PI;l=st(P,t)*st(p,t)}return h*l}function wn(o,e){const t=X(o.EPoint,e.SPoint)<.001,n=[...o.points,...e.points.slice(t?1:0)];return O.fromPoints(n)}class $t extends O{constructor(e){super(e)}}function En(o,e=100,t=1e3){console.time("getRailCouples");const{length:n}=o,i=It(n);for(let a=0;a<n;a++)for(let h=a+1;h<n;h++){const[l,u]=ut(o[a],o[h]);i[a][h]=l,i[h][a]=u}const s=new Array(n);for(let a=0;a<n;a++){o[a];let h=-1/0,l=-1;for(let u=0;u<n;u++){if(a===u)continue;const{std:P,min:p,mean:d,max:g}=i[a][u],x=P>1e10?0:(.9-P/t)*ft(d,e);x>h&&(h=x,l=u)}s[a]=l}const r=new Set;for(let a=0;a<s.length;a++)r.has(a)||s[s[a]]===a&&(r.add(a),r.add(s[a]));const c=r.size>>1;new Array(c);for(let a=0;a<s.length;a++)r.has(a)||console.log("配对不成功",a);return console.timeEnd("getRailCouples"),{successIndex:r,minStdIndexArr:s}}function Dn(o,e=1){const t=o.len,n=Math.ceil(t/e),i=o.toPoints(n);return $t.fromPoints(i)}class An{constructor(e,t){C(this,"rail0");C(this,"rail1");this.rail0=e,this.rail1=t}createRungs(e){var v;const{rail0:t,rail1:n}=this;this.checkDirection();const i=t.len,s=n.len,{length:r,width:c}=e,[a,h]=ut(t,n);let[l,u,P,p]=[i,a,t,n];i>s||(l=s,P=n,p=t,u=h),P.isClosed;const g=p.isClosed?(((v=u.datas[0])==null?void 0:v.index)||0)/p.curves.length:0,x=Math.floor(l/c),M=new Array(x);for(let m=0;m<x;m+=1){const b=m/x,{pos:L}=P.getPosDataByPer(b,!0),{pos:w}=p.getPosDataByPer(b+g,!0),k=new I(L,w);M[m]=k}return M}checkDirection(){const{rail0:e,rail1:t}=this;it(e.points),it(t.points),t.reverse()}}function it(o){return ct(o)>0}class Ln{constructor(e,t,n=.3,i=Math.SQRT2){C(this,"length");C(this,"width");this.minRatio=n,this.maxRatio=i,this.length=e,this.width=t}fillLine(e,t){const{length:n}=this,i=R(y(),t,e),s=mt(i);if(s<this.minRatio*n)return[];const r=[e];let c=Math.floor(s/n);const a=yt(y(),i,n/s);for(let u=1;u<c;u++){const P=J(y(),e,a,u);r.push(P)}const h=s/n%1;if(!(h+1<this.maxRatio)&&c>0){const u=(h+1)/2,P=J(y(),r[r.length-1]||e,a,u);r.push(P)}return r.push(t),r}}class Z{constructor(e,t="NONZERO"){this.shapes=e,this.windingRule=t}static fromCommands(e){const t=[];let n=[];for(const s of e)s.type==="M"?(n.length>0&&t.push(n),n=[s]):n.push(s);n.length>0&&t.push(n);const i=t.map(s=>H.fromCommands(s));return new Z(i)}static fromPathString(e){const t=rt(e);return Z.fromCommands(t)}getBBox2(e=B()){for(const t of this.shapes)t.getBBox2(e);return e}includePoint(e){let t=!0;for(const n of this.shapes){const{isClockwise:i}=n,s=n.includePoint(e);if(t&&(t=i?!s:s),!t)return!1}return t}applyFn(e){for(const t of this.shapes)for(const n of t.curves)n.applyFn(e)}applyFFDFn(e){for(const t of this.shapes)for(const n of t.curves)n.applyFFDFn(e)}intersectLine(e){let t=[];for(const n of this.shapes)t=t.concat(n.getLineIntersects(e));return t}split(){const{shapes:e}=this,t=[];for(let i=0;i<e.length;i++){const s=e[i],{bounds:r,isClockwise:c}=s;if(!c)t.push([s]);else{const a=t.find(h=>{const l=h[0].bounds;return l.xMin<=r.xMin&&l.xMax>=r.xMax&&l.yMin<=r.yMin&&l.yMax>=r.yMax});a?a.push(s):console.error("can't find the path for the shape",s)}}return t.map(i=>new Z(i))}splitByCoord(e){for(const t of this.shapes)t.splitByCoord(e)}toPathString(e=0){let t="";for(const n of this.shapes)t+=n.toPathString(e)+" ";return t=t.slice(0,-1),t}toPoints(e){let t=[];for(const n of this.shapes)t=t.concat(n.toPoints(e));return t}clone(){const e=this.shapes.map(t=>{const n=t.curves.map(i=>i.clone());return new H(n)});return new Z(e,this.windingRule)}}const Bn=[1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800],Pt=o=>Bn[o],Tn=(o,e)=>Pt(o)/(Pt(e)*Pt(o-e)),zt=(o,e,t)=>Tn(e,o)*t**o*(1-t)**(e-o),Nt=(o,e=0,t=1)=>Math.min(Math.max(o,e),t);function In(o,e,t=!0){return t?n=>{const[i,s]=n,r=e.length-1,c=e[0].length-1;let a=(i-o.x)/o.width,h=(s-o.y)/o.height,l=0,u=y();for(let P=0;P<=r;P++){const p=zt(P,r,a);for(let d=0;d<=c;d++){const g=zt(d,c,h),x=p*g;l+=x,J(u,u,e[P][d],x)}}yt(u,u,1/l),Xt(n,u)}:n=>{const[i,s]=n,r=e.length-1,c=e[0].length-1;let a=Nt((i-o.x)/o.width),h=Nt((s-o.y)/o.height);a=a*r,h=h*c;const l=Math.floor(a),u=Math.floor(h);a=a-l,h=h-u;const P=e[l][u],p=e[l+1][u],d=e[l][u+1],g=e[l+1][u+1],x=(1-a)*(1-h)*P[0]+a*(1-h)*p[0]+(1-a)*h*d[0]+a*h*g[0],M=(1-a)*(1-h)*P[1]+a*(1-h)*p[1]+(1-a)*h*d[1]+a*h*g[1];return n[0]=x,n[1]=M,n}}function Fn(o,e){const{length:t}=o;if(e<1)throw new Error("degree must be at least 1 (linear)");if(e>t-1)throw new Error(`degree:${e} must be less than or equal to point count - 1(${t-1})`);const n=new Array(t),i=new Array(t);for(let s=0;s<t;s++)n[s]=o[s][0],i[s]=o[s][1];return s=>{if(s<0||s>1)throw new Error("out of bounds");s=s*t+e;const r=jt(n,e,s),c=jt(i,e,s);return S(r,c)}}function jt(o,e,t){const{length:n}=o,i=n+e,s=Math.floor(t),r=new Array(i);for(let c=0;c<i;c++)r[c]=o[c%n];for(let c=0;c<e;c++)for(let a=s;a>s-e+c;a--){const h=(t-a)/(e-c);r[a]=h*r[a]+(1-h)*r[a-1]}return r[s]}function Qt(o,e,t,n=0,i=0,s=.1){const r=[],c=o/2,a=e/2,h=_t(s);let l=u=>{const p=h()*n+(1-n);let d=(p*Math.cos(u)+1)*c,g=(p*Math.sin(u)+1)*a;return S(d,g)};for(let u=0;u<t;u++){let P=l(2*Math.PI*(u/t+i));r.push(P)}return r}function Ot(o){let e=1/0,t=1/0,n=-1/0,i=-1/0;for(const s of o){const{bbox:r}=s;e=Math.min(e,r.x),t=Math.min(t,r.y),n=Math.max(n,r.x+r.width),i=Math.max(i,r.y+r.height)}return{x:e,y:t,width:n-e,height:i-t}}function Zt(o,e){const t=Ot(o),n=e.width/t.width,i=e.height/t.height;for(const s of o)s.applyFn(r=>{r[0]=(r[0]-t.x)*n+e.x,r[1]=(r[1]-t.y)*i+e.y})}function Yt(o,e=3){const t=[],i=new Array(100),s=Fn(o,Number(e)),r=performance.now();for(let a=0;a<100;a++)i[a]=s(a/100);performance.now()-r;const c=new Array(100);for(let a=0;a<100;a++){const h=S(i[a][0],i[a][1]),l=S(i[(a+1)%100][0],i[(a+1)%100][1]),u=A(y(),h,l,.5);c[a]=u}for(let a=0;a<100;a++){const h=T(c[a]),l=c[(a+1)%100],u=i[(a+1)%100];t.push(new V(h,u,l))}return t}function kn(o=100,e=100,t=6,n=.5,i=Math.random(),s=3){const r=Qt(o,e,t,n,i),c=Yt(r,s);return Zt(c,{x:0,y:0,width:o,height:e}),At(c)}class dt{constructor(e){C(this,"value");C(this,"next",null);this.value=e}}class pt{constructor(){C(this,"head",null);C(this,"tail",null);C(this,"size",0)}static fromArray(e){const t=new pt;return e.forEach(n=>t.append(n)),t}toArray(){let e=this.head;const t=[];for(;e;)t.push(e.value),e=e.next;return t}append(e){const t=new dt(e);this.tail&&(this.tail.next=t),this.tail=t,this.head||(this.head=t),this.size++}prepend(e){const t=new dt(e);this.head&&(t.next=this.head),this.head=t,this.tail||(this.tail=t),this.size++}delete(e){var n;if(!this.head)return;for(;this.head&&this.head.value===e;)this.head=this.head.next,this.size--;let t=this.head;for(;t&&t.next;)t.next.value===e?(t.next=t.next.next,this.size--):t=t.next;((n=this.tail)==null?void 0:n.value)===e&&(this.tail=t)}find(e){let t=this.head;for(;t;){if(t.value===e)return t;t=t.next}return null}toString(){let e=this.head;const t=[];for(;e;)t.push(e.value),e=e.next;return t.join(" -> ")}getSize(){return this.size}clear(){this.head=null,this.tail=null,this.size=0}}f.BezierCurve=_,f.BezierCurveType=St,f.BezierShape=Lt,f.ClosedShape=H,f.Curve=Mt,f.LineCurve=I,f.LineCurveType=tt,f.LineToQuadratic=nn,f.LinkedList=pt,f.Node=dt,f.Path=Z,f.PointNode=Bt,f.Polygon=an,f.Polyline=O,f.QuadraticCurve=V,f.QuadraticCurveType=vt,f.Rail=An,f.Shape=Dt,f.SingleRail=$t,f.SingleShape=q,f.Stitch=Ln,f.calDisData=ut,f.calExtendCurve=Sn,f.calPointsArea=ct,f.calRadius=un,f.checkLineCurveIntersect=Ct,f.connectPolyline=wn,f.copyMatrix=fn,f.createBBox2=B,f.createMatrix=It,f.createSingleRailFromSingleShape=Dn,f.createSvgByPath=sn,f.gaussElimination=tn,f.getAngleMark=st,f.getBezierCurvesBBox=Ot,f.getBezierFromCurve=bt,f.getBezierShapeFormSingleShape=cn,f.getConnectMark=bn,f.getCurvature=Tt,f.getCurvesByPolygon=Yt,f.getDebugPathStr=on,f.getDigit=mn,f.getDistMark=ft,f.getEaseElasticInOut=xn,f.getEaseElasticOut=yn,f.getPathStr=At,f.getPointsClockwise=it,f.getPolygon=Qt,f.getRailCouples=En,f.getRandomGenerate=_t,f.getRandomPathStr=kn,f.getRoots=F,f.getTriangleArea=ln,f.getTriangleSignArea=ht,f.interpolatePolygon=rn,f.isInLeft=hn,f.isPointInPoints=at,f.lineInterSect=j,f.lineToBezier=wt,f.linearRegression=kt,f.max=Pn,f.mean=et,f.median=gn,f.mergeCouple=Mn,f.min=dn,f.pathStringToPathCommands=rt,f.quadraticToBezier=Et,f.resizeCurvesByBBox=Zt,f.simplyCurves=en,f.std=pn,f.sum=$,f.transformPoint=In,f.variance=Ft,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})}); |
{ | ||
"name": "geo-2d", | ||
"version": "1.0.0-beta.16", | ||
"version": "1.0.0-beta.17", | ||
"type": "module", | ||
@@ -12,3 +12,6 @@ "files": [ | ||
".": { | ||
"import": "./dist/geometry.es.js", | ||
"import": { | ||
"types": "./src/index.ts", | ||
"default": "./dist/geometry.es.js" | ||
}, | ||
"require": "./dist/geometry.umd.js" | ||
@@ -34,3 +37,3 @@ }, | ||
"preview": "vite preview", | ||
"publish": "vite build --mode lib && npm publish", | ||
"publish:geo": "vite build --mode lib && npm publish", | ||
"test": "vitest", | ||
@@ -56,3 +59,3 @@ "coverage": "vitest run --coverage" | ||
"type": "git", | ||
"url": "https://github.com/quarksb/geo-2d" | ||
"url": "https://github.com/quarksb/geo-2d.git" | ||
}, | ||
@@ -59,0 +62,0 @@ "publishConfig": { |
Sorry, the diff of this file is too big to display
143694
44
3592