memoscan
← all memos

Memo 0xf35e7900…a1810c on Ethereum

///4 function determineClosestPointOnLoop(e,t,s){let y=determineClosestStructureAndParticle(e,t,s,T),l={valid:F,x:0,y:0};if(y.closestStructureId>=0){let s=mySs[y.closestStructureId],p=y.closestPLocalId;if(s.type==ST1||s.type==ST9||s.type==ST8||s.type==ST7||s.type==ST4){let y=p,i=p,S=p,r=s.pIs.length;if(s.type==ST1)y=(i-1+r)%r,S=(i+1)%r;else if(s.type==ST4){if(13==s.STID)return l;5!=s.STID&&10!=s.STID||(i-=i%2),9!=s.STID&&6!=s.STID||i%2==0&&i++,y=(i-2+r)%r,S=(i+2)%r}else if(s.type==ST9)i<=1?(y=r-1,S=2):i>=r-1?(y=i-1,S=1):(y=i-1,S=i+1);else if(s.type==ST8)i<2?(y=(i-1+r)%r,S=(i+1)%r):(i%4==2?i=(i-2+r)%r:i%4==3&&(i=(i+2+r)%r),y=(i-4+r)%r,S=(i+4)%r);else if(s.type==ST7){let e=2+s.PRPA;i%e>1&&(i=(i-i%e+1)%r),y=(i-e+r)%r,S=(i+e)%r}let I=s.pIs[y],d=s.pIs[i],n=s.pIs[S],m=myPs[I].p,o=myPs[d].p,x=myPs[n].p,P=dist(e,t,m.x,m.y),c=dist(e,t,x.x,x.y),f=e,u=t,L=o.x,a=o.y,E=m.x,Y=m.y;c<P&&(E=x.x,Y=x.y);let _=((f-L)*(E-L)+(u-a)*(Y-a))/((E-L)*(E-L)+(Y-a)*(Y-a));_=max(0,min(1,_));let D=L+_*(E-L),v=a+_*(Y-a);l.x=D,l.y=v,l.valid=T}else{let e=s.pIs[p];l.x=myPs[e].p.x,l.y=myPs[e].p.y,l.valid=T}}return l} function determineClosestStructureAndParticle(t,s,e,l){let o={closestStructureId:-1,closestPGlobalId:-1,closestPLocalId:-1,closestPDistance:1e5};if(bDoMF&&mySs.length>0){let c=-1,r=-1,y=-1,P=PINF;for(let e=0;e<mySs.length;e++){if(!l||l&&mySs[e].bLoop&&mySs[e].type!=ST12){const l=mySs[e].pIs.length;for(let o=0;o<l;o++){let l=mySs[e].pIs[o];if(-1!=myPs[l].isOfStrc){let n=t-myPs[l].p.x,u=s-myPs[l].p.y,S=n*n+u*u;S<P&&(r=o,y=l,P=S,c=e)}}}}if(c>=0){let t=sqrt(P);t<e&&y>=0&&r>=0&&(o.closestStructureId=c,o.closestPGlobalId=y,o.closestPLocalId=r,o.closestPDistance=t)}}return o} function drawMouseInfluenceCircle(){if(mouseIsPressed&&-1==GrabStrcId&&-1==GrabPid){let e=millis()-mousePressedTime,l=pow(Cs(e/MOUSE_F_RAD_T,0,1),.75),s=MOUSE_F_RAD_PCT*l*BDM,o=60;ogI.noStroke(),ogI.fill("black");for(let e=0;e<o;e++){let l=PI2*e/o,c=mouseX+zScale*s*cos(l),i=mouseY+zScale*s*sin(l);ogI.circle(c,i,zScale)}}} //Fixed 1/5/2024: function applyMouseForces(s){let mx=((mouseX/width-.5)/zScale+.5)*BDM;let my=((mouseY/height-.5)/zScale+.5)*BDM; if (bDoMF&&mouseIsPressed&&mouseX>0&&mouseX<width&&mouseY>0&&mouseY<height){ if (GrabStrcId>=0&&GrabPid>=0){ let mInP=T;if(!pointInPolygon(mx,my,myPs,nMaskPoints)){ let cpop=getClosestPointOnPolygonNaive(mx,my,myPs,nMaskPoints); if(cpop!=null){mx=0.99*cpop.x+0.01*mx;my=0.99*cpop.y+0.01*my;mInP=F;}}const _=mySs[GrabStrcId].springs.length; let o=[GrabPid];for(let s=0;s<_;s++){let e=mySs[GrabStrcId].springs[s],t=e.getIP(),_=e.getIQ(); t==GrabPid?o.push(_):_==GrabPid&&o.push(t)}for(let _=0;_<o.length;_++){let E=o[_],l=1==s?myPs[E].p0:myPs[E].pE; if (!isNaN(l.x) && !isNaN(l.y)){let dx=mx-l.x;let dy=my-l.y;let dh=sqrt(dx*dx+dy*dy); if(dh>1){let maxDh=(!mInP)?width/5:width/2;let frac=min(1,maxDh/dh);dx*=frac;dy*=frac; let e=0==_?20:5,fx=dx/100*e,fy=dy/100*e;myPs[E].addF(fx,fy,s)}}} }else{let _=millis()-mousePressedTime,o=pow(Cs(_/MOUSE_F_RAD_T,0,1),.75);const E=MOUSE_F_RAD_PCT*BDM*o,l=E*E;let m,R;for(let _=0;_<myPs.length;_++) if(!myPs[_].bIsABoundarySite){let o=1==s?myPs[_].p0:myPs[_].pE;let dx=mx-o.x;let dy=my-o.y;let I=dx*dx+dy*dy; if(I<l&&I>REST_L){0==myPs[_].isOfStrc?(m=-1,R=1):(m=MOUSE_REPULSION,R=MOUSE_F_POW); let e=sqrt(I),t=pow(1-e/E,R)*m,o=dx/e*t,l=dy/e*t;myPs[_].addF(o,l,s)}}}}} function applyFlockingForces(t){if(bApplyFlockF){const s=3*estAvgSep(),l=StSh.ballForceBalance,e=1-l;for(let o=0;o<mySs.length;o++)if(mySs[o].type==ST9&&mySs[o].bFlocking&&-1==mySs[o].siteAttachId){let m=mySs[o].pIs[0],y=1==t?myPs[m].p0.x:myPs[m].pE.x,i=1==t?myPs[m].p0.y:myPs[m].pE.y,p=PINF,a=0,n=0,r=F;for(let s=0;s<mySs.length;s++)if(mySs[s].type==ST4){const l=mySs[s].pIs.length;for(let e=0;e<l;e++){const l=mySs[s].pIs[e],o=1==t?myPs[l].p0.x:myPs[l].pE.x,m=1==t?myPs[l].p0.y:myPs[l].pE.y,S=y-o,c=i-m,P=S*S+c*c;P<p&&(r=T,p=P,a=o,n=m)}}if(r){let o=0,r=0,S=y-a,c=i-n,P=Math.sqrt(S*S+c*c);P>0&&(S/=P,c/=P,p>s?(o=0-S*l+c*e,r=0-c*l-S*e):p<=s&&(o=10*S,r=10*c),o*=StSh.ballAttr,r*=StSh.ballAttr,myPs[m].addF(o,r,t))}}let o=[[3,.3,1.5,1,1,2],[2,.2,1.5,1,2.5,-4],[8,.05,1.5,4,.5,16]][StSh.flockCfg];const m=BDM*estAvgSep(),y=m*o[0],i=o[2],p=o[3],a=o[4],n=o[5],r=o[1];if(StSh.bUseAmoCnt){resampNoiBlobPolyl=new ofPolyline;for(let t=0;t<nMaskPoints;t++)resampNoiBlobPolyl.add(myPs[t].p.x,myPs[t].p.y,0)}const S=((mouseX/width-.5)/zScale+.5)*BDM,c=((mouseY/height-.5)/zScale+.5)*BDM;let P=resampNoiBlobPolyl.points,d=resampNoiBlobPolyl.points.length,f=pointInsideVerts(S,c,P,d),u=.125*BDM;StSh.bUseAmoCnt&&(resampNoiBlobPolyl=null);for(let s=0;s<10;s++)if(s!=ST9){let l=o[1];s==ST2?l*=map(Math.cos(myMillis/1e4),-1,1,.75,1):s==ST0&&(l*=map(Math.sin(myMillis/1e4),-1,1,.6,1));const e=myFlocks[s].length;if(e>0)for(let o=0;o<e;o++){const P=myFlocks[s][o];if(mySs[P].bFlocking){const d=mySs[P].pIs[0],h=myPs[d],x=1==t?h.p0:h.pE,b=1==t?h.v0:h.v1;let F=CV(0,0),V=CV(0,0),M=CV(0,0),g=CV(0,0),C=CV(0,0),I=CV(0,0),A=CV(0,0),k=0,v=0;for(let l=0;l<e;l++)if(l!=o){let e=myFlocks[s][l];if(mySs[e].bFlocking){const s=mySs[e].pIs[0],l=myPs[s],o=1==t?l.p0:l.pE,i=1==t?l.v0:l.v1,p=x.x-o.x,a=x.y-o.y,n=Math.sqrt(p*p+a*a);if(n>0&&(n<y&&(k++,I.add(o.x,o.y),A.add(i.x,i.y)),n<m)){let t=Sb(x,o);t.normalize(),t.div(n),M.add(t),v++}}}if(k>0){I.div(k);let t=Sb(I,x);t.normalize(),t.mult(MAXSP),F=Sb(t,b),F.limit(l),A.div(k),A.normalize(),A.mult(MAXSP),V=Sb(A,b),V.limit(l)}if(v>0&&(M.div(v),M.mag()>0&&(M.normalize(),M.mult(MAXSP),M.sub(b),M.limit(l))),s==ST2&&mouseIsPressed&&f){let s=CV(S,c),e=Sb(s,x),o=min(u,e.mag());if(e.normalize(),e.mult(MAXSP),C=Sb(e,b),C.limit(l),o>m&&o<u){let s=C.x,l=C.y;C.x=(.25*s-l)*(1-o/u),C.y=(.25*l+s)*(1-o/u),C.mult(n),myPs[d].addF(C.x,C.y,t)}}M.mult(i),V.mult(p),F.mult(a),myPs[d].addF(M.x,M.y,t),myPs[d].addF(V.x,V.y,t),myPs[d].addF(F.x,F.y,t);let B=Math.sqrt(b.x*b.x+b.y*b.y);if(B>0){let s=CV(b.x/B,b.y/B),l=mySs[P].pIs[1],e=myPs[l],o=1==t?e.p0:e.pE,m=CV(o.x-x.x,o.y-x.y);m.normalize();let y=B*p5.Vector.cross(s,m).z;g.set(0-m.y*y,m.x*y),g.mult(r),myPs[l].addF(g.x,g.y,t)}}}}}} function calculateNumberOfMaskPoints(){rawBlobPVectorArrayContainer=imper.getBlobContFromPArr(sitePs);let r=pArea(rawBlobPVectorArrayContainer.points);r=abs(r)/(BDM*BDM);let t=r/nInteriorPoints,o=sqrt(3),n=o*sqrt(t/(3*o/2));n/=2.236;let a=polygonPerimeter(rawBlobPVectorArrayContainer.points);a/=BDM;let e=~~(pow(Cs(map(nInteriorPoints,200,1e3,2,1),1,2),.3333)*a/n);e-=e%12,nMaskPoints=e} function generateMask(t){StSh.bUseAmoCnt?generateMaskAmorph(t):(updateSitePhysics(),calculateImplicitContour(nMaskPoints),generateMaskStructured(t)),theBB={L:PINF,T:PINF,R:NINF,B:NINF};let e=min(myPs.length,nMaskPoints);for(let t=0;t<e;t++){let e=myPs[t].p;e.x<theBB.L&&(theBB.L=e.x),e.y<theBB.T&&(theBB.T=e.y),e.x>theBB.R&&(theBB.R=e.x),e.y>theBB.B&&(theBB.B=e.y)}let B=0;StSh.bDoRings&&(B+=StSh.firstOffsetRingSpacing+StSh.nOffRIngs*StSh.offsetRingSpacing,theBB.L-=B,theBB.T-=B,theBB.R+=B,theBB.B+=B),StSh.doMbrHairs&&(B+=REST_L*StSh.mbrHairLengthFactor,theBB.L-=B,theBB.T-=B,theBB.R+=B,theBB.B+=B)} function generateMaskStructured(o){if(o){calculateNumberOfMaskPoints(),calculateImplicitContour(nMaskPoints);for(let o=0;o<resampNoiBlobPolyl.points.length;o++){let l=resampNoiBlobPolyl.points[o].x,e=resampNoiBlobPolyl.points[o].y,s=new Particle;s.set(l,e),s.bIsABoundarySite=T,s.bNoShoAsBlb=T,s.isFree=F,myPs.push(s)}}else{resampNoiBlobPolyl.points.length!=nMaskPoints&&(imper.baseThreshold=max(.01,imper.baseThreshold-.1));for(let o=0;o<resampNoiBlobPolyl.points.length;o++){let l=resampNoiBlobPolyl.points[o].x,e=resampNoiBlobPolyl.points[o].y;myPs[o].set(l,e)}}} function generateMaskAmorph(t){if(t){let t=estAvgSep();t/=2.236;let s=PI2*maskR,a=pow(Cs(map(nInteriorPoints,200,1e3,2,1),1,2),.3333),o=~~(round(a*s/t));o-=o%12,nMaskPoints=o}let s=StSh.amoContourNoiseFalloff;noiseDetail(3,s);let a=StSh.ORG_SCALE_FACTOR/StSh.maxOSF,o=StSh.amoInvSp,e=StSh.amoNoi,i=StSh.amoRot,n=StSh.amoAR,S=StSh.amoMaskWrinkle,h=StSh.amoPowX,M=StSh.amoPowY,l=cos(i),m=sin(i),p=n>1?1/n:1,r=n>1?1:n;h*=1+.05*sin(PI2*myMillis/(2*o)+HALF_PI),M*=1+.05*sin(PI2*myMillis/(2*o));let k=new ofPolyline;const P=myMillis/StSh.amoInvSp2;if(StSh.bHpo){let t=StSh.hipRat,s=StSh.bPropHip,a=StSh.hipNoi,e=t*StSh.hipRatVar,i=StSh.hipRatVarInvSp,n=t+e*sin(myMillis/i),h=n*n;for(let t=0;t<nMaskPoints;t++){let e=t/nMaskPoints*PI2,i=11+S*cos(e+P),M=29+S*sin(e+P),l=a*(noise(i,M,myMillis/o)-.5),m=1,p=1,r=1;s?(m=1/sqrt(4*n)*sqrt(4*(n-sq(sin(e)))),p=.4*(m+.25*l)*cos(e),r=.4*(m+.25*l)*sin(e)):(n=h,m=1/n*(4*(n-sq(sin(e)))),p=.1*(m+l)*cos(e),r=.1*(m+l)*sin(e)),p=BDM*(.5+p),r=BDM*(.5+r),k.add(p,r)}}else{let t=1,s=1;105==SHMA&&(t=.96,s=.96);let i=StSh.amoWFq,n=StSh.amoWAm;i%4==0&&(n=0-n);let c=StSh.amoBumpShaperA,u=StSh.amoBumpShaperB;for(let I=0;I<nMaskPoints;I++){let A=I/nMaskPoints*PI2,y=11+S*cos(A+P),d=29+S*sin(A+P),f=e*(noise(y,d,myMillis/o)-.5),R=n*cos(i*A)*(.5*u*(1+c*cos(2*A))),B=p*(maskR*t+f+R)*a,D=r*(maskR*s+f+R)*a,b=cos(A),q=sin(A),v=abs(b),w=abs(q),F=Math.sign(b),g=Math.sign(q),H=B*F*pow(v,h),N=D*g*pow(w,M),C=l*N-m*H;H=BDM*(.5+(l*H+m*N)),N=BDM*(.5+C),k.add(H,N)}}k.close();let c=k.getRsmpByNum(nMaskPoints);for(let s=0;s<c.points.length;s++){let a=c.points[s].x,o=c.points[s].y;if(t){let t=new Particle;t.set(a,o),t.bIsABoundarySite=T,t.bNoShoAsBlb=T,t.isFree=F,myPs.push(t)}else myPs[s].set(a,o)}k=null,c=null} function pArea(t){let e=0;const n=t.length;let o=n-1;for(let l=0;l<n;l++){let n=t[l],r=t[o];e+=(r.x+n.x)*(r.y-n.y),o=l}return e/2} function polygonPerimeter(t){let e=0;const n=t.length;let o=n-1;for(let l=0;l<n;l++){const n=t[l],r=t[o];e+=dist(n.x,n.y,r.x,r.y),o=l}return e} function pointInsideVerts(t,e,n,o){let l=F;for(let r=0,y=o-1;r<o;y=r++){const o=n[r].x,c=n[r].y,i=n[y].x,s=n[y].y;c>e!=s>e&&t<(i-o)*(e-c)/(s-c)+o&&(l=!l)}return l} //DIST XFORM function setupDT(){dtInG=CG(dtW,dtH,P2D),dtOutG=CG(dtW,dtH,P2D),dtInG.pixelDensity(1),dtOutG.pixelDensity(1);let t=dtInG.canvas.getContext("2d",{willReadFrequently:T}),e=dtOutG.canvas.getContext("2d",{willReadFrequently:T});t.willReadFrequently=T,e.willReadFrequently=T,dtInBf=new Int8Array(dtW*dtH),dtOutBf=new Int16Array(dtW*dtH)} function getDT(t,e){let s=drawStrcsForDT(e),c=s[0],r=s[1];initDTOut(),propDT(),copyDTToOutg();let o=getMaxDTLoc(),l=o.x/dtW*BDM,a=o.y/dtH*BDM,n=determineClosestStructureAndParticle(l,a,BDM,F),u=-1,i=l,d=a;return n.closestPGlobalId>-1?(i=myPs[n.closestPGlobalId].p.x,d=myPs[n.closestPGlobalId].p.y,u=dist(l,a,i,d)):-1==n.closestStructureId&&(u=1e5),e<=0&&(globalOccupancy=c),{dtx:l,dty:a,minDist:u,occupancy:c,area:r}} function drawStrcsForDT(t){dtInG.background(0,0,0),dtInG.push(),dtInG.scale(dtW/BDM);const e=4*dtW*dtH;let n=T,d=0,l=0,o=0,r=T,I=0;t>0&&(r=F,n=F,I=t);const s=mySs.length;if(s>I){if(r){let t=getMbrIntCont();if(t){dtInG.noStroke(),dtInG.fill(255),dtInG.beginShape();for(let e=0;e<t.length;e++){let n=t[e].x,d=t[e].y;dtInG.vertex(n,d)}dtInG.endShape(CLOSE)}if(n){dtInG.loadPixels();for(let t=0;t<e;t+=4)l+=dtInG.pixels[t]<127?0:1}}for(let e=0;e<s;e++){if(mySs[e].type==ST13||mySs[e].type==ST11)continue;let n=0;r||e!=t||(n=255),dtInG.strokeWeight(9),dtInG.strokeJoin(ROUND),dtInG.stroke(n);const d=T;let l=mySs[e].getContours(d);for(let t=0;t<l.length;t++){let e=l[t],d=l[t].verts;e.bClosed?dtInG.fill(n):dtInG.noFill(),dtInG.beginShape();for(let t=0;t<d.length;t++){let e=d[t].x,n=d[t].y;dtInG.vertex(e,n)}e.bClosed?dtInG.endShape(CLOSE):dtInG.endShape()}}if(n){dtInG.loadPixels();for(let t=0;t<e;t+=4)d+=dtInG.pixels[t]<127?0:1;o=d/l}}return dtInG.pop(),[o,d]} function initDTOut(){const t=dtW*dtH;dtInG.loadPixels();for(let d=0;d<t;d++){let t=dtInG.pixels[4*d];dtInBf[d]=t<127?0:255}dtOutBf.fill(32767);let d=0;for(let t=0;t<dtH;t++){let l=dtW*t;for(let e=0;e<dtW;e++){let f=e+l;isBoundaryDT(e,t,f)?(dtOutBf[f]=0,d++):isJustOutsideDT(e,t,f)&&(dtOutBf[f]=-1)}}return d} function idt(t,d,f,u,a){let e=d+u,i=f+a;if(e<0||i<0||e>=dtW||i>=dtH)return;let n=dtOutBf[e+dtW*i];n+=(0==u||0==a?12:17)*(n<0?-1:1),Math.abs(dtOutBf[t])>Math.abs(n)&&(dtOutBf[t]=n)} function propDT(){let t,d,i,o;for(d=0;d<dtH;d++)for(i=d*dtW,t=0;t<dtW;t++)o=i+t,idt(o,t,d,-1,0),idt(o,t,d,-1,-1),idt(o,t,d,0,-1);for(d=dtHm1;d>=0;d--)for(i=d*dtW,t=dtWm1;t>=0;t--)o=i+t,idt(o,t,d,1,0),idt(o,t,d,1,1),idt(o,t,d,0,1);for(t=dtWm1;t>=0;t--)for(d=dtHm1;d>=0;d--)o=d*dtW+t,idt(o,t,d,1,0),idt(o,t,d,1,1),idt(o,t,d,0,1);for(t=0;t<dtW;t++)for(d=0;d<dtH;d++)o=d*dtW+t,idt(o,t,d,-1,0),idt(o,t,d,-1,-1),idt(o,t,d,0,-1)} function isBoundaryDT(t,d,n){if(0==dtInBf[n])return F;if(t<=0||0==dtInBf[n-1])return T;if(t>=dtWm1||0==dtInBf[n+1])return T;let f=n-dtW,B=n+dtW;return d<=0||0==dtInBf[f]||d>=dtHm1||0==dtInBf[B]||t<=0||d<=0||0==dtInBf[f-1]||t<=0||d>=dtHm1||0==dtInBf[B-1]||t>=dtWm1||d<=0||0==dtInBf[f+1]||t>=dtWm1||d>=dtHm1||0==dtInBf[B+1]?T:F} function isJustOutsideDT(t,d,n){if(0!=dtInBf[n])return F;if(t>0&&0!=dtInBf[n-1])return T;if(t<dtWm1&&0!=dtInBf[n+1])return T;let f=n-dtW,B=n+dtW;return d>0&&0!=dtInBf[f]||d<dtHm1&&0!=dtInBf[B]||t>0&&d>0&&0!=dtInBf[f-1]||t>0&&d<dtHm1&&0!=dtInBf[B-1]||t<dtWm1&&d>0&&0!=dtInBf[f+1]||t<dtWm1&&d<dtHm1&&0!=dtInBf[B+1]?T:F} function getMaxDTLoc(){let t=0,n=0;const e=dtW*dtH;for(let d=0;d<e;d++){let e=dtOutBf[d];e>t&&(t=e,n=d)}let d=~~(n/dtW),f=n%dtW;return CV(f,d,t)} function getDTAtLoc(t,o){let d=0,n=~~(t/BDM*dtW),r=~~(o/BDM*dtH)*dtW+n;return r<dtW*dtH&&r>0&&(d=dtOutBf[r]),d} function copyDTToOutg(){const t=255/dtOutBf.reduce(((t,u)=>Math.max(t,u)),-Infinity),u=dtW*dtH;let d=0;dtOutG.loadPixels();for(let e=0;e<u;e++){let u=~~(t*dtOutBf[e]);dtOutG.pixels[d++]=u,dtOutG.pixels[d++]=u,dtOutG.pixels[d++]=u,dtOutG.pixels[d++]=255}dtOutG.updatePixels()} function getMbrIntCont(){let s=[];if(mySs[0].type==ST10){const n=mySs[0].pIs.length/nMaskPoints;if(n>0){const t=(n-1)*nMaskPoints,o=t+nMaskPoints;for(let n=t;n<o;n++){const t=mySs[0].pIs[n];s.push(myPs[t].p)}}else for(let n=0;n<nMaskPoints;n++)s.push(myPs[n].p)}return s} //BLOBS function determineWhichBlobsToDraw(){if(StSh.bDrawBs){const t=mySs.length;if(t>0){let e=0;for(let s=0;s<t;s++)mySs[s].bLoop&&mySs[s].bShowEnclBl&&e++;if(e>0){let e=[],s=[];for(let l=0;l<t;l++)if(mySs[l].bLoop&&mySs[l].bShowEnclBl){let t=[],o=1,n=0;mySs[l].type==ST9&&(n=1),mySs[l].type==ST4&&(o=2),mySs[l].type==ST7&&(o=2+mySs[l].PRPA);let y=mySs[l].boundingBox,m=mySs[l].pIs;for(let e=n;e<m.length;e+=o)t.push(myPs[m[e]].p);e.push(t),s.push(y),t=null}if(e.length>0){let t=d3Voronoi.cellPolygons(),l=t.next();const o=16;let n=myFrmCnt%o;for(let e=0;e<n;e++)l=t.next();for(;!l.done;){if(myPs[n].bDrawSiteBlob=F,-1==myPs[n].isOfStrc){const t=myPs[n].p.x,l=myPs[n].p.y;for(let o=0;o<e.length;o++){const y=s[o];if(t>y.L&&t<y.R&&l>y.T&&l<y.B){let s=e[o],y=s.length;pointInsideVerts(t,l,s,y)&&(myPs[n].bDrawSiteBlob=T)}}}for(let e=0;e<o;e++)l=t.next(),n++}}e=null,s=null}}}} function getOffsetCurveContours(s){let t=[];resetRnd(CHASH);const l=s.PRPA,e=s.PRPB,n=s.PRPC,P=s.STID,o=.8*REST_L,y=nMaskPoints-1;for(let s=0;s<l;s++){const p=Math.pow(map(s,0,l,1,0),1.5),u=p*W1,f=(n+s)*e/o;if(s>=l/2-1&&P){let s=T,l=[],e=myPs[0].p.x,n=myPs[0].p.y;for(let P=1;P<nMaskPoints;P++){let o=myPs[P].p.x,i=myPs[P].p.y,m=o-e,R=i-n,_=o+f*R,C=i-f*m,a=noise(_,C)<p;if(a){if(!s){l=[];let s=e+f*R,t=n-f*m;l.push(CV(s,t))}l.push(CV(_,C)),s=T}if(!a||P==y){if(s){l.push(CV(_,C));let s=new StyPl(l,F,T,F,F,STR_BK,FIL_NO,u,0,0,T);t.push(s),s=null,l=null}s=F}e=o,n=i}}else{let s=[],l=myPs[0].p.x,e=myPs[0].p.y;for(let t=1;t<nMaskPoints;t++){let n=t%nMaskPoints,P=myPs[n].p.x,o=myPs[n].p.y,y=P+f*(o-e),p=o-f*(P-l);s.push(CV(y,p)),l=P,e=o}let n=new StyPl(s,T,T,F,F,STR_BK,FIL_NO,u,0,0,T);t.push(n),n=null,s=null}}return t} function renderStructures(){const r=mySs.length;for(let e=0;e<r;e++)mySs[e].renderStructure()} function renderLetters(){const e=mySs.length;for(let t=0;t<e;t++)mySs[t].type==ST12&&mySs[t].renderLetter()} let nRenderedSiteBlobs=0; function renderEncircledSiteBlobs(){if(nRenderedSiteBlobs=0,StSh.bDrawBs){let e=d3Voronoi.cellPolygons(),o=e.next(),l=0;const t=255==StSh.siteBlbSCol?designBgCol:0,s=255==StSh.siteBlbFCol?designBgCol:0;GFXP5.noFill(),GFXP5.noStroke();const i=StSh.bDoFillSiteBlobs;for(GFXP5.strokeWeight(W1),GFXP5.stroke(t),i&&GFXP5.fill(s);!o.done;){if(myPs[l].bDrawSiteBlob&&!myPs[l].bNoShoAsBlb&&-1==myPs[l].isOfStrc){const e=o.value,t=e.length-1,s=myPs[l].c.x,n=myPs[l].c.y,r=drawSiteBlob(GFXP5C,F,e,t,s,n);i&&r&&GFXP5C.fill(),nRenderedSiteBlobs++}o=e.next(),l++}}GFXP5.noFill(),0==nRenderedSiteBlobs&&myFrmCnt>1e3&&StSh.bDrawBs&&(StSh.bDrawBs=F)} function renderSelectVoronoiCells(){if(StSh.bDrawVs){const e=mySs.length;let t=0;for(let o=0;o<e;o++)mySs[o].bShoVorCls&&t++;if(t>0){let e=d3Voronoi.cellPolygons(),t=e.next(),o=0;GFXP5.strokeWeight(W0);const s=StSh.nVoronoiSubdivs;for(;!t.done;){let l=myPs[o],n=l.isInStrc;if(n>0&&mySs[n].bShoVorCls){const e=t.value,o=e.length-1;if(s>1){let t=[];for(let l=0;l<o;l++)for(let o=0;o<s;o++){let o=e[l][0],s=e[l][1];t.push(CV(o,s))}const l=t.length;for(let e=0;e<l;e++){const o=(e-1+l)%l,s=(e+1)%l;t[e].x=(t[o].x+t[e].x+t[s].x)/3,t[e].y=(t[o].y+t[e].y+t[s].y)/3}for(let e=l-1;e>=0;e--){const o=(e-1+l)%l,s=(e+1)%l;t[e].x=(t[o].x+t[e].x+t[s].x)/3,t[e].y=(t[o].y+t[e].y+t[s].y)/3}GFXP5.noFill(),GFXP5.stroke(0),GFXP5.beginShape();for(let e=0;e<t.length;e++)GFXP5.vertex(t[e].x,t[e].y);GFXP5.endShape(CLOSE),t=null}else{GFXP5.noFill(),GFXP5.stroke(0),GFXP5.beginShape();for(let t=0;t<o;t++){let o=e[t][0],s=e[t][1];GFXP5.vertex(o,s)}GFXP5.endShape(CLOSE)}if(mySs[n].bShoVorNuc&&!l.bNoShoAsVorNuc){const e=l.p;GFXP5.fill(0),GFXP5.noStroke(),GFXP5.circle(e.x,e.y,W3)}}if(StSh.bDrawClippedVoronoiCellsOnInteriorStructureBoundaries){const e=myPs[o].isOfStrc;if(e>0){const s=mySs[e];if(s.bShoVorCls&&s.bShoVorEdgs&&s.type==ST4){const l=s.pIs,n=l.length;let r=-1;for(let e=0;e<n;e++)l[e]==o&&(r=e);if(r>=0&&r%2==0){GFXP5.stroke(0);const o=r,s=(r+2)%n,i=l[(r-2+n)%n],y=l[o],S=l[s],f=myPs[i].p.x,P=myPs[i].p.y,c=myPs[y].p.x,h=myPs[y].p.y,p=myPs[S].p.x,F=myPs[S].p.y,a=t.value,x=a.length-1,G=3;for(let t=0;t<x;t++){const o=a[t][0],s=a[t][1],l=a[t+1][0],n=a[t+1][1];if(mySs[e].pointInside(o,s)){if((o-c)*(P-h)-(s-h)*(f-c)>0){if((l-p)*(h-F)-(n-F)*(c-p)>0)GFXP5.line(o,s,l,n);else{const e=(F-P)*(l-o)-(p-f)*(n-s);if(Math.abs(e)>0){const t=((p-f)*(s-P)-(F-P)*(o-f))/e,r=((l-o)*(s-P)-(n-s)*(o-f))/e;if(Math.abs(t)<G&&Math.abs(r)<G){const e=o+t*(l-o),r=s+t*(n-s);GFXP5.line(o,s,e,r)}}}}}}}}}}t=e.next(),o++}}}} function drawSiteBlob(e,t,r,i,o,s){let l=r[1][0]-r[0][0],n=r[1][1]-r[0][1];if(isNaN(l)||isNaN(n))return F;const a=StSh.siteBlobScale,g=StSh.siteBlobTightness;let P=[];for(let e=0;e<i;e++){const t=e+1,i=o+a*((r[e][0]+r[t][0])/2-o),l=s+a*((r[e][1]+r[t][1])/2-s);P[e]=[i,l]}let S=getVPtArr(P,0,0,g);if(isNaN(S[0])||isNaN(S[1]))return F;if(t){e.beginShape(),e.vertex(S[0],S[1]);for(let t=0;t<i;t++){const r=getVPtArr(P,t,1,g),i=getVPtArr(P,t+1,-1,g),o=getVPtArr(P,t+1,0,g);e.bezierVertex(r[0],r[1],i[0],i[1],o[0],o[1])}e.endShape(CLOSE)}else{e.beginPath(),e.moveTo(S[0],S[1]);for(let t=0;t<i;t++){const r=getVPtArr(P,t,1,g),i=getVPtArr(P,t+1,-1,g),o=getVPtArr(P,t+1,0,g);e.bezierCurveTo(r[0],r[1],i[0],i[1],o[0],o[1])}e.closePath(),e.stroke()}return P=null,T} function getClosestPointOnPolygonNaive(t,e,n,r){let l=-1,u=PINF,o=0,i=0;for(let p=0;p<r;p++){const r=n[p].p.x,f=n[p].p.y;o+=r,i+=f;const s=r-t,C=f-e,V=s*s+C*C;V<u&&(u=V,l=p)}o/=r,i/=r;let p=l;if(null==n[p])return null;let f=n[p].p.x,s=n[p].p.y;if(u<Number.EPSILON)return f+=(o-f)*R20K[r],s+=(i-s)*R20K[r+p],CV(f,s,l);const C=(l+r-1)%r,V=(l+r+1)%r,y=n[C].p.x,c=n[C].p.y,x=n[V].p.x,N=n[V].p.y,P=y-f,a=c-s,g=x-f,h=N-s,q=y-x,I=c-N,K=((t-f)*P+(e-s)*a)/(P*P+a*a),M=((t-f)*g+(e-s)*h)/(g*g+h*h),O=K>0&&K<1,R=M>0&&M<1;if(O&&R){let n=f+K*(y-f),r=s+K*(c-s),u=n-t,o=r-e,i=f+M*(x-f),p=s+M*(N-s),C=i-t,V=p-e;return u*u+o*o<C*C+V*V?CV(n,r,l):CV(i,p,l)}if(O){let t=Math.sqrt(q*q+I*I),e=f+K*(y-f),n=s+K*(c-s);return e+=I/t/1024,n-=q/t/1024,CV(e,n,l)}if(R){let t=Math.sqrt(q*q+I*I),e=f+M*(x-f),n=s+M*(N-s);return e+=I/t/1024,n-=q/t/1024,CV(e,n,l)}return f+=.09375*(o-f),s+=.09375*(i-s),CV(f,s,l)} function pointInPolygon(n,t,o,p){let e=F;for(let l=0,r=p-1;l<p;r=l++){let p=o[l].p.x,y=o[l].p.y,f=o[r].p.x,i=o[r].p.y;y>t!=i>t&&n<(f-p)*(t-y)/(i-y)+p&&(e=!e)}return e} function getCentroidOfConvexPolygonAreaFast(t){const n=t.length-2,e=t[0][0],o=t[0][1];let r=0,l=0,c=0;for(let f=0;f<n;f++){const n=t[f+1],g=t[f+2],s=n[0]-e,a=n[1]-o,i=g[0]-e,u=s*(g[1]-o)-a*i;c+=u,r+=u*(e+n[0]+g[0]),l+=u*(o+n[1]+g[1])}return c*=3,r/=c,l/=c,[r,l]} function getVPtArr(t,n,r,s){const c=t.length;if(0===r)return t[n%c];{const e=t[n%c],o=t[(n+c-1)%c],h=t[(n+1)%c];let l=o[0]-e[0],a=o[1]-e[1];const f=Math.sqrt(l*l+a*a);let i=h[0]-e[0],q=h[1]-e[1];const u=Math.sqrt(i*i+q*q);l/=f,a/=f,i/=u,q/=u;const M=l+i,g=a+q,A=Math.sqrt(M*M+g*g);let P=0;if(A>0){P=s/A;const t=l*q-a*i;1===r?(P*=u,P*=t>0?-1:1):(P*=f,P*=t<0?-1:1)}return[e[0]+P*g,e[1]-P*M]}} function copyParticlesToD3Data(t){if(1==t)for(let t=0;t<myPs.length;t++){const a=2*t;d3Data[a]=myPs[t].pE.x,d3Data[a+1]=myPs[t].pE.y}else if(2==t)for(let t=0;t<myPs.length;t++){const a=2*t;d3Data[a]=myPs[t].p0.x,d3Data[a+1]=myPs[t].p0.y}} function updateParticles(){const s=myFrmCnt%16,e=mySs.length;if(myFrmCnt%3600==699)for(let s=0;s<e;s++)mySs[s].type==ST12&&mySs[s].purgeInteriorParticles();for(let t=nMaskPoints;t<myPs.length;t++)if(t%s==0)if(myPs[t].damping>.9375&&(myPs[t].damping-=.0001220703125),myPs[t].isFree=T,myPs[t].isInStrc=-1,-1==myPs[t].isOfStrc){const s=myPs[t].p.x,r=myPs[t].p.y;for(let m=0;m<e;m++)if(mySs[m].hasEncl){let e=1,y=0,n=F;switch(mySs[m].type){case ST4:e=2;break;case ST7:y=1,e=2+mySs[m].PRPA;break;case ST9:case ST12:y=1;break;case ST3:n=T,e=2;break;case ST8:n=T,e=4}let i=[];const a=mySs[m].pIs,c=a.length;if(n){for(let s=y;s<c;s+=e){const e=a[s];i.push(myPs[e].p)}for(let s=c-1;s>0;s-=e){const e=a[s];i.push(myPs[e].p)}}else for(let s=y;s<c;s+=e){const e=a[s];i.push(myPs[e].p)}pointInsideVerts(s,r,i,i.length)&&(myPs[t].isFree=F,myPs[t].isInStrc=m),i=null}}else myPs[t].isFree=F} function drawParticles(){if(StSh.bDrawPs){GFXP5.noStroke(),GFXP5.fill(0,0,0);const P=StSh.pDiam/2;switch(StSh.particleDrawMode){case P_SIZE_CONSTANT:for(let s=nMaskPoints;s<myPs.length;s++)if(myPs[s].isFree){const e=myPs[s].p;GFXP5C.beginPath(),GFXP5C.ellipse(e.x,e.y,P,P,0,0,PI2),GFXP5C.fill()}break;case P_SIZE_SPEEDBASED:StSh.bDrawPs=T;for(let P=nMaskPoints;P<myPs.length;P++)if(myPs[P].isFree){const s=.5*myPs[P].v.mag();if(s>.25){const e=myPs[P].p;GFXP5C.beginPath(),GFXP5C.ellipse(e.x,e.y,s,s,0,0,PI2),GFXP5C.fill()}}break;case P_SIZE_VARIEGATED:const s=min(19999,myPs.length),e=.65,i=1.414*P;for(let t=nMaskPoints;t<s;t++)if(myPs[t].isFree){const s=myPs[t].p,_=R20K[t]<e?P:i;GFXP5C.beginPath(),GFXP5C.ellipse(s.x,s.y,_,_,0,0,PI2),GFXP5C.fill()}}}} function estAvgSep(){let t=PI*maskR*maskR/nInteriorPoints,a=sqrt(3);return a*sqrt(t/(3*a/2))}