UNPKG

@anvaka/streamlines

Version:
2 lines (1 loc) 6.81 kB
(function(k,w){typeof exports=="object"&&typeof module<"u"?w(exports):typeof define=="function"&&define.amd?define(["exports"],w):(k=typeof globalThis<"u"?globalThis:k||self,w(k.streamlines={}))})(this,(function(k){"use strict";class w{constructor(e,t){this.x=e,this.y=t}equals(e){return this.x===e.x&&this.y===e.y}add(e){return new w(this.x+e.x,this.y+e.y)}mulScalar(e){return new w(this.x*e,this.y*e)}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}normalize(){const e=this.length();this.x/=e,this.y/=e}distanceTo(e){const t=e.x-this.x,u=e.y-this.y;return Math.sqrt(t*t+u*u)}}function K(r,e){if(!(r instanceof e))throw new TypeError("Cannot call a class as a function")}var V=(function(){function r(){K(this,r),this.children=null}return r.prototype.occupy=function(t){this.children||(this.children=[]),this.children.push(t)},r.prototype.isTaken=function(t,u,f){if(!this.children)return!1;for(var o=0;o<this.children.length;++o){var s=this.children[o],a=s.x-t,h=s.y-u,m=Math.sqrt(a*a+h*h);if(f(m,s))return!0}return!1},r.prototype.getMinDistance=function(t,u){let f=1/0;if(!this.children)return f;for(var o=0;o<this.children.length;++o){var s=this.children[o],a=s.x-t,h=s.y-u,m=Math.sqrt(a*a+h*h);m<f&&(f=m)}return f},r})();function z(r,e){var t=Math.max(r.width,r.height),u=Math.ceil(t/e),f=new Map,o={occupyCoordinates:h,isTaken:m,isOutside:a,findNearest:s};return o;function s(l,c){var g=P(l),y=A(c);let x=1/0;for(var v=-1;v<2;++v){var T=g+v;if(!(T<0||T>=u)){var n=f.get(T);if(n)for(var i=-1;i<2;++i){var d=y+i;if(d<0||d>=u)continue;var S=n.get(d);if(!S)continue;let E=S.getMinDistance(l,c);E<x&&(x=E)}}}return x}function a(l,c){return l<r.left||l>r.left+r.width||c<r.top||c>r.top+r.height}function h(l){var c=l.x,g=l.y;M(c,g).occupy(l)}function m(l,c,g){if(!f)return!1;for(var y=P(l),x=A(c),v=-1;v<2;++v){var T=y+v;if(!(T<0||T>=u)){var n=f.get(T);if(n)for(var i=-1;i<2;++i){var d=x+i;if(!(d<0||d>=u)){var S=n.get(d);if(S&&S.isTaken(l,c,g))return!0}}}}return!1}function M(l,c){p(l,c);var g=P(l),y=f.get(g);y||(y=new Map,f.set(g,y));var x=A(c),v=y.get(x);return v||(v=new V,y.set(x,v)),v}function P(l){return Math.floor(u*(l-r.left)/t)}function A(l){return Math.floor(u*(l-r.top)/t)}function p(l,c){if(r.left>l||r.left+t<l)throw new Error("x is out of bounds");if(r.top>c||r.top+t<c)throw new Error("y is out of bounds")}}function L(r,e,t){var u=t(r);if(u){var f=t(r.add(u.mulScalar(e*.5)));if(f){var o=t(r.add(f.mulScalar(e*.5)));if(o){var s=t(r.add(o.mulScalar(e)));if(s){var a=u.mulScalar(e/6).add(f.mulScalar(e/3)).add(o.mulScalar(e/3)).add(s.mulScalar(e/6));return a}}}}}var B=1,F=2,I=3;function G(r,e,t){var u=[r],f=r,o=B,s=null,a=-1,h=z(t.boundingBox,t.timeStep*.9);return{start:r,next:p,getStreamline:m,getNextValidSeed:M};function m(){return u}function M(){for(;a<u.length-1;){a+=1;var n=u[a],i=T(n);if(i){var d=n.x-i.y*t.dSep,S=n.y+i.x*t.dSep;if(Array.isArray(t.seedArray)&&t.seedArray.length>0){var E=t.seedArray.shift();d=E.x,S=E.y}if(!e.isOutside(d,S)&&!e.isTaken(d,S,A))return a-=1,new w(d,S);var q=n.x+i.y*t.dSep,_=n.y-i.x*t.dSep;if(!e.isOutside(q,_)&&!e.isTaken(q,_,A))return new w(q,_)}}}function P(n){return R(n,t.dTest)?!1:n<t.dTest}function A(n){return R(n,t.dSep)?!1:n<t.dSep}function p(){for(;;){if(s=null,o===B){var n=c();if(n){u.push(n),h.occupyCoordinates(n),f=n;var i=v(n);if(i)return}else t.forwardOnly?o=I:(f=r,o=F)}if(o===F){var n=g();if(n){u.unshift(n),f=n,h.occupyCoordinates(n);var i=v(n);if(i)return}else o=I}if(o===I)return u.forEach(l),!0}}function l(n){e.occupyCoordinates(n)}function c(){var n=L(f,t.timeStep,T);if(n)return y(f,n)}function g(){var n=L(f,t.timeStep,T);if(n)return n=n.mulScalar(-1),y(f,n)}function y(n,i){if(s=n.add(i),!e.isOutside(s.x,s.y)&&!e.isTaken(s.x,s.y,P)&&!h.isTaken(s.x,s.y,x))return s}function x(n){return n<t.timeStep*.9}function v(n){var i=!1;return t.onPointAdded&&(i=t.onPointAdded(n,u[o===B?u.length-2:1],t,u)),i}function T(i){var i=t.vectorField(i,u,o===I);if(i&&!(Number.isNaN(i.x)||Number.isNaN(i.y))){var d=i.x*i.x+i.y*i.y;if(d!==0)return d=Math.sqrt(d),new w(i.x/d,i.y/d)}}}function R(r,e){return Math.abs(r-e)<1e-4}function H(r){if(!r)throw new Error("Canvas is required");var e=r.getContext("2d"),t=r.width,u=r.height;return f;function f(s,a,h){e.beginPath(),e.strokeStyle="rgba(0, 0, 0, 0.6)",s=o(s,h.boundingBox),a=o(a,h.boundingBox),e.moveTo(s.x,s.y),e.lineTo(a.x,a.y),e.stroke(),e.closePath()}function o(s,a){var h=(s.x-a.left)/a.width,m=(s.y-a.top)/a.height;return{x:h*t,y:(1-m)*u}}}var j=0,Q=1,D=2,U=3,C=4;const W=typeof globalThis<"u"&&globalThis.performance&&typeof globalThis.performance.now=="function"?globalThis.performance:{now:()=>Date.now()};function J(r){var e=Object.create(null);if(!r)throw new Error("Configuration is required to compute streamlines");r.boundingBox?(e.boundingBox={},Object.assign(e.boundingBox,r.boundingBox)):(console.warn("No bounding box passed to streamline. Creating default one"),e.boundingBox={left:-5,top:-5,width:10,height:10}),Z(e.boundingBox);var t=e.boundingBox;if(e.vectorField=r.vectorField,e.onStreamlineAdded=r.onStreamlineAdded,e.onPointAdded=r.onPointAdded,e.forwardOnly=r.forwardOnly,!r.seed)e.seed=new w(Math.random()*t.width+t.left,Math.random()*t.height+t.top);else if(Array.isArray(r.seed)){var u=r.seed.shift();e.seed=new w(u.x,u.y),e.seedArray=r.seed}else e.seed=new w(r.seed.x,r.seed.y);e.dSep=r.dSep>0?r.dSep:1/Math.max(t.width,t.height),e.dTest=r.dTest>0?r.dTest:e.dSep*.5;var f=z(t,e.dSep);e.timeStep=r.timeStep>0?r.timeStep:.01,e.stepsPerIteration=r.stepsPerIteration>0?r.stepsPerIteration:10,e.maxTimePerIteration=r.maxTimePerIteration>0?r.maxTimePerIteration:1e3;var o=e.stepsPerIteration,s,a=j,h=[],m=G(e.seed,f,e),M=!1,P=!1,A;return{run:l,getGrid:p,dispose:g};function p(){return f}function l(){if(!P)return P=!0,A=setTimeout(y,0),new Promise(c)}function c(d){s=d}function g(){M=!0,clearTimeout(A)}function y(){if(!M){for(var d=e.maxTimePerIteration,S=W.now(),E=0;E<o&&(a===j&&x(),a===Q&&n(),a===D&&T(),a===C&&v(),!(W.now()-S>d));++E)if(a===U){s(e);return}A=setTimeout(y,0)}}function x(){var d=m.next();d&&(i(),a=D)}function v(){var d=h[0],S=d.getNextValidSeed();S?(m=G(S,f,e),a=Q):(h.shift(),a=D)}function T(){h.length===0?a=U:a=C}function n(){var d=m.next();d&&(i(),a=C)}function i(){var d=m.getStreamline();d.length>1&&(h.push(m),e.onStreamlineAdded&&e.onStreamlineAdded(d,e))}}function Z(r){var e="Bounding box {left, top, width, height} is required";if(!r)throw new Error(e);if(N(r.left,e),N(r.top,e),typeof r.size=="number"&&(r.width=r.size,r.height=r.size),N(r.width,e),N(r.height,e),r.width<=0||r.height<=0)throw new Error("Bounding box cannot be empty")}function N(r,e){if(typeof r!="number"||Number.isNaN(r))throw new Error(e)}k.default=J,k.renderTo=H,Object.defineProperties(k,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));