added collision check to corpus map animation

This commit is contained in:
Bachir Soussi Chiadmi
2018-02-28 15:54:21 +01:00
parent 7dcdddf9de
commit 65d4d3df85
4 changed files with 129 additions and 88 deletions
@@ -34,7 +34,7 @@
// var _stage = new createjs.Stage('edlp-map'); // var _stage = new createjs.Stage('edlp-map');
var _nodes = []; var _nodes = [];
// var _particules = []; // var _particules = [];
var _p_radius = 3; // nodes radius (real radius, not diametre) var _base_radius = 3; // nodes radius (real radius, not diametre)
var _p_velocity_factor = 0.5; var _p_velocity_factor = 0.5;
var _m_pos = {x:0, y:0}; var _m_pos = {x:0, y:0};
var _node_hover_id = -1; var _node_hover_id = -1;
@@ -129,7 +129,7 @@
this.debug = d; this.debug = d;
this.mass = 8; this.mass = 8;
this.base_radius = _p_radius; this.base_radius = _base_radius;
this.g = { this.g = {
l : 1, // drawing line width l : 1, // drawing line width
s : 1 // drawing space between squares s : 1 // drawing space between squares
@@ -145,6 +145,7 @@
this.y = this.wall_limits.top + Math.random()*(this.wall_limits.bottom - this.wall_limits.top); this.y = this.wall_limits.top + Math.random()*(this.wall_limits.bottom - this.wall_limits.top);
this.hover = false; this.hover = false;
// physics // physics
this.p = _physics.makeParticle(this.mass, this.x, this.y); this.p = _physics.makeParticle(this.mass, this.x, this.y);
this.p.velocity = new Physics.Vector((Math.random()-0.5)*_p_velocity_factor, (Math.random()-0.5)*_p_velocity_factor); this.p.velocity = new Physics.Vector((Math.random()-0.5)*_p_velocity_factor, (Math.random()-0.5)*_p_velocity_factor);
@@ -206,7 +207,7 @@
&& _m_pos.y > this.y - this.real_radius && _m_pos.y > this.y - this.real_radius
&& _m_pos.y < this.y + this.real_radius){ && _m_pos.y < this.y + this.real_radius){
if(_node_hover_id == -1 || _node_hover_id == this.id){ if(_node_hover_id == -1 || _node_hover_id == this.id){
console.log("Node hover", this.id); // console.log("Node hover", this.id);
this.hover = true; this.hover = true;
this.highlightEntries(); this.highlightEntries();
_node_hover_id = this.id; _node_hover_id = this.id;
@@ -235,7 +236,7 @@
_ctx.beginPath(); _ctx.beginPath();
_ctx.lineWidth = this.g.l*2;//this.hover ? this.g.l*2 : this.g.l; _ctx.lineWidth = this.g.l*2;//this.hover ? this.g.l*2 : this.g.l;
var r,d; var r,d;
for (var i = 0; i < this.entrees.length; i++) { for (let i = 0; i < this.entrees.length; i++) {
// _ctx.fillStyle = i == 0 ? _entrees_colors[this.entrees[i]] : "#fff"; // _ctx.fillStyle = i == 0 ? _entrees_colors[this.entrees[i]] : "#fff";
// _ctx.strokeStyle = _entrees_colors[this.entrees[i]]; // _ctx.strokeStyle = _entrees_colors[this.entrees[i]];
_ctx.fillStyle = i == 0 ? edlp_vars['e_col_'+this.entrees[i]] : "#fff"; _ctx.fillStyle = i == 0 ? edlp_vars['e_col_'+this.entrees[i]] : "#fff";
@@ -266,53 +267,70 @@
// / ____/ / / / /_/ (__ ) / /__(__ ) // / ____/ / / / /_/ (__ ) / /__(__ )
// /_/ /_/ /_/\__, /____/_/\___/____/ // /_/ /_/ /_/\__, /____/_/\___/____/
// /____/ // /____/
// TODO: how to use particule collision in new OOP Node() contexte // TODO: we may convert a lot of computation into a web worker https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
function checkParticulesCollisions(){ function checkParticulesCollisions(){
// pre create vars to save memory;
var node_a, node_b, p_a, p_b,
d, full_rad,
newVelX1, newVelY1, newVelX2, newVelY2,
makeup, angle;
// colisions between _particules // colisions between _particules
for (var p = 0, l = _particules.length; p < l; p++) { for (var n = 0, l = _nodes.length; n < l; n++) {
var particule = _particules[p]; node_a = _nodes[n];
// var theta = 360 / (Math.PI * _p_radius); p_a = node_a.p;
if(!particule.attracted) continue; // console.log(`p_a`, p_a.attracted);
for (var q = 0; q < p; q++) { // var theta = 360 / (Math.PI * _base_radius);
if(q==p) continue; // if(!p_a.attracted) continue;
// console.log('test');
for (var q = 0; q < n; q++) {
if(q===n) continue;
var a = particule; node_b = _nodes[q];
var b = _particules[q]; p_b = node_b.p;
if(!b.attracted) continue; // if(!p_b.attracted) continue;
var d = a.distanceTo(b); d = p_a.distanceTo(p_b);
full_rad = node_a.real_radius + node_b.real_radius;
// if not colliding skip following
if(d > full_rad) continue;
// apply new forces if colliding // apply new forces if colliding
if(d <= _p_radius*2){ newVelX1 = (p_a.velocity.x * (p_a.mass - p_b.mass)
+ (2 * p_b.mass * p_b.velocity.x)) / (p_a.mass + p_b.mass);
newVelY1 = (p_a.velocity.y * (p_a.mass - p_b.mass)
+ (2 * p_b.mass * p_b.velocity.y)) / (p_a.mass + p_b.mass);
newVelX2 = (p_b.velocity.x * (p_b.mass - p_a.mass)
+ (2 * p_a.mass * p_a.velocity.x)) / (p_a.mass + p_b.mass);
newVelY2 = (p_b.velocity.y * (p_b.mass - p_a.mass)
+ (2 * p_a.mass * p_a.velocity.y)) / (p_a.mass + p_b.mass);
var newVelX1 = (a.velocity.x * (a.mass - b.mass) + (2 * b.mass * b.velocity.x)) / (a.mass + b.mass); p_a.velocity.x = newVelX1;
var newVelY1 = (a.velocity.y * (a.mass - b.mass) + (2 * b.mass * b.velocity.y)) / (a.mass + b.mass); p_a.velocity.y = newVelY1;
var newVelX2 = (b.velocity.x * (b.mass - a.mass) + (2 * a.mass * a.velocity.x)) / (a.mass + b.mass); p_b.velocity.x = newVelX2;
var newVelY2 = (b.velocity.y * (b.mass - a.mass) + (2 * a.mass * a.velocity.y)) / (a.mass + b.mass); p_b.velocity.y = newVelY2;
a.velocity.x = newVelX1; p_a.velocity.multiplyScalar(0.75);
a.velocity.y = newVelY1; p_b.velocity.multiplyScalar(0.75);
b.velocity.x = newVelX2;
b.velocity.y = newVelY2;
a.velocity.multiplyScalar(0.75);
b.velocity.multiplyScalar(0.75);
// move particles if they overlap // move particles if they overlap
if (d < _p_radius*2) { if (d < full_rad) {
var makeup = _p_radius - d/2; makeup = full_rad/2 - d/2;
var angle = Math.atan2(b.position.y - a.position.y, b.position.x - a.position.x); angle = Math.atan2(p_b.position.y - p_a.position.y, p_b.position.x - p_a.position.x);
b.position.x += makeup * Math.cos(angle); p_b.position.x += makeup * Math.cos(angle);
b.position.y += makeup * Math.sin(angle); p_b.position.y += makeup * Math.sin(angle);
angle += Math.PI; angle += Math.PI;
a.position.x += makeup * Math.cos(angle); p_a.position.x += makeup * Math.cos(angle);
a.position.y += makeup * Math.sin(angle); p_a.position.y += makeup * Math.sin(angle);
}
} }
_nodes[n].p = p_a;
_nodes[q].p = p_b;
} }
} }
}; };
@@ -326,7 +344,7 @@
_$canvas _$canvas
.on('mousemove', function(event) { .on('mousemove', function(event) {
event.preventDefault(); event.preventDefault();
console.log("onMouseMove"); // console.log("onMouseMove");
_m_pos.x = event.originalEvent.clientX; _m_pos.x = event.originalEvent.clientX;
_m_pos.y = event.originalEvent.clientY; _m_pos.y = event.originalEvent.clientY;
// console.log("/ _ / - / _ /"); // console.log("/ _ / - / _ /");
@@ -369,14 +387,17 @@
function render(){ function render(){
_ctx.clearRect(0, 0, _canvas.width, _canvas.height); _ctx.clearRect(0, 0, _canvas.width, _canvas.height);
checkParticulesCollisions();
for (var i = 0; i < _nodes.length; i++) { for (var i = 0; i < _nodes.length; i++) {
_nodes[i].onUpdate(); _nodes[i].onUpdate();
} }
if(_node_hover_id != -1){ // if(_node_hover_id != -1){
_canvas.style.cursor = 'pointer'; // _canvas.style.cursor = 'pointer';
}else{ // }else{
_canvas.style.cursor = 'auto'; // _canvas.style.cursor = 'auto';
} // }
_canvas.style.cursor = _node_hover_id != -1 ? 'pointer' : 'auto';
}; };
function startAnime(){ function startAnime(){
@@ -34,7 +34,7 @@
// var _stage = new createjs.Stage('edlp-map'); // var _stage = new createjs.Stage('edlp-map');
var _nodes = []; var _nodes = [];
// var _particules = []; // var _particules = [];
var _p_radius = 3; // nodes radius (real radius, not diametre) var _base_radius = 3; // nodes radius (real radius, not diametre)
var _p_velocity_factor = 0.5; var _p_velocity_factor = 0.5;
var _m_pos = {x:0, y:0}; var _m_pos = {x:0, y:0};
var _node_hover_id = -1; var _node_hover_id = -1;
@@ -129,7 +129,7 @@
this.debug = d; this.debug = d;
this.mass = 8; this.mass = 8;
this.base_radius = _p_radius; this.base_radius = _base_radius;
this.g = { this.g = {
l : 1, // drawing line width l : 1, // drawing line width
s : 1 // drawing space between squares s : 1 // drawing space between squares
@@ -145,6 +145,7 @@
this.y = this.wall_limits.top + Math.random()*(this.wall_limits.bottom - this.wall_limits.top); this.y = this.wall_limits.top + Math.random()*(this.wall_limits.bottom - this.wall_limits.top);
this.hover = false; this.hover = false;
// physics // physics
this.p = _physics.makeParticle(this.mass, this.x, this.y); this.p = _physics.makeParticle(this.mass, this.x, this.y);
this.p.velocity = new Physics.Vector((Math.random()-0.5)*_p_velocity_factor, (Math.random()-0.5)*_p_velocity_factor); this.p.velocity = new Physics.Vector((Math.random()-0.5)*_p_velocity_factor, (Math.random()-0.5)*_p_velocity_factor);
@@ -206,7 +207,7 @@
&& _m_pos.y > this.y - this.real_radius && _m_pos.y > this.y - this.real_radius
&& _m_pos.y < this.y + this.real_radius){ && _m_pos.y < this.y + this.real_radius){
if(_node_hover_id == -1 || _node_hover_id == this.id){ if(_node_hover_id == -1 || _node_hover_id == this.id){
console.log("Node hover", this.id); // console.log("Node hover", this.id);
this.hover = true; this.hover = true;
this.highlightEntries(); this.highlightEntries();
_node_hover_id = this.id; _node_hover_id = this.id;
@@ -235,7 +236,7 @@
_ctx.beginPath(); _ctx.beginPath();
_ctx.lineWidth = this.g.l*2;//this.hover ? this.g.l*2 : this.g.l; _ctx.lineWidth = this.g.l*2;//this.hover ? this.g.l*2 : this.g.l;
var r,d; var r,d;
for (var i = 0; i < this.entrees.length; i++) { for (let i = 0; i < this.entrees.length; i++) {
// _ctx.fillStyle = i == 0 ? _entrees_colors[this.entrees[i]] : "#fff"; // _ctx.fillStyle = i == 0 ? _entrees_colors[this.entrees[i]] : "#fff";
// _ctx.strokeStyle = _entrees_colors[this.entrees[i]]; // _ctx.strokeStyle = _entrees_colors[this.entrees[i]];
_ctx.fillStyle = i == 0 ? edlp_vars['e_col_'+this.entrees[i]] : "#fff"; _ctx.fillStyle = i == 0 ? edlp_vars['e_col_'+this.entrees[i]] : "#fff";
@@ -266,53 +267,70 @@
// / ____/ / / / /_/ (__ ) / /__(__ ) // / ____/ / / / /_/ (__ ) / /__(__ )
// /_/ /_/ /_/\__, /____/_/\___/____/ // /_/ /_/ /_/\__, /____/_/\___/____/
// /____/ // /____/
// TODO: how to use particule collision in new OOP Node() contexte // TODO: we may convert a lot of computation into a web worker https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
function checkParticulesCollisions(){ function checkParticulesCollisions(){
// pre create vars to save memory;
var node_a, node_b, p_a, p_b,
d, full_rad,
newVelX1, newVelY1, newVelX2, newVelY2,
makeup, angle;
// colisions between _particules // colisions between _particules
for (var p = 0, l = _particules.length; p < l; p++) { for (var n = 0, l = _nodes.length; n < l; n++) {
var particule = _particules[p]; node_a = _nodes[n];
// var theta = 360 / (Math.PI * _p_radius); p_a = node_a.p;
if(!particule.attracted) continue; // console.log(`p_a`, p_a.attracted);
for (var q = 0; q < p; q++) { // var theta = 360 / (Math.PI * _base_radius);
if(q==p) continue; // if(!p_a.attracted) continue;
// console.log('test');
for (var q = 0; q < n; q++) {
if(q===n) continue;
var a = particule; node_b = _nodes[q];
var b = _particules[q]; p_b = node_b.p;
if(!b.attracted) continue; // if(!p_b.attracted) continue;
var d = a.distanceTo(b); d = p_a.distanceTo(p_b);
full_rad = node_a.real_radius + node_b.real_radius;
// if not colliding skip following
if(d > full_rad) continue;
// apply new forces if colliding // apply new forces if colliding
if(d <= _p_radius*2){ newVelX1 = (p_a.velocity.x * (p_a.mass - p_b.mass)
+ (2 * p_b.mass * p_b.velocity.x)) / (p_a.mass + p_b.mass);
newVelY1 = (p_a.velocity.y * (p_a.mass - p_b.mass)
+ (2 * p_b.mass * p_b.velocity.y)) / (p_a.mass + p_b.mass);
newVelX2 = (p_b.velocity.x * (p_b.mass - p_a.mass)
+ (2 * p_a.mass * p_a.velocity.x)) / (p_a.mass + p_b.mass);
newVelY2 = (p_b.velocity.y * (p_b.mass - p_a.mass)
+ (2 * p_a.mass * p_a.velocity.y)) / (p_a.mass + p_b.mass);
var newVelX1 = (a.velocity.x * (a.mass - b.mass) + (2 * b.mass * b.velocity.x)) / (a.mass + b.mass); p_a.velocity.x = newVelX1;
var newVelY1 = (a.velocity.y * (a.mass - b.mass) + (2 * b.mass * b.velocity.y)) / (a.mass + b.mass); p_a.velocity.y = newVelY1;
var newVelX2 = (b.velocity.x * (b.mass - a.mass) + (2 * a.mass * a.velocity.x)) / (a.mass + b.mass); p_b.velocity.x = newVelX2;
var newVelY2 = (b.velocity.y * (b.mass - a.mass) + (2 * a.mass * a.velocity.y)) / (a.mass + b.mass); p_b.velocity.y = newVelY2;
a.velocity.x = newVelX1; p_a.velocity.multiplyScalar(0.75);
a.velocity.y = newVelY1; p_b.velocity.multiplyScalar(0.75);
b.velocity.x = newVelX2;
b.velocity.y = newVelY2;
a.velocity.multiplyScalar(0.75);
b.velocity.multiplyScalar(0.75);
// move particles if they overlap // move particles if they overlap
if (d < _p_radius*2) { if (d < full_rad) {
var makeup = _p_radius - d/2; makeup = full_rad/2 - d/2;
var angle = Math.atan2(b.position.y - a.position.y, b.position.x - a.position.x); angle = Math.atan2(p_b.position.y - p_a.position.y, p_b.position.x - p_a.position.x);
b.position.x += makeup * Math.cos(angle); p_b.position.x += makeup * Math.cos(angle);
b.position.y += makeup * Math.sin(angle); p_b.position.y += makeup * Math.sin(angle);
angle += Math.PI; angle += Math.PI;
a.position.x += makeup * Math.cos(angle); p_a.position.x += makeup * Math.cos(angle);
a.position.y += makeup * Math.sin(angle); p_a.position.y += makeup * Math.sin(angle);
}
} }
_nodes[n].p = p_a;
_nodes[q].p = p_b;
} }
} }
}; };
@@ -326,7 +344,7 @@
_$canvas _$canvas
.on('mousemove', function(event) { .on('mousemove', function(event) {
event.preventDefault(); event.preventDefault();
console.log("onMouseMove"); // console.log("onMouseMove");
_m_pos.x = event.originalEvent.clientX; _m_pos.x = event.originalEvent.clientX;
_m_pos.y = event.originalEvent.clientY; _m_pos.y = event.originalEvent.clientY;
// console.log("/ _ / - / _ /"); // console.log("/ _ / - / _ /");
@@ -369,14 +387,17 @@
function render(){ function render(){
_ctx.clearRect(0, 0, _canvas.width, _canvas.height); _ctx.clearRect(0, 0, _canvas.width, _canvas.height);
checkParticulesCollisions();
for (var i = 0; i < _nodes.length; i++) { for (var i = 0; i < _nodes.length; i++) {
_nodes[i].onUpdate(); _nodes[i].onUpdate();
} }
if(_node_hover_id != -1){ // if(_node_hover_id != -1){
_canvas.style.cursor = 'pointer'; // _canvas.style.cursor = 'pointer';
}else{ // }else{
_canvas.style.cursor = 'auto'; // _canvas.style.cursor = 'auto';
} // }
_canvas.style.cursor = _node_hover_id != -1 ? 'pointer' : 'auto';
}; };
function startAnime(){ function startAnime(){
@@ -1211,7 +1211,6 @@ main[role="main"] .layout-content {
overflow: hidden; } overflow: hidden; }
main[role="main"] .layout-content .row .col { main[role="main"] .layout-content .row .col {
pointer-events: all; pointer-events: all;
height: 100%;
position: relative; } position: relative; }
main[role="main"] .layout-content .row .col > .wrapper { main[role="main"] .layout-content .row .col > .wrapper {
position: relative; position: relative;
@@ -110,7 +110,7 @@ main[role="main"]{
overflow: hidden; overflow: hidden;
.col{ .col{
pointer-events:all; pointer-events:all;
height: 100%; // height: 100%;
position: relative; position: relative;
&>.wrapper{ &>.wrapper{
position: relative; position: relative;