-
Notifications
You must be signed in to change notification settings - Fork 0
/
polygon.js
2 lines (2 loc) · 4.74 KB
/
polygon.js
1
2
var gdjs;(function(j){const D=()=>({collision:!1,move_axis:[0,0]}),S=()=>({collision:!1,closeX:0,closeY:0,closeSqDist:0,farX:0,farY:0,farSqDist:0}),F={minMaxA:[0,0],minMaxB:[0,0],edge:[0,0],axis:[0,0],move_axis:[0,0],result:D()},R={p:[0,0],q:[0,0],r:[0,0],s:[0,0],deltaQP:[0,0],axis:[0,0],result:S()},n=class{constructor(){this.vertices=[];this.edges=[];this.center=[0,0]}move(t,e){for(let o=0,i=this.vertices.length;o<i;++o)this.vertices[o][0]+=t,this.vertices[o][1]+=e}rotate(t){let e=0;const o=Math.cos(-t),i=Math.sin(-t);for(let l=0,s=this.vertices.length;l<s;++l)e=this.vertices[l][0],this.vertices[l][0]=e*o+this.vertices[l][1]*i,this.vertices[l][1]=-e*i+this.vertices[l][1]*o}computeEdges(){for(;this.edges.length<this.vertices.length;)this.edges.push([0,0]);this.edges.length!=this.vertices.length&&(this.edges.length=this.vertices.length);for(let t=0,e=this.vertices.length;t<e;++t){const o=this.vertices[t],i=t+1>=e?this.vertices[0]:this.vertices[t+1];this.edges[t][0]=i[0]-o[0],this.edges[t][1]=i[1]-o[1]}}isConvex(){this.computeEdges();const t=this.edges.length;if(t<3)return!1;const e=this.edges[0][0]*this.edges[0+1][1]-this.edges[0][1]*this.edges[0+1][0]>0;for(let i=1;i<t-1;++i)if(this.edges[i][0]*this.edges[i+1][1]-this.edges[i][1]*this.edges[i+1][0]>0!==e)return!1;return this.edges[t-1][0]*this.edges[0][1]-this.edges[t-1][1]*this.edges[0][0]>0===e}computeCenter(){this.center[0]=0,this.center[1]=0;const t=this.vertices.length;for(let e=0;e<t;++e)this.center[0]+=this.vertices[e][0],this.center[1]+=this.vertices[e][1];return this.center[0]/=t,this.center[1]/=t,this.center}static createRectangle(t,e){const o=new j.Polygon;return o.vertices.push([-t/2,-e/2]),o.vertices.push([+t/2,-e/2]),o.vertices.push([+t/2,+e/2]),o.vertices.push([-t/2,+e/2]),o}static collisionTest(t,e,o){t.computeEdges(),e.computeEdges();let i=F.edge;const l=F.move_axis,s=F.result;let a=Number.MAX_VALUE;i[0]=0,i[1]=0,i[0]=0,i[1]=0,s.collision=!1,s.move_axis[0]=0,s.move_axis[1]=0;for(let m=0,g=t.vertices.length,v=e.vertices.length;m<g+v;m++){m<g?i=t.edges[m]:i=e.edges[m-g];const f=F.axis;f[0]=-i[1],f[1]=i[0],n.normalise(f);const x=F.minMaxA,M=F.minMaxB;n.project(f,t,x),n.project(f,e,M);const r=n.distance(x[0],x[1],M[0],M[1]);if(r>0||r===0&&o)return s.collision=!1,s.move_axis[0]=0,s.move_axis[1]=0,s;const d=Math.abs(r);d<a&&(a=d,l[0]=f[0],l[1]=f[1])}s.collision=!0;const h=t.computeCenter(),c=e.computeCenter(),P=[h[0]-c[0],h[1]-c[1]];return n.dotProduct(P,l)<0&&(l[0]=-l[0],l[1]=-l[1]),s.move_axis[0]=l[0]*a,s.move_axis[1]=l[1]*a,s}static raycastTest(t,e,o,i,l){const s=R.result;if(s.collision=!1,t.vertices.length<2)return s;t.computeEdges();const a=R.p,h=R.q,c=R.r,P=R.s;let m=Number.MAX_VALUE;a[0]=e,a[1]=o,c[0]=i-e,c[1]=l-o;for(let g=0;g<t.edges.length;g++){h[0]=t.vertices[g][0],h[1]=t.vertices[g][1],P[0]=t.edges[g][0],P[1]=t.edges[g][1];const v=R.deltaQP;v[0]=h[0]-a[0],v[1]=h[1]-a[1];const f=n.crossProduct(c,P),x=n.crossProduct(v,P)/f,M=n.crossProduct(v,c)/f;if(Math.abs(f)<=1e-4&&Math.abs(n.crossProduct(v,c))<=1e-4){const r=R.axis;r[0]=c[0],r[1]=c[1],n.normalise(r);const d=0,u=n.dotProduct(r,c),p=n.dotProduct(r,v),y=n.dotProduct(r,[v[0]+P[0],v[1]+P[1]]),b=Math.max(Math.min(d,u),Math.min(p,y)),A=Math.min(Math.max(d,u),Math.max(p,y));if(b>A)return s;s.collision=!0,u===0&&(s.closeX=e,s.closeY=o,s.closeSqDist=0,s.farX=e,s.farY=o,s.farSqDist=0);const q=b/Math.abs(u),T=A/Math.abs(u);return s.closeX=e+q*c[0],s.closeY=o+q*c[1],s.closeSqDist=q*q*(c[0]*c[0]+c[1]*c[1]),s.farX=e+T*c[0],s.farY=o+T*c[1],s.farSqDist=T*T*(c[0]*c[0]+c[1]*c[1]),s}else if(f!==0&&0<=x&&x<=1&&0<=M&&M<=1){const r=a[0]+x*c[0],d=a[1]+x*c[1],u=(r-e)*(r-e)+(d-o)*(d-o);u<m?(s.collision||(s.farX=r,s.farY=d,s.farSqDist=u),m=u,s.closeX=r,s.closeY=d,s.closeSqDist=u,s.collision=!0):(s.farX=r,s.farY=d,s.farSqDist=u)}}return s}static normalise(t){const e=Math.sqrt(t[0]*t[0]+t[1]*t[1]);e!=0&&(t[0]/=e,t[1]/=e)}static dotProduct(t,e){return t[0]*e[0]+t[1]*e[1]}static crossProduct(t,e){return t[0]*e[1]-t[1]*e[0]}static project(t,e,o){let i=n.dotProduct(t,e.vertices[0]);o[0]=i,o[1]=i;for(let l=1,s=e.vertices.length;l<s;++l)i=n.dotProduct(t,e.vertices[l]),i<o[0]?o[0]=i:i>o[1]&&(o[1]=i)}static distance(t,e,o,i){return t<o?o-e:t-i}static isPointInside(t,e,o){let i=!1;for(let l=0,s=t.vertices.length-1;l<t.vertices.length;s=l++){let a=t.vertices[l],h=t.vertices[s];a[1]>o!=h[1]>o&&e<(h[0]-a[0])*(o-a[1])/(h[1]-a[1])+a[0]&&(i=!i)}return i}static copyCollisionTestResult(t,e){e.collision=t.collision,e.move_axis[0]=t.move_axis[0],e.move_axis[1]=t.move_axis[1]}static copyRaycastTestResult(t,e){e.collision=t.collision,e.closeX=t.closeX,e.closeY=t.closeY,e.closeSqDist=t.closeSqDist,e.farX=t.farX,e.farY=t.farY,e.farSqDist=t.farSqDist}};let C=n;C.makeNewCollisionTestResult=D,C.makeNewRaycastTestResult=S,j.Polygon=C})(gdjs||(gdjs={}));
//# sourceMappingURL=polygon.js.map