d3-force-surface
Version:
A multi-surface elastic collision force type for the d3-force simulation engine.
3 lines (2 loc) • 2.17 kB
JavaScript
// Version 1.0.2 d3-force-surface - https://github.com/vasturiano/d3-force-surface
!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){return function(){return t}}t.forceSurface=function(){var t,r,o=[],f=1,u=function(t){return 1},e=function(t){return t.from},i=function(t){return t.to},a=function(t){return!!t.oneWay};function c(){function n(t,n){return r(t.from,n.from,n.to)!=r(t.to,n.from,n.to)&&r(t.from,t.to,n.from)!=r(t.from,t.to,n.to);function r(t,n,r){var o=(r.y-t.y)*(n.x-t.x),f=(n.y-t.y)*(r.x-t.x);return o>f+Number.EPSILON?1:o+Number.EPSILON<f?-1:0}}function c(t,n){var r=t.x,o=t.y;return{x:r+n.x,y:o+n.y}}function y(t,n){var r=x(t.x,t.y);return h(r.d,r.a+n)}function x(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 h(t,n){return{x:t*Math.cos(n),y:t*Math.sin(n)}}t.forEach((function(t){var m=u(t),v=x(t.vx,t.vy),s={from:{x:t.x,y:t.y},to:{x:t.x+t.vx,y:t.y+t.vy}};o.forEach((function(o){var u={from:e(o),to:i(o)},d=x(u.to.x-u.from.x,u.to.y-u.from.y),l=function(t){var n=2*Math.PI;for(;t<0;)t+=n;for(;t>n;)t-=n;return t}(d.a-v.a)<Math.PI;if(!l||!a(o)){var M=function(t,n){var r=t.from,o=t.to;return{from:c(r,n),to:c(o,n)}}(s,h(m,d.a+Math.PI/2*(l?-1:1))),p=n(u,{from:c(t,h(m,d.a-Math.PI/2)),to:c(t,h(m,d.a+Math.PI/2))});if(p||n(u,M)){var I=h(v.d,v.a-d.a);I.y*=-f;var g=y(I,d.a);if(t.vx=g.x,t.vy=g.y,p&&!a(o)){var P=h(y(c(M.from,{x:-u.from.x,y:-u.from.y}),-d.a).y,d.a-Math.PI/2);t.x+=P.x,t.y+=P.y}r&&r(t,o)}}}))}))}return c.initialize=function(n){t=n},c.surfaces=function(t){return arguments.length?(o=t,c):o},c.elasticity=function(t){return arguments.length?(f=t,c):f},c.radius=function(t){return arguments.length?(u="function"==typeof t?t:n(+t),c):u},c.from=function(t){return arguments.length?(e=t,c):e},c.to=function(t){return arguments.length?(i=t,c):i},c.oneWay=function(t){return arguments.length?(a="function"==typeof t?t:n(!!t),c):a},c.onImpact=function(t){return arguments.length?(r=t,c):r},c}}));