2 lines
5.7 KiB
JavaScript
2 lines
5.7 KiB
JavaScript
function S(e,i,t,n,h){y(e,i,t||0,n||e.length-1,h||E)}function y(e,i,t,n,h){for(;n>t;){if(n-t>600){var s=n-t+1,o=i-t+1,l=Math.log(s),r=.5*Math.exp(2*l/3),a=.5*Math.sqrt(l*r*(s-r)/s)*(o-s/2<0?-1:1),c=Math.max(t,Math.floor(i-o*r/s+a)),m=Math.min(n,Math.floor(i+(s-o)*r/s+a));y(e,i,c,m,h)}var u=e[i],x=t,f=n;for(B(e,t,i),h(e[n],u)>0&&B(e,t,n);x<f;){for(B(e,x,f),x++,f--;h(e[x],u)<0;)x++;for(;h(e[f],u)>0;)f--}h(e[t],u)===0?B(e,t,f):(f++,B(e,f,n)),f<=i&&(t=f+1),i<=f&&(n=f-1)}}function B(e,i,t){var n=e[i];e[i]=e[t],e[t]=n}function E(e,i){return e<i?-1:e>i?1:0}class q{constructor(i=9){this._maxEntries=Math.max(4,i),this._minEntries=Math.max(2,Math.ceil(this._maxEntries*.4)),this.clear()}all(){return this._all(this.data,[])}search(i){let t=this.data;const n=[];if(!_(i,t))return n;const h=this.toBBox,s=[];for(;t;){for(let o=0;o<t.children.length;o++){const l=t.children[o],r=t.leaf?h(l):l;_(i,r)&&(t.leaf?n.push(l):I(i,r)?this._all(l,n):s.push(l))}t=s.pop()}return n}collides(i){let t=this.data;if(!_(i,t))return!1;const n=[];for(;t;){for(let h=0;h<t.children.length;h++){const s=t.children[h],o=t.leaf?this.toBBox(s):s;if(_(i,o)){if(t.leaf||I(i,o))return!0;n.push(s)}}t=n.pop()}return!1}load(i){if(!(i&&i.length))return this;if(i.length<this._minEntries){for(let n=0;n<i.length;n++)this.insert(i[n]);return this}let t=this._build(i.slice(),0,i.length-1,0);if(!this.data.children.length)this.data=t;else if(this.data.height===t.height)this._splitRoot(this.data,t);else{if(this.data.height<t.height){const n=this.data;this.data=t,t=n}this._insert(t,this.data.height-t.height-1,!0)}return this}insert(i){return i&&this._insert(i,this.data.height-1),this}clear(){return this.data=d([]),this}remove(i,t){if(!i)return this;let n=this.data;const h=this.toBBox(i),s=[],o=[];let l,r,a;for(;n||s.length;){if(n||(n=s.pop(),r=s[s.length-1],l=o.pop(),a=!0),n.leaf){const c=v(i,n.children,t);if(c!==-1)return n.children.splice(c,1),s.push(n),this._condense(s),this}!a&&!n.leaf&&I(n,h)?(s.push(n),o.push(l),l=0,r=n,n=n.children[0]):r?(l++,n=r.children[l],a=!1):n=null}return this}toBBox(i){return i}compareMinX(i,t){return i.minX-t.minX}compareMinY(i,t){return i.minY-t.minY}toJSON(){return this.data}fromJSON(i){return this.data=i,this}_all(i,t){const n=[];for(;i;)i.leaf?t.push(...i.children):n.push(...i.children),i=n.pop();return t}_build(i,t,n,h){const s=n-t+1;let o=this._maxEntries,l;if(s<=o)return l=d(i.slice(t,n+1)),p(l,this.toBBox),l;h||(h=Math.ceil(Math.log(s)/Math.log(o)),o=Math.ceil(s/Math.pow(o,h-1))),l=d([]),l.leaf=!1,l.height=h;const r=Math.ceil(s/o),a=r*Math.ceil(Math.sqrt(o));w(i,t,n,a,this.compareMinX);for(let c=t;c<=n;c+=a){const m=Math.min(c+a-1,n);w(i,c,m,r,this.compareMinY);for(let u=c;u<=m;u+=r){const x=Math.min(u+r-1,m);l.children.push(this._build(i,u,x,h-1))}}return p(l,this.toBBox),l}_chooseSubtree(i,t,n,h){for(;h.push(t),!(t.leaf||h.length-1===n);){let s=1/0,o=1/0,l;for(let r=0;r<t.children.length;r++){const a=t.children[r],c=g(a),m=R(i,a)-c;m<o?(o=m,s=c<s?c:s,l=a):m===o&&c<s&&(s=c,l=a)}t=l||t.children[0]}return t}_insert(i,t,n){const h=n?i:this.toBBox(i),s=[],o=this._chooseSubtree(h,this.data,t,s);for(o.children.push(i),X(o,h);t>=0&&s[t].children.length>this._maxEntries;)this._split(s,t),t--;this._adjustParentBBoxes(h,s,t)}_split(i,t){const n=i[t],h=n.children.length,s=this._minEntries;this._chooseSplitAxis(n,s,h);const o=this._chooseSplitIndex(n,s,h),l=d(n.children.splice(o,n.children.length-o));l.height=n.height,l.leaf=n.leaf,p(n,this.toBBox),p(l,this.toBBox),t?i[t-1].children.push(l):this._splitRoot(n,l)}_splitRoot(i,t){this.data=d([i,t]),this.data.height=i.height+1,this.data.leaf=!1,p(this.data,this.toBBox)}_chooseSplitIndex(i,t,n){let h,s=1/0,o=1/0;for(let l=t;l<=n-t;l++){const r=M(i,0,l,this.toBBox),a=M(i,l,n,this.toBBox),c=N(r,a),m=g(r)+g(a);c<s?(s=c,h=l,o=m<o?m:o):c===s&&m<o&&(o=m,h=l)}return h||n-t}_chooseSplitAxis(i,t,n){const h=i.leaf?this.compareMinX:A,s=i.leaf?this.compareMinY:O,o=this._allDistMargin(i,t,n,h),l=this._allDistMargin(i,t,n,s);o<l&&i.children.sort(h)}_allDistMargin(i,t,n,h){i.children.sort(h);const s=this.toBBox,o=M(i,0,t,s),l=M(i,n-t,n,s);let r=Y(o)+Y(l);for(let a=t;a<n-t;a++){const c=i.children[a];X(o,i.leaf?s(c):c),r+=Y(o)}for(let a=n-t-1;a>=t;a--){const c=i.children[a];X(l,i.leaf?s(c):c),r+=Y(l)}return r}_adjustParentBBoxes(i,t,n){for(let h=n;h>=0;h--)X(t[h],i)}_condense(i){for(let t=i.length-1,n;t>=0;t--)i[t].children.length===0?t>0?(n=i[t-1].children,n.splice(n.indexOf(i[t]),1)):this.clear():p(i[t],this.toBBox)}}function v(e,i,t){if(!t)return i.indexOf(e);for(let n=0;n<i.length;n++)if(t(e,i[n]))return n;return-1}function p(e,i){M(e,0,e.children.length,i,e)}function M(e,i,t,n,h){h||(h=d(null)),h.minX=1/0,h.minY=1/0,h.maxX=-1/0,h.maxY=-1/0;for(let s=i;s<t;s++){const o=e.children[s];X(h,e.leaf?n(o):o)}return h}function X(e,i){return e.minX=Math.min(e.minX,i.minX),e.minY=Math.min(e.minY,i.minY),e.maxX=Math.max(e.maxX,i.maxX),e.maxY=Math.max(e.maxY,i.maxY),e}function A(e,i){return e.minX-i.minX}function O(e,i){return e.minY-i.minY}function g(e){return(e.maxX-e.minX)*(e.maxY-e.minY)}function Y(e){return e.maxX-e.minX+(e.maxY-e.minY)}function R(e,i){return(Math.max(i.maxX,e.maxX)-Math.min(i.minX,e.minX))*(Math.max(i.maxY,e.maxY)-Math.min(i.minY,e.minY))}function N(e,i){const t=Math.max(e.minX,i.minX),n=Math.max(e.minY,i.minY),h=Math.min(e.maxX,i.maxX),s=Math.min(e.maxY,i.maxY);return Math.max(0,h-t)*Math.max(0,s-n)}function I(e,i){return e.minX<=i.minX&&e.minY<=i.minY&&i.maxX<=e.maxX&&i.maxY<=e.maxY}function _(e,i){return i.minX<=e.maxX&&i.minY<=e.maxY&&i.maxX>=e.minX&&i.maxY>=e.minY}function d(e){return{children:e,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function w(e,i,t,n,h){const s=[i,t];for(;s.length;){if(t=s.pop(),i=s.pop(),t-i<=n)continue;const o=i+Math.ceil((t-i)/n/2)*n;S(e,o,i,t,h),s.push(i,o,o,t)}}export{q as R};
|