| 
					
				 | 
			
			
				@@ -8,6 +8,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  * @License: GPL-V3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// JS performance improvement http://archive.oreilly.com/pub/a/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   * depends on : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   * 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -520,75 +522,85 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     function checkParticulesCollisions(){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       // pre create vars to save memory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var d, full_rad, margin, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          newVelX1, newVelY1, newVelX2, newVelY2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          makeup, angle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var na,nb, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ma,mb, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          w,h,dx,dy, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          makeup, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          newVelX1, newVelY1, newVelX2, newVelY2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // , angle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       // colisions between _particules 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var n = 0; n < _nodes.length; n++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var n = 0, l = _nodes.length; n < l; n++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        na = _nodes[n]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ma = na.p.mass; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // avoid colliding for centered nodes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // if(_nodes[n].center) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // avoid colliding for scrambling nodes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if(_nodes[n].scrambling) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var q = n+1; q < _nodes.length; q++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if(q===n) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(na.scrambling) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var q = n+1; q < l; q++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          nb = _nodes[q]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          mb = nb.p.mass; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           // avoid impact between center and aside particules 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if((_nodes[n].center && _nodes[q].aside) || (_nodes[n].aside && _nodes[q].center)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if((na.center && nb.aside) || (na.aside && nb.center)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          margin = _nodes[n].center ? 0 : 0; // in px 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           // avoid impact between two centered particulses that comes to the center 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if(_nodes[n].center && _nodes[q].center){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if(Math.min(_nodes[n].p.distanceTo(_attracter), _nodes[q].p.distanceTo(_attracter)) > 300){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if(na.center && nb.center){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(Math.min(na.p.distanceTo(_attracter), nb.p.distanceTo(_attracter)) > 300){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               if( Math.random()>0.3 ) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          d = _nodes[n].p.distanceTo(_nodes[q].p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          full_rad = _nodes[n].r + _nodes[q].r + margin; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // if not colliding skip following 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if(d > full_rad) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // apply new forces if colliding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          newVelX1 = (_nodes[n].p.velocity.x * (_nodes[n].p.mass - _nodes[q].p.mass) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      + (2 * _nodes[q].p.mass * _nodes[q].p.velocity.x)) / (_nodes[n].p.mass + _nodes[q].p.mass); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          newVelY1 = (_nodes[n].p.velocity.y * (_nodes[n].p.mass - _nodes[q].p.mass) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      + (2 * _nodes[q].p.mass * _nodes[q].p.velocity.y)) / (_nodes[n].p.mass + _nodes[q].p.mass); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          newVelX2 = (_nodes[q].p.velocity.x * (_nodes[q].p.mass - _nodes[n].p.mass) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      + (2 * _nodes[n].p.mass * _nodes[n].p.velocity.x)) / (_nodes[n].p.mass + _nodes[q].p.mass); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          newVelY2 = (_nodes[q].p.velocity.y * (_nodes[q].p.mass - _nodes[n].p.mass) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      + (2 * _nodes[n].p.mass * _nodes[n].p.velocity.y)) / (_nodes[n].p.mass + _nodes[q].p.mass); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          w = h = (na.r+nb.r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dx = na.p.position.x - nb.p.position.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dy = na.p.position.y - nb.p.position.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // if both dx and dy are inferior to w & h so squares are colliding (overlapping) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // if( Math.abs(dx) <= w && Math.abs(dy) <= h){ console.log('colliding'); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // else not so skip 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if( Math.abs(dx) > w || Math.abs(dy) > h) continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if(Math.abs(dx) < Math.abs(dy)){ // vertical collision 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            makeup = (h - Math.abs(dy))/2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(dy > 0){ // a is upper than b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              na.p.position.y += makeup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              nb.p.position.y -= makeup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else{ // b is upper than a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              na.p.position.y -= makeup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              nb.p.position.y += makeup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // bounce 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // https://en.wikipedia.org/wiki/Elastic_collision#One-dimensional_Newtonian 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            newVelY1 = (ma-mb)/(ma+mb)*na.p.velocity.y+2*mb/(ma+mb)*nb.p.velocity.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            newVelY2 = (mb-ma)/(mb+ma)*nb.p.velocity.y+2*ma/(mb+ma)*na.p.velocity.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            na.p.velocity.y = newVelY1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            nb.p.velocity.y = newVelY2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }else{ // horizontal collision 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            makeup = (w - Math.abs(dx))/2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(dx > 0){ // a is at left of b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              na.p.position.x += makeup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              nb.p.position.x -= makeup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else{ // b is at left of a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              na.p.position.x -= makeup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              nb.p.position.x += makeup; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // bounce 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // https://en.wikipedia.org/wiki/Elastic_collision#One-dimensional_Newtonian 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            newVelX1 = (ma-mb)/(ma+mb)*na.p.velocity.x+2*mb/(ma+mb)*nb.p.velocity.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            newVelX2 = (mb-ma)/(mb+ma)*nb.p.velocity.x+2*ma/(mb+ma)*na.p.velocity.x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          _nodes[n].p.velocity.x = newVelX1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          _nodes[n].p.velocity.y = newVelY1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          _nodes[q].p.velocity.x = newVelX2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          _nodes[q].p.velocity.y = newVelY2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            na.p.velocity.x = newVelX1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            nb.p.velocity.x = newVelX2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           // slow down particule on impact 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          _nodes[n].p.velocity.multiplyScalar(_nodes[n].center && _nodes[n].p.velocity.length() < 1 ? 1.1 : 0.90); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          _nodes[q].p.velocity.multiplyScalar(_nodes[q].center && _nodes[q].p.velocity.length() < 1 ? 1.1 : 0.90); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // move particles if they overlap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (d < full_rad) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            makeup = (full_rad/2 - d/2)*1.2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            angle = Math.atan2(_nodes[q].p.position.y - _nodes[n].p.position.y, _nodes[q].p.position.x - _nodes[n].p.position.x); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            _nodes[q].p.position.x += makeup * Math.cos(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            _nodes[q].p.position.y += makeup * Math.sin(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            angle += Math.PI; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            _nodes[n].p.position.x += makeup * Math.cos(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            _nodes[n].p.position.y += makeup * Math.sin(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // na.p.velocity.multiplyScalar(na.center && na.p.velocity.length() < 1 ? 1.1 : 0.90); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // nb.p.velocity.multiplyScalar(nb.center && nb.p.velocity.length() < 1 ? 1.1 : 0.90); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          na.p.velocity.multiplyScalar(0.90); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          nb.p.velocity.multiplyScalar(0.90); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 |