|
@@ -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);
|
|
|
|
|
|
}
|
|
|
}
|