NEW collsion detection and elastic choc algorythme which works nice with squares
This commit is contained in:
@@ -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);
|
||||
w = h = (na.r+nb.r);
|
||||
dx = na.p.position.x - nb.p.position.x;
|
||||
dy = na.p.position.y - nb.p.position.y;
|
||||
|
||||
full_rad = _nodes[n].r + _nodes[q].r + margin;
|
||||
// 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 not colliding skip following
|
||||
if(d > full_rad) 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;
|
||||
|
||||
// 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);
|
||||
na.p.velocity.y = newVelY1;
|
||||
nb.p.velocity.y = newVelY2;
|
||||
|
||||
_nodes[n].p.velocity.x = newVelX1;
|
||||
_nodes[n].p.velocity.y = newVelY1;
|
||||
_nodes[q].p.velocity.x = newVelX2;
|
||||
_nodes[q].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;
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
w = h = (na.r+nb.r);
|
||||
dx = na.p.position.x - nb.p.position.x;
|
||||
dy = na.p.position.y - nb.p.position.y;
|
||||
|
||||
full_rad = _nodes[n].r + _nodes[q].r + margin;
|
||||
// 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 not colliding skip following
|
||||
if(d > full_rad) 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;
|
||||
|
||||
// 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);
|
||||
na.p.velocity.y = newVelY1;
|
||||
nb.p.velocity.y = newVelY2;
|
||||
|
||||
_nodes[n].p.velocity.x = newVelX1;
|
||||
_nodes[n].p.velocity.y = newVelY1;
|
||||
_nodes[q].p.velocity.x = newVelX2;
|
||||
_nodes[q].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;
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user