d3-force-bounce
Version:
An elastic collision force type for the d3-force simulation engine.
3 lines (2 loc) • 6.78 kB
JavaScript
// Version 1.0.2 d3-force-bounce - https://github.com/vasturiano/d3-force-bounce
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";function n(t,n,r,i){if(isNaN(n)||isNaN(r))return t;var e,o,h,s,a,u,f,l,x,c=t._root,y={data:i},_=t._x0,v=t._y0,d=t._x1,p=t._y1;if(!c)return t._root=y,t;for(;c.length;)if((u=n>=(o=(_+d)/2))?_=o:d=o,(f=r>=(h=(v+p)/2))?v=h:p=h,e=c,!(c=c[l=f<<1|u]))return e[l]=y,t;if(s=+t._x.call(null,c.data),a=+t._y.call(null,c.data),n===s&&r===a)return y.next=c,e?e[l]=y:t._root=y,t;do{e=e?e[l]=new Array(4):t._root=new Array(4),(u=n>=(o=(_+d)/2))?_=o:d=o,(f=r>=(h=(v+p)/2))?v=h:p=h}while((l=f<<1|u)==(x=(a>=h)<<1|s>=o));return e[x]=c,e[l]=y,t}function r(t,n,r,i,e){this.node=t,this.x0=n,this.y0=r,this.x1=i,this.y1=e}function i(t){return t[0]}function e(t){return t[1]}function o(t,n,r){var o=new h(null==n?i:n,null==r?e:r,NaN,NaN,NaN,NaN);return null==t?o:o.addAll(t)}function h(t,n,r,i,e,o){this._x=t,this._y=n,this._x0=r,this._y0=i,this._x1=e,this._y1=o,this._root=void 0}function s(t){for(var n={data:t.data},r=n;t=t.next;)r=r.next={data:t.data};return n}var a=o.prototype=h.prototype;function u(t){return function(){return t}}a.copy=function(){var t,n,r=new h(this._x,this._y,this._x0,this._y0,this._x1,this._y1),i=this._root;if(!i)return r;if(!i.length)return r._root=s(i),r;for(t=[{source:i,target:r._root=new Array(4)}];i=t.pop();)for(var e=0;e<4;++e)(n=i.source[e])&&(n.length?t.push({source:n,target:i.target[e]=new Array(4)}):i.target[e]=s(n));return r},a.add=function(t){const r=+this._x.call(null,t),i=+this._y.call(null,t);return n(this.cover(r,i),r,i,t)},a.addAll=function(t){var r,i,e,o,h=t.length,s=new Array(h),a=new Array(h),u=1/0,f=1/0,l=-1/0,x=-1/0;for(i=0;i<h;++i)isNaN(e=+this._x.call(null,r=t[i]))||isNaN(o=+this._y.call(null,r))||(s[i]=e,a[i]=o,e<u&&(u=e),e>l&&(l=e),o<f&&(f=o),o>x&&(x=o));if(u>l||f>x)return this;for(this.cover(u,f).cover(l,x),i=0;i<h;++i)n(this,s[i],a[i],t[i]);return this},a.cover=function(t,n){if(isNaN(t=+t)||isNaN(n=+n))return this;var r=this._x0,i=this._y0,e=this._x1,o=this._y1;if(isNaN(r))e=(r=Math.floor(t))+1,o=(i=Math.floor(n))+1;else{for(var h,s,a=e-r||1,u=this._root;r>t||t>=e||i>n||n>=o;)switch(s=(n<i)<<1|t<r,(h=new Array(4))[s]=u,u=h,a*=2,s){case 0:e=r+a,o=i+a;break;case 1:r=e-a,o=i+a;break;case 2:e=r+a,i=o-a;break;case 3:r=e-a,i=o-a}this._root&&this._root.length&&(this._root=u)}return this._x0=r,this._y0=i,this._x1=e,this._y1=o,this},a.data=function(){var t=[];return this.visit((function(n){if(!n.length)do{t.push(n.data)}while(n=n.next)})),t},a.extent=function(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},a.find=function(t,n,i){var e,o,h,s,a,u,f,l=this._x0,x=this._y0,c=this._x1,y=this._y1,_=[],v=this._root;for(v&&_.push(new r(v,l,x,c,y)),null==i?i=1/0:(l=t-i,x=n-i,c=t+i,y=n+i,i*=i);u=_.pop();)if(!(!(v=u.node)||(o=u.x0)>c||(h=u.y0)>y||(s=u.x1)<l||(a=u.y1)<x))if(v.length){var d=(o+s)/2,p=(h+a)/2;_.push(new r(v[3],d,p,s,a),new r(v[2],o,p,d,a),new r(v[1],d,h,s,p),new r(v[0],o,h,d,p)),(f=(n>=p)<<1|t>=d)&&(u=_[_.length-1],_[_.length-1]=_[_.length-1-f],_[_.length-1-f]=u)}else{var g=t-+this._x.call(null,v.data),w=n-+this._y.call(null,v.data),N=g*g+w*w;if(N<i){var A=Math.sqrt(i=N);l=t-A,x=n-A,c=t+A,y=n+A,e=v.data}}return e},a.remove=function(t){if(isNaN(o=+this._x.call(null,t))||isNaN(h=+this._y.call(null,t)))return this;var n,r,i,e,o,h,s,a,u,f,l,x,c=this._root,y=this._x0,_=this._y0,v=this._x1,d=this._y1;if(!c)return this;if(c.length)for(;;){if((u=o>=(s=(y+v)/2))?y=s:v=s,(f=h>=(a=(_+d)/2))?_=a:d=a,n=c,!(c=c[l=f<<1|u]))return this;if(!c.length)break;(n[l+1&3]||n[l+2&3]||n[l+3&3])&&(r=n,x=l)}for(;c.data!==t;)if(i=c,!(c=c.next))return this;return(e=c.next)&&delete c.next,i?(e?i.next=e:delete i.next,this):n?(e?n[l]=e:delete n[l],(c=n[0]||n[1]||n[2]||n[3])&&c===(n[3]||n[2]||n[1]||n[0])&&!c.length&&(r?r[x]=c:this._root=c),this):(this._root=e,this)},a.removeAll=function(t){for(var n=0,r=t.length;n<r;++n)this.remove(t[n]);return this},a.root=function(){return this._root},a.size=function(){var t=0;return this.visit((function(n){if(!n.length)do{++t}while(n=n.next)})),t},a.visit=function(t){var n,i,e,o,h,s,a=[],u=this._root;for(u&&a.push(new r(u,this._x0,this._y0,this._x1,this._y1));n=a.pop();)if(!t(u=n.node,e=n.x0,o=n.y0,h=n.x1,s=n.y1)&&u.length){var f=(e+h)/2,l=(o+s)/2;(i=u[3])&&a.push(new r(i,f,l,h,s)),(i=u[2])&&a.push(new r(i,e,l,f,s)),(i=u[1])&&a.push(new r(i,f,o,h,l)),(i=u[0])&&a.push(new r(i,e,o,f,l))}return this},a.visitAfter=function(t){var n,i=[],e=[];for(this._root&&i.push(new r(this._root,this._x0,this._y0,this._x1,this._y1));n=i.pop();){var o=n.node;if(o.length){var h,s=n.x0,a=n.y0,u=n.x1,f=n.y1,l=(s+u)/2,x=(a+f)/2;(h=o[0])&&i.push(new r(h,s,a,l,x)),(h=o[1])&&i.push(new r(h,l,a,u,x)),(h=o[2])&&i.push(new r(h,s,x,l,f)),(h=o[3])&&i.push(new r(h,l,x,u,f))}e.push(n)}for(;n=e.pop();)t(n.node,n.x0,n.y0,n.x1,n.y1);return this},a.x=function(t){return arguments.length?(this._x=t,this):this._x},a.y=function(t){return arguments.length?(this._y=t,this):this._y},t.forceBounce=function(){var t,n,r=1,i=function(t){return 1},e=function(t){return Math.pow(i(t),2)};function h(){var h=o(t,(function(t){return t.x}),(function(t){return t.y})).visitAfter((function(t){if(t.data)return t.r=i(t.data);for(var n=t.r=0;n<4;++n)t[n]&&t[n].r>t.r&&(t.r=t[n].r)}));function s(t,n){var r=a(t.x,t.y);return u(r.d,r.a+n)}function a(t,n){return t=t||0,{d:Math.sqrt(t*t+n*n),a:0===t&&0===n?0:Math.atan(n/t)+(t<0?Math.PI:0)}}function u(t,n){return{x:t*Math.cos(n),y:t*Math.sin(n)}}t.forEach((function(t){var o=i(t);h.visit((function(i,h,f,l,x){var c=i.data,y=i.r,_=o+y;if(!c)return h>t.x+_||l<t.x-_||f>t.y+_||x<t.y-_;if(c.index>t.index){if(t.x===c.x&&t.y===c.y){var v=u(1e-6,2*Math.random()*Math.PI);c.x+=v.x,c.y+=v.y}var d=a(c.x-t.x,c.y-t.y),p=Math.max(0,_-d.d);if(!p)return;var g=s({x:t.vx,y:t.vy},-d.a),w=s({x:c.vx,y:c.vy},-d.a),N=function(t,n,r,i){var e=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1;return{a:(e*n*(i-r)+t*r+n*i)/(t+n),b:(e*t*(r-i)+t*r+n*i)/(t+n)}}(e(t),e(c),g.x,w.x,r);g.x=N.a,w.x=N.b;var A=s(g,d.a);t.vx=A.x,t.vy=A.y;var M=s(w,d.a);c.vx=M.x,c.vy=M.y;var b=u(p,d.a),m=o/(o+y);t.x-=b.x*(1-m),t.y-=b.y*(1-m),c.x+=b.x*m,c.y+=b.y*m,n&&n(t,c)}}))}))}return h.initialize=function(n){t=n},h.elasticity=function(t){return arguments.length?(r=t,h):r},h.radius=function(t){return arguments.length?(i="function"==typeof t?t:u(+t),h):i},h.mass=function(t){return arguments.length?(e="function"==typeof t?t:u(+t),h):e},h.onImpact=function(t){return arguments.length?(n=t,h):n},h}}));