memoscan
← all memos

Memo 0x5158ae5f…5dd3cd on Ethereum

///7 function delaunayTriangulate(e){let r,l,n,t,i,u,h,c,s,g,p,f,o=e.length;if(o<3)return[];for(e=e.slice(0),c=new Array(o),r=o;r--;)c[r]=r;c.sort((function(r,l){let n=e[l].x-e[r].x;return 0!==n?n:r-l})),s=supertriangle(e),e.push(s[0],s[1],s[2]),g=[];let a=circumcircle(e,o+0,o+1,o+2);for(a&&(g=[a]),p=[],f=[],r=c.length;r--;f.length=0){for(h=c[r],l=g.length;l--;)n=e[h].x-g[l].x,n>0&&n*n>g[l].r?(p.push(g[l]),g.splice(l,1)):(t=e[h].y-g[l].y,n*n+t*t-g[l].r>IMPL_DLNY_EPS||(f.push(g[l].i,g[l].j,g[l].j,g[l].k,g[l].k,g[l].i),g.splice(l,1)));for(dedup(f),l=f.length;l;)u=f[--l],i=f[--l],a=circumcircle(e,i,u,h),a&&g.push(a)}for(r=g.length;r--;)p.push(g[r]);for(g.length=0,r=p.length;r--;)p[r].i<o&&p[r].j<o&&p[r].k<o&&g.push(p[r].i,p[r].j,p[r].k);return dlnyTris=g,g} function dedup(e){for(let l=e.length;l;){let t=e[--l],f=e[--l];for(let i=l;i;){let c=e[--i],n=e[--i];if(f===n&&t===c||f===c&&t===n){e.splice(l,2),e.splice(i,2);break}}}} function circumcircle(L,P,_,r){let t,M,c,e,i,a,n,u,x=L[P].x,y=L[P].y,D=L[_].x,E=L[_].y,I=L[r].x,N=L[r].y,S=Math.abs(y-E),Y=Math.abs(E-N);if(S<IMPL_DLNY_EPS&&Y<IMPL_DLNY_EPS)return;S<IMPL_DLNY_EPS?(e=-(I-D)/(N-E),a=(D+I)/2,u=(E+N)/2,t=(D+x)/2,M=e*(t-a)+u):Y<IMPL_DLNY_EPS?(c=-(D-x)/(E-y),i=(x+D)/2,n=(y+E)/2,t=(I+D)/2,M=c*(t-i)+n):(c=-(D-x)/(E-y),e=-(I-D)/(N-E),i=(x+D)/2,a=(D+I)/2,n=(y+E)/2,u=(E+N)/2,t=(c*i-e*a+u-n)/(c-e),M=S>Y?c*(t-i)+n:e*(t-a)+u);let l=D-t,b=E-M;return{i:P,j:_,k:r,x:t,y:M,r:l*l+b*b}} function supertriangle(t){let e=PINF,N=PINF,l=NINF,n=NINF;for(let r=t.length;r--;)t[r].x<e&&(e=t[r].x),t[r].x>l&&(l=t[r].x),t[r].y<N&&(N=t[r].y),t[r].y>n&&(n=t[r].y);let r=l-e,x=n-N,y=Math.max(r,x),F=e+.5*r,I=N+.5*x;return[CV(F-20*y,I-y),CV(F,I+20*y),CV(F+20*y,I-y)]} function initImplicitSpringPairings_2(){springPairings=[];let i=T,s=T,n=T;if(i)for(let i=0;i<nSpineSites-1;i++)springPairings.push([i,i+1]);if(s){let i,s;for(let n=0;n<uniqDlnyEs.length;n++){i=uniqDlnyEs[n][0],s=uniqDlnyEs[n][1];let e=F;for(let n=0;n<springPairings.length;n++)springPairings[n][0]===i&&springPairings[n][1]===s&&(e=T);e||(s>i?springPairings.push([i,s]):springPairings.push([s,i]))}}if(n)for(let i=0;i<1;i++)for(let i=0;i<sitePVecs.length;i++){let s=-1,n=PINF;for(let e=i+1;e<sitePVecs.length;e++){let t=F;for(let s=0;s<uniqDlnyEs.length;s++){let n=uniqDlnyEs[s][0],r=uniqDlnyEs[s][1];n==i&&r==e&&(t=T)}if(!t){let t=sitePVecs[i].x-sitePVecs[e].x,r=sitePVecs[i].y-sitePVecs[e].y,l=sqrt(t*t+r*r);l<n&&(n=l,s=e)}}s>0&&n<closenessThreshForSprings&&springPairings.push([i,s])}} function initImplicitSpringPairings_Radial(){springPairings=[];for(let i=0;i<uniqDlnyEs.length;i++){let n=uniqDlnyEs[i][0],s=uniqDlnyEs[i][1],g=F;for(let i=0;i<springPairings.length;i++)springPairings[i][0]===n&&springPairings[i][1]===s&&(g=T);g||(s>n?springPairings.push([n,s]):springPairings.push([s,n]))}} function initImplicitSiteParticles_3(t,s){bDisableSiteWarping&&(t=s=F),resetRnd(CHASH);for(let a=0;a<sitePVecs.length;a++){let e=sitePVecs[a].x,i=sitePVecs[a].y;if(s){let t=e-.5,s=i-.5,a=Math.sqrt(t*t+s*s),n=Math.atan2(s,t);n+=twist*(1-min(a/.5,1)),a<.5&&(a=.5*pow(a/.5,bloat+.5)),e=.5+a*cos(n),i=.5+a*sin(n)}t&&(bendx>0?e+=(1-e)*bendx*sin(PI*i):e=1-e+(1-e)*bendx*sin(PI*i),bendy>0?i+=(1-i)*bendy*sin(PI*e):i=1-i+(1-i)*bendy*sin(PI*e));let n,m=map(e,0,1,X0,X1),o=map(i,0,1,Y0,Y1);n=new Particle,n.bIsABoundarySite=F,n.set(m,o),n.setBConstrainToMask(F),n.damping=blobContourDamping+.05*myRAB(-1,1),n.mass=Cs(myRGauss(1,max(.001,StSh.massRandomness)),.75,1.25),n.mass*=map(Math.abs(e-.5),0,.5,1,1.3),a==centralSiteId&&(n.mass=1);let b=sitePVecs[a].z;n.bContributesToImplicitBlob=b>0,sitePs.push(n)}} function initImplicitSiteParticles_Radial(){let t=1,e=1;StSh.radialSiteMassDirection?(t=1,e=.5):(t=.5,e=1);let s=0;for(let t=0;t<sitePVecs.length;t++){let e=sitePVecs[t].x,i=sitePVecs[t].y,a=2*dist(e,i,.5,.5);a>s&&(s=a)}let i=1+StSh.nRdR*StSh.nRadialArms;for(let a=0;a<sitePVecs.length;a++){let l=sitePVecs[a].x,n=sitePVecs[a].y;bendx>0?l+=(1-l)*bendx*sin(PI*n):l=1-l+(1-l)*bendx*sin(PI*n),bendy>0?n+=(1-n)*bendy*sin(PI*l):n=1-n+(1-n)*bendy*sin(PI*l);let S,P=map(l,0,1,X0,X1),c=map(n,0,1,Y0,Y1);sitePVecs[a].x=l,sitePVecs[a].y=n,S=new Particle,S.set(P,c),S.damping=blobContourDamping+.05*myRAB(-1,1);let h=2*dist(l,n,.5,.5)/s;h=pow(h,StSh.radialSiteDistFracPow),S.mass=map(h,0,1,t,e),a==centralSiteId&&(S.mass=2,StSh.radialSiteMassDirection||(S.mass+=3/StSh.nRadialArms)),StSh.bMakeBulbous&&a<i&&(a-1)%StSh.nRadialArms==0&&(a-1)/StSh.nRadialArms==StSh.nRdR-2&&(S.mass*=myRAB(2.5,3.5));let d=sitePVecs[a].z;S.bContributesToImplicitBlob=d>0,sitePs.push(S)}if(sitePVecs.length>0){let t=0;for(let e=0;e<sitePVecs.length;e++)t+=sitePs[e].mass;if(t/=sitePVecs.length,t<1)for(let e=0;e<sitePVecs.length;e++)sitePs[e].mass+=1-t}} function initImplicitSiteSprings_4(){for(let i=0;i<springPairings.length;i++){let s=springPairings[i][0],n=springPairings[i][1],t=sitePs[s].p,e=sitePs[n].p,r=dist(t.x,t.y,e.x,e.y),g=blobContourSpringK,p=new Spring(sitePs);p.setParticleIndicesAndRestLength(s,n,r,g),siteSprings.push(p)}} function identifyImplicitSpecialSites(){niceSiteIds=[];for(let e=0;e<uniqDlnyEs.length;e++){let i=uniqDlnyEs[e],s=i[0],t=i[1],c=sitePVecs[s],l=sitePVecs[t];if(sitePVecs[s].z>0){let e=T,i=T;for(let n=0;n<sitePVecs.length;n++)if(n!=s&&n!=t){let s=sitePVecs[n],t=(l.x-c.x)*(s.y-c.y)-(l.y-c.y)*(s.x-c.x);abs(t)<.002||(t>0&&(i=F),t<0&&(e=F))}(i||e)&&(niceSiteIds.includes(s)||niceSiteIds.push(s))}}} function regularizeImplicitConfiguration(){resetRnd(CHASH);for(let e=0;e<sitePs.length;e++){sitePs[e].bContributesToImplicitBlob&&0}let e=BDM/2,t=BDM/2;rawBlobPVectorArrayContainer=imper.getBlobContFromPArr(sitePs);let s=PINF,l=NINF,i=PINF,o=NINF,n=rawBlobPVectorArrayContainer.points;for(let e=0;e<n.length;e++){let t=n[e];t.x<s&&(s=t.x),t.x>l&&(l=t.x),t.y<i&&(i=t.y),t.y>o&&(o=t.y)}let r=(s+l)/2,a=(i+o)/2,p=0,P=0,m=0;for(let e=0;e<sitePs.length;e++){let t=sitePs[e].mass;m+=t,p+=t*sitePs[e].p.x,P+=t*sitePs[e].p.y}p/=m,P/=m;let y=0,B=0,c=new ofPolyline;c.setPointsFromBlobContour(rawBlobPVectorArrayContainer),resampledBlobPolyline=c.getRsmpByNum(240);for(let e=0;e<resampledBlobPolyline.points.length;e++)y+=resampledBlobPolyline.points[e].x,B+=resampledBlobPolyline.points[e].y;y/=resampledBlobPolyline.points.length,B/=resampledBlobPolyline.points.length;let C=(r+y+p+e)/4,g=(a+B+P+t)/4,h=sitePs[centralSiteId].p.x,b=sitePs[centralSiteId].p.y,I=CX-h,f=CY-b;for(let e=0;e<sitePs.length;e++){let t=sitePs[e].p.x,s=sitePs[e].p.y;t+=I,s+=f,sitePs[e].set(t,s)}C+=I,g+=f;let u=CX-C,A=CY-g;for(let e=0;e<sitePs.length;e++){let t=sitePs[e].p.x,s=sitePs[e].p.y;t+=u,s+=A,sitePs[e].set(t,s)}CX+=u,CY+=A;let S=1,M=(l-s)/BDM,d=(o-i)/BDM,x=M>d?M:d,N=M>d?d:M;if(x<.666||x>.72){S=Cs(x,.666,.72)/x,S>1&&N<.55&&(S+=.01),S=Cs(S,.85,1.125)}if(S*=StSh.ORG_SCALE_FACTOR,1!=S){for(let e=0;e<sitePs.length;e++){let t=sitePs[e].p.x,s=sitePs[e].p.y,l=t-CX,i=s-CY;t=CX+l*S,s=CY+i*S,sitePs[e].set(t,s)}for(let e=0;e<siteSprings.length;e++){let t=siteSprings[e].getRestL();t*=S,siteSprings[e].setRestL(t),siteSprings[e].setBaseL(t)}imper=new ImplicitBlobmaker(255*S)}if(prevZeroLocation.set(sitePs[0].p.x,sitePs[0].p.y),T){const e=StSh.nMemLayers;let t=max(0,e-3);const s=.297,l=.32;let i=.8;imper.setBaseThresh(i),calculateNumberOfMaskPoints(),calculateImplicitContour(nMaskPoints);let o=pArea(resampNoiBlobPolyl.points),n=sqrt(abs(o)/PI)/BDM;if(n<s){if(T&&t>0){i-=.05*t,i=Cs(i,.01,.99),imper.setBaseThresh(i)}}else if(n>l){let e=0;const s=map(t,0,4,0,1);let o=s*n+(1-s)*l;for(;n>o&&i<.99&&e<100;){imper.setBaseThresh(i),calculateImplicitContour(nMaskPoints);let t=pArea(resampNoiBlobPolyl.points);n=sqrt(abs(t)/PI)/BDM,i+=.01,e++}}let r=0;207==SHMA?r=myRAB(.2,.25):205==SHMA?r=myRAB(.1,.15):202==SHMA&&(r=myRAB(.07,.11)),0!=r&&(i=max(.01,i-r),imper.setBaseThresh(i),calculateImplicitContour(nMaskPoints))}} function regularizeImplicitConfigurationRadial(){let e=.95;imper.setBaseThresh(e);let t=imper.getBlobContFromPArr(sitePs),s=t.points,l=0;for(let e=0;e<s.length;e++){let t=s[e],i=dist(t.x,t.y,BDM/2,BDM/2);i>l&&(l=i)}l/=X1-X0;let i=0;for(let e=0;e<sitePVecs.length;e++){let t=sitePVecs[e].x,s=sitePVecs[e].y,l=dist(t,s,.5,.5);l>i&&(i=l)}if(i>0){let r=l/i,o=0;for(;r<1&&e>.5&&o<100;){e-=.01,imper.setBaseThresh(e),t=imper.getBlobContFromPArr(sitePs),s=t.points,l=0;for(let e=0;e<s.length;e++){let t=s[e],i=dist(t.x,t.y,BDM/2,BDM/2);i>l&&(l=i)}l/=X1-X0,r=l/i,o++}}if(l>.62&&(e=1),bloat>2){e-=map(bloat,(minBloat+maxBloat)/2,maxBloat,0,.2)}imper.setBaseThresh(e),imper.setBaseThresh(e),t=imper.getBlobContFromPArr(sitePs),s=t.points;let r=1e5,o=-1e5;for(let e=0;e<s.length;e++){let t=s[e];t.x>o&&(o=t.x),t.x<r&&(r=t.x)}let a=(o-r)/width,n=a;a<.6?n=(a+.6)/2:a>.66&&(n=(a+.66)/2);let m=0;for(;m<26&&abs(a-n)>.01;){t=imper.getBlobContFromPArr(sitePs),s=t.points;let e=1e5,l=-1e5;for(let t=0;t<s.length;t++){let i=s[t];i.x>l&&(l=i.x),i.x<e&&(e=i.x)}if(a=(l-e)/width,a>n)for(let e=0;e<sitePs.length;e++)sitePs[e].mass-=.01;else if(a<n)for(let e=0;e<sitePs.length;e++)sitePs[e].mass+=.01;m++}prevZeroLocation.set(sitePs[0].p.x,sitePs[0].p.y)} function updateSitePhysics(){if(bEnableSpringPhysics)for(let e=1;e<=2;e++){let t=siteSprings.length;if(bApplyWaveToSpineRestLengths&&nSpineSites>0){let e=PI/(nSpineSites-1);for(let t=0;t<nSpineSites;t++){let s=siteSprings[t].getBaseL(),i=(t-centralSiteId)*e,n=StSh.siteWvA,a=StSh.siteWvS,l=fadeInPhysics*n*sin(i+myMillis/a);siteSprings[t].setRestL(s*(1+l))}}if(1==e)for(let e=0;e<t;e++)siteSprings[e].updatePass1();else if(2==e)for(let e=0;e<t;e++)siteSprings[e].updatePass2();if(CONT_MODE==CONT_MODE_IMPLICIT_RADIAL){let t=600,s=1.2,i=.2505;for(let n=0;n<radialTipIndices.length;n++){let a=147+3*n,l=377+3*n,p=radialTipIndices[n],r=fadeInPhysics*s*(noise(a+myMillis/t)-i),d=fadeInPhysics*s*(noise(l+myMillis/t)-i);sitePs[p].addF(r,d,e)}for(let t=0;t<sitePVecs.length;t++){let s=t,i=sitePVecs[t].x,n=sitePVecs[t].y,a=sitePs[t].p.x,l=sitePs[t].p.y,p=1;0==t&&(p=100);let r=p*(i-(a-X0)/(X1-X0)),d=p*(n-(l-Y0)/(Y1-Y0));sitePs[s].addF(r,d,e)}}if(bRestoreCenterSiteToCenter){let t=0,s=0,i=sitePs[centralSiteId],n=1==e?i.p0:i.pE,a=n.x,l=n.y,p=CX-a,r=CY-l;Math.sqrt(p*p+r*r)>1&&(t=.15*p*fadeInPhysics,s=.15*r*fadeInPhysics,sitePs[centralSiteId].addF(t,s,e))}if(bRestoreSpineToVertical&&nSpineSites>0){let t=0,s=nSpineSites-1,i=sitePs[t],n=sitePs[s],a=sitePs[centralSiteId],l=1==e?i.p0:i.pE,p=1==e?n.p0:n.pE,r=1==e?a.p0:a.pE,d=l.x-r.x,S=l.y-r.y,P=p.x-r.x,h=p.y-r.y,y=Math.sqrt(d*d+S*S),f=Math.sqrt(P*P+h*h);if(y>0&&f>0){let i=(l.x+p.x)/2,n=r.y-y,a=(l.x+p.x)/2,c=r.y+f,o=i-r.x,I=n-r.y,g=Math.sqrt(o*o+I*I),x=a-r.x,M=c-r.y,T=Math.sqrt(x*x+M*M),C=rotationalRestoreForce*fadeInPhysics,E=C*(d*I-S*o)/(g*y),u=C*(P*M-h*x)/(T*f),F=E*S/y*-1,R=E*d/y,b=u*h/f*-1,q=u*P/f;sitePs[t].addF(F,R,e),sitePs[s].addF(b,q,e)}}for(let t=0;t<sitePs.length;t++)sitePs[t].update(e)}} function calculateImplicitContour(o){rawBlobPVectorArrayContainer=imper.getBlobContFromPArr(sitePs);let e=new ofPolyline;if(e.setPointsFromBlobContour(rawBlobPVectorArrayContainer),e.points.length>1){let l;if(resampledBlobPolyline=e.getRsmpByNum(o),bAddNoiseToBlobPolyline&&StSh.edgeNoiseAmp>0){noiseDetail(3,.3);let e=fadeInPhysics*StSh.edgeNoiseAmp;l=getNoisyVersionOfBlobPolyline(resampledBlobPolyline,StSh.edgeNoiseScale,e).getRsmpByNum(o)}else l=resampledBlobPolyline;calculateContourZeroOffset(l),resampNoiBlobPolyl=new ofPolyline;const t=l.points.length;for(let o=0;o<t;o++){let e=(o+zeroOffsetIndex)%t,i=l.points[e].x,s=l.points[e].y;i=Cs(i,0,BDM-1),s=Cs(s,0,BDM-1),resampNoiBlobPolyl.add(i,s,0)}const i=resampNoiBlobPolyl.points.length,s=12;let n=F;for(let o=0;o<i;o++){let e=resampNoiBlobPolyl.points[o].x,l=resampNoiBlobPolyl.points[o].y,t=resampNoiBlobPolyl.points[(o+1)%i].x,r=resampNoiBlobPolyl.points[(o+1)%i].y,p=o+s;for(let s=o+2;s<p;s++){let o=s%i,p=(s+1)%i,a=resampNoiBlobPolyl.points[o].x,y=resampNoiBlobPolyl.points[o].y,m=resampNoiBlobPolyl.points[p].x,B=resampNoiBlobPolyl.points[p].y;if(checkIntersection(e,l,t,r,a,y,m,B)){n=T;break}}}n&&(StSh.edgeNoiseAmp*=.95)}} function calculateContourZeroOffset(e){const o=e.points.length;if(o>0){let t=PINF,n=0;for(let r=0;r<o;r++){let o=e.points[r],f=prevZeroLocation.x-o.x,s=prevZeroLocation.y-o.y,i=f*f+s*s;i<t&&(t=i,n=r)}zeroOffsetIndex=n,prevZeroLocation.set(e.points[zeroOffsetIndex].x,e.points[zeroOffsetIndex].y)}} function getNoisyVersionOfBlobPolyline(o,n,t){let i=new ofPolyline,e=o.points.length;for(let s=0;s<e;s++){let l=s==e-1?0:s+1,p=o.points[s].x,y=o.points[s].y,r=o.points[l].x-p,f=o.points[l].y-y,x=Math.sqrt(r*r+f*f),a=3e-4*myMillis,c=t*(noise(p/n,y/n,a)-.5),d=o.points[s].x+c*(f/x),g=o.points[s].y-c*(r/x);i.add(d,g)}return i.close(),i} //IMPLICIT class ImplicitPolygon{constructor(){this.points=[],this.failure=F,this.elapsed=0}addPoint(t,i){this.points.push(CV(t,i))}render(){let t=this.points.length;if(t>2){GFXP5.noFill(),GFXP5.stroke(0,0,0,60),GFXP5.strokeWeight(1),GFXP5.beginShape();for(let i=0;i<t;i++){let t=this.points[i].x,s=this.points[i].y;GFXP5.vertex(t,s)}GFXP5.endShape(CLOSE)}}} class ImplicitBlobmaker { constructor(radius){ this.cachedField=[]; this.siteArray=[]; this.squareSize=12; this.N_CONVERGE_ITERATIONS=StSh.impConvergeIterations; this.MAX_BOUNDARY_LENGTH=1600; this.cachedFieldGamma=StSh.cachedFieldGamma; this.R=~~radius; this.R2=(this.R*this.R); this.maxVal=1.; this.baseThreshold=(102./128.); this.threshHold=this.baseThreshold; this.initSqDims(6); this.makeField(this.R); this.mouseStrength=0; } setBaseThresh(h){this.baseThreshold=h,this.threshHold=this.baseThreshold} getBlobContFromPArr(t){this.siteArray=[];const e=t.length;for(let s=0;s<e;s++){if(t[s].bContributesToImplicitBlob){let e=t[s].p,i=t[s].mass;this.siteArray.push(CV(e.x,e.y,i))}}this.N_CONVERGE_ITERATIONS=StSh.impConvergeIterations;const s=122/128;this.mouseStrength=s*this.mouseStrength+.046875*(mouseIsPressed?1:0);const i=((mouseX/width-.5)/zScale+.5)*BDM,r=((mouseY/height-.5)/zScale+.5)*BDM;this.siteArray.push(CV(i,r,MOUSINFL*this.mouseStrength));let o=new ImplicitPolygon;if(this.siteArray.length>0){let t=this.siteArray[0],e=this.getSqWithPix(t.x,t.y);o=this.computeBoundaryRobust(e,5)} let b=o.points;let a=abs(pArea(b)),p=polygonPerimeter(b),c=p*p/(a*4*PI);if(c>1.3){MOUSINFL=0}return o} initSqDims(s){this.squareSize=s;} makeField(e){let t=2*e+1,a=e/2,i=e*e,c=i*i,h=c*i;noiseDetail(1,.6),this.cachedField=this.create2DArr(t,t);for(let l=0;l<t;l++)for(let d=0;d<t;d++){let t=e-d,s=e-l,o=t*t+s*s,r=o*o,n=0;o<=i&&(n=-.444444*(r*o)/h+1.888888*r/c+-2.444444*o/i+1,n=.98*n+.02*noise(d/a,l/a),n=Math.pow(n,this.cachedFieldGamma)),this.cachedField[l][d]=n*this.maxVal}} create2DArr(r,e){let n=new Array(r);for(let t=0;t<r;t++)n[t]=new Array(e);return n} getMaxAllowableSep(){let t=F,e=0;for(;e<2*this.R&&!t;){this.getFieldValueHalfwayGivenDistance(e)<this.threshHold&&(t=T),e++}return e-1} getFieldValueHalfwayGivenDistance(t){let e=t/2,i=0;if(e<=this.R){let t=~~(this.R+Math.round(e)),n=~~this.R;i=2*this.cachedField[n][t]}return i} getSqWithPix(t,e){return CV(~~(t/this.squareSize),~~(e/this.squareSize))} getFieldAtPix(t,e){let i,n,a,h,s,l=0;const r=this.siteArray.length;for(let u=0;u<r;u++)s=this.siteArray[u],i=t-s.x,n=e-s.y,i*i+n*n<this.R2&&(a=this.R+Math.round(i),h=this.R+Math.round(n),l+=this.cachedField[h][a]*s.z);return l} find1stSqWithEdge(e,t){let i,s,h,l=0,r=0,a=0,u=F;if(this.siteArray.length>0)for(;!u&&a<256;){if(i=e,s=t-a,h=this.evaluateSq(i,s),h>0){u=T,l=i,r=s;break}a++}return CV(l,r)} evaluateSq(e,t){let i=0,s=e*this.squareSize,h=t*this.squareSize,l=s+this.squareSize,r=h+this.squareSize;return this.getFieldAtPix(l,r)<this.threshHold&&(i|=1),this.getFieldAtPix(l,h)<this.threshHold&&(i|=2),this.getFieldAtPix(s,h)<this.threshHold&&(i|=4),this.getFieldAtPix(s,r)<this.threshHold&&(i|=8),i} converge(e,t,i,l,h){let s=0,n=0,o=0,r=0,u=0,V=0;const d=[i,e,i,e][h],g=[i,i,e,e][h],A=[l,t,l,l][h],a=[t,t,l,t][h];this.getFieldAtPix(d,A)<=this.getFieldAtPix(g,a)?(o=d,r=A,u=g,V=a):(o=g,r=a,u=d,V=A);for(let e=0;e<this.N_CONVERGE_ITERATIONS;e++)s=(o+u)/2,n=(r+V)/2,this.getFieldAtPix(s,n)>this.threshHold?(u=s,V=n):(o=s,r=n);return CV(s,n)} computeBoundaryRobust(t,e){let s=millis();this.threshHold=Math.min(1,Math.max(0,this.baseThreshold+StSh.impBaseThresholdBoost));let h=0,o=this.computeBoundary(t);for(;o.failure&&h<e;)this.threshHold-=.01,o=this.computeBoundary(t),h++;return T&&o.points.reverse(),o.elapsed=millis()-s,o} computeBoundary(t){let e,i,l=T,s=3,n=0;e=new ImplicitPolygon;const o=this.find1stSqWithEdge(~~t.x,~~t.y);let h=~~o.x,u=~~o.y;const r=h,a=u;let d=1;const c=[0,1,0,0,-1,-1,-1,-1,0,1,0,0,0,1,0,0],g=[0,0,-1,-1,0,0,0,0,1,0,-1,-1,1,0,1,0],x=[0,0,1,1,3,3,3,3,2,0,1,1,2,0,2,0],A=this.squareSize,p=this.threshHold,y=this.MAX_BOUNDARY_LENGTH;let P,V;do{P=u,V=h,n=0;const t=h*A,o=u*A,f=t+A,w=o+A;this.getFieldAtPix(f,w)<p&&(n+=1),this.getFieldAtPix(f,o)<p&&(n+=2),this.getFieldAtPix(t,o)<p&&(n+=4),this.getFieldAtPix(t,w)<p&&(n+=8),h+=c[n],u+=g[n],s=x[n],i=this.converge(t,o,f,w,s),d>y?(l=F,e.failure=T,print("FAILURE: blob with "+d)):(e.points.push(CV(i.x,i.y)),h==r&&u==a?l=F:d++)}while(l);return e} } function checkIntersection(n,t,c,r,e,o,i,s){const u=c-n,f=i-e,h=s-o,k=r-t,I=h*u-f*k;if(0===I)return F;const a=t-o,b=n-e,d=(f*a-h*b)/I;if(d<0||d>1)return F;const g=(u*a-k*b)/I;return g<0||g>1?F:T} //VSHADER class StyledPolylineRenderer { constructor(){ let pf=atob("cHJlY2lzaW9uIGxvd3AgZmxvYXQ7dm9pZCBtYWluKCl7Z2xfRnJhZ0NvbG9yID12ZWM0KDAuLDAuLDAuLDEuKTt9"); let pv="#define V2 vec2\n#define F float\n#define R return\n#define U uniform\nprecision highp float;attribute vec3 aPosition;U V2 resolution;U V2 noiseOffset;U V2 noiseFrequency;U F noiseAmplitude;U F noiseAsymmetry;U F noiseFalloff;U F thickness;U F nibAngle;U F nibStrength;U F zoom;F hash (V2 p){R 2.*fract(sin(dot(p,V2(12.9898,78.233)))*43758.5453)-1.;}F iqNoi(in V2 p){V2 i=floor(p);V2 f=fract(p);V2 u=f*f*(3.-2.*f);R mix(mix( hash(i+V2(0.,0.)),hash(i+V2(1.,0.)),u.x),mix(hash(i+V2(0.,1.)),hash(i+V2(1.,1.)),u.x),u.y);}F iqPerlinNoise6(in V2 p){V2 uv=p;mat2 m=mat2(1.6,1.2,-1.2,1.6);F ampl=noiseFalloff;F f=0.;for(int o=0;o<6;o++){f +=iqNoi(uv)*ampl;ampl*=noiseFalloff;uv=m*uv;}f=0.5+0.5*f;R f;}void main(){F px=zoom*((aPosition.x/resolution.x)* 2.-1.);F py=zoom*((aPosition.y/resolution.y)*-2.+1.);F orientation=aPosition.z;F assymmetry=noiseAsymmetry*orientation;vec2 noiPos=vec2(px,py+assymmetry)+noiseOffset;F noise=iqPerlinNoise6 (noiseFrequency*noiPos)-0.5;F th=zoom*thickness*(1.+noiseAmplitude*noise);F ns=nibStrength*0.5;th*=((1.-ns)+ns*cos(2.*(orientation+nibAngle)));px+=th*cos(orientation);py-=th*sin(orientation);gl_Position=vec4(px,py,0.,1.);}"; this.offBuf=CG(BDM,BDM,WEBGL);this.shPolyl=this.offBuf.createShader(pv,pf);this.aStyPolyl=new ofPolyline();} beginDraw(){this.offBuf.clear(),this.offBuf.background(255,255,255,255),this.offBuf.noStroke(),this.offBuf.shader(this.shPolyl),this.shPolyl.setUniform("resolution",[BDM,BDM]),this.shPolyl.setUniform("zoom",zScale)} drawStyledPolyline(s,t,i,l,o,e,h,n,f,y,r,m,P,S,a){this.aStyPolyl=s.getRsmpBySpc(r),S&&(this.aStyPolyl=this.aStyPolyl.getSmoothed(m)),this.offBuf.noStroke(),this.offBuf.fill(0,0,0),this.shPolyl.setUniform("thickness",t/BDM),this.shPolyl.setUniform("noiseOffset",i),this.shPolyl.setUniform("noiseFrequency",l),this.shPolyl.setUniform("noiseAmplitude",o),this.shPolyl.setUniform("noiseAsymmetry",e),this.shPolyl.setUniform("noiseFalloff",h),this.shPolyl.setUniform("nibAngle",n),this.shPolyl.setUniform("nibStrength",f),this.aStyPolyl.displayShaderTriangleStrip(this.offBuf,y)} } //POLYLINE class ofPolyline{ constructor(){ this.bClosed=F;this.dirty=T;this.perimeter=0; this.points=[];this.lengths=[]; this.bDidRsmp=F;this.bDidSmth=F;this.bDidNrm=F; this.resamped=null;this.smoothed=null; } clear(){this.dirty=T,this.bClosed=F,this.perimeter=0,this.points=null,this.lengths=null,this.points=[],this.lengths=[],this.bDidRsmp=F,this.bDidSmth=F,this.bDidNrm=F,this.resamped=null,this.smoothed=null} setFromStyledPolyline(t){let s=t.verts,i=s.length;for(let t=0;t<i;t++)this.add(s[t].x,s[t].y);t.bClosed&&this.close()} setPointsFromBlobContour(t){let s=t.points,i=s.length;for(let t=0;t<i;t++){let i=s[t];this.add(i.x,i.y)}this.close()} add(t,s,i=9){if(!this.bClosed){this.dirty=T,this.bDidRsmp=F,this.bDidSmth=F,this.bDidNrm=F;const h=this.points.length;let e=CV(t,s);if(0===h)this.points.push(e),this.lengths.push(0);else{let t=this.points[h-1],s=(t.x-e.x)*(t.x-e.x)+(t.y-e.y)*(t.y-e.y);if(s>i){this.points.push(e);let t=this.lengths[this.lengths.length-1];this.lengths.push(t+Math.sqrt(s))}}}} clickToClose(t,s){let i=F;if(!this.bClosed){const h=this.points.length;if(h>=3){const e=this.points[0].x,n=this.points[0].y;let o=e-t,l=n-s;if(sqrt(o*o+l*l)<30){let t=this.points[h-1];o=t.x-e,l=t.y-n;let s=sqrt(o*o+l*l),d=this.lengths[this.lengths.length-1];this.lengths.push(d+s),this.bClosed=T,this.dirty=T,i=T,this.bDidRsmp=F,this.bDidSmth=F,this.bDidNrm=F}}}return i} close(){if(!this.bClosed){const t=this.points.length;if(t>=3){let s=this.points[0],i=this.points[t-1],h=p5.Vector.dist(s,i),e=this.lengths[this.lengths.length-1];this.lengths.push(e+h),this.bClosed=T,this.dirty=T,this.bDidRsmp=F,this.bDidSmth=F,this.bDidNrm=F}}} displayShaderTriangleStrip(t,s){const i=this.points.length;if(i>1)if(this.bDidNrm){let s,h,e,n,o;for(t.beginShape(TRIANGLE_STRIP),s=0;s<i;s++)h=this.points[s],e=h.x,n=h.y,o=h.z,t.vertex(e,n,o-PI),t.vertex(e,n,o);t.endShape()}else{let h,e,n,o,l,d,p=0,r=this.bClosed?i+1:i-1,x=p,b=this.bClosed?(x-1+i)%i:0==x?0:x-1,g=this.bClosed?(x+1)%i:x+1,y=this.points[b],a=this.points[x],f=this.points[g],c=s[0],u=s[1];if(t.beginShape(TRIANGLE_STRIP),this.bClosed)for(e=p;e<r;e++)g=(x+1)%i,f=this.points[g],l=f.x-y.x,d=f.y-y.y,h=Math.atan2(d,l)+HALF_PI,n=a.x+c,o=a.y+u,t.vertex(n,o,h-Math.PI),t.vertex(n,o,h),this.points[x].z=h,b=x,x=g,y=a,a=f;else{for(e=p;e<r;e++)g=x+1,f=this.points[g],l=f.x-y.x,d=f.y-y.y,h=Math.atan2(d,l)+HALF_PI,n=a.x+c,o=a.y+u,t.vertex(n,o,h-Math.PI),t.vertex(n,o,h),this.points[x].z=h,b=x,x=g,y=a,a=f;t.vertex(f.x+c,f.y+u,h-Math.PI),t.vertex(f.x+c,f.y+u,h),this.points[g].z=h}t.endShape(),this.bDidNrm=T}} getSmoothed(t){const s=this.points.length;if(s<=1)return this;if(this.bDidSmth)return this.smoothed;{this.smoothed=null,this.smoothed=new ofPolyline;const i=2*(t=Math.max(1,t));let e,o,h,n,r,d,m,l,p,a;if(this.bClosed){for(h=0;h<s;h++){for(e=o=0,r=0;r<i;r++)l=this.points[(h+r)%s],e+=l.x,o+=l.y;e/=i,o/=i,this.smoothed.add(e,o,1e-4)}let t=this.smoothed.points[0];return this.smoothed.clickToClose(t.x,t.y),this.bDidSmth=T,this.smoothed}{this.smoothed.add(this.points[0].x,this.points[0].y,1e-4);const r=Math.max(t,s-t);for(h=0;h<t;h++){for(a=Math.min(Math.max(h,1),t),e=o=0,m=Math.min(s,h+a),n=0;n<m;n++)l=this.points[n],e+=l.x,o+=l.y;e/=m,o/=m,this.smoothed.add(e,o,1e-4)}for(h=t;h<r;h++){for(e=o=0,d=h-t,m=h+t,n=d;n<m;n++)l=this.points[n],e+=l.x,o+=l.y;e/=i,o/=i,this.smoothed.add(e,o,1e-4)}if(r>=t)for(h=r;h<s;h++){for(a=Math.min(Math.max(s-h,1),t),e=o=0,d=h-a,m=s,p=m-d,n=d;n<m;n++)l=this.points[n],e+=l.x,o+=l.y;e/=p,o/=p,this.smoothed.add(e,o,1e-4)}return this.bDidSmth=T,this.smoothed}}} getPrm(){if(this.dirty){const t=this.points.length;let s=0;if(t>=2){let i,e,o,h;i=this.points[0];for(let n=1;n<t;n++)e=this.points[n],o=i.x-e.x,h=i.y-e.y,s+=Math.sqrt(o*o+h*h),i=e;this.bClosed&&(i=this.points[t-1],e=this.points[0],o=i.x-e.x,h=i.y-e.y,s+=Math.sqrt(o*o+h*h))}else s=0;return this.perimeter=s,this.dirty=F,this.perimeter}return this.perimeter} getRsmpBySpc(t){if(this.bDidRsmp)return this.resamped;{this.resamped=null,this.resamped=new ofPolyline;const s=this.points.length,i=s-1;if(s<=1||t<=.001)return this;const e=.1*t;let o,h,n,r,d,m,l,p,a,f,V,y,x,c,u=this.getPrm()-e,g=0,b=1;for(o=0;o<u;o+=t){for(V=0,y=this.lengths.length-1,h=g;h<y;h++){if(b=g+1,a=this.lengths[g],f=this.lengths[b],o>=a&&o<f){d=(o-a)/(f-a),V=g+d;break}g=b}n=~~V,r=this.bClosed?~~((n+1)%s):Math.min(n+1,i),l=this.points[n],p=this.points[r],m=V-n,x=p.x*m+l.x*(1-m),c=p.y*m+l.y*(1-m),this.resamped.add(x,c)}if(this.bClosed){if(this.bClosed){let t=this.resamped.points[0];this.resamped.clickToClose(t.x,t.y)}}else{const t=this.bClosed?0:i,s=this.points[t];this.resamped.points[this.resamped.points.length-1].dist(s)>e&&this.resamped.add(s.x,s.y)}return this.bDidRsmp=T,this.resamped}} getRsmpByNum(t){let s=this.getPrm()/(t=max(t,2));return this.getRsmpBySpc(s)} }