Template:Team:Valencia Biocampus/Templates/js/simuelegans1.js

From 2013.igem.org

Raphael.fn.arrow = function(x1, y1, x2, y2, size) { var angle = Raphael.angle(x1, y1, x2, y2); var a45 = Raphael.rad(angle-45); var a45m = Raphael.rad(angle+45); var a135 = Raphael.rad(angle-135); var a135m = Raphael.rad(angle+135); var x1a = x1 + Math.cos(a135) * size; var y1a = y1 + Math.sin(a135) * size; var x1b = x1 + Math.cos(a135m) * size; var y1b = y1 + Math.sin(a135m) * size; var x2a = x2 + Math.cos(a45) * size; var y2a = y2 + Math.sin(a45) * size; var x2b = x2 + Math.cos(a45m) * size; var y2b = y2 + Math.sin(a45m) * size; return this.path( "M"+x1+" "+y1+"L"+x1a+" "+y1a+ "M"+x1+" "+y1+"L"+x1b+" "+y1b+ "M"+x1+" "+y1+"L"+x2+" "+y2+ "M"+x2+" "+y2+"L"+x2a+" "+y2a+ "M"+x2+" "+y2+"L"+x2b+" "+y2b ); };

simuelegans = function() {};

var initialx = -1; var initialy = -1;

var initialr; var initiala;


var canvas = Raphael("raphael", 500, 500); // Back canvas (contains the drawing)


var path_in_coords = new Array(); function xytopath(x, y){ var guide_path, path, full_path;

if(initialx==-1 && initialy==-1){ initialx = 0; initialy = 0; }

var path2return = new Array(x.length);

var tmpx, tmpy;

tmpx = (x[0] * plate.attrs.r / simulator.plate_radius + plate.attrs.cx); tmpy = (y[0] * plate.attrs.r / simulator.plate_radius + plate.attrs.cy);

path2return[-1] = "[\"M"+tmpx+","+tmpy+"\"";


for(var i =1; i<x.length ; i++){

tmpx = (x[i-1] * plate.attrs.r / simulator.plate_radius + plate.attrs.cx); tmpy = (y[i-1] * plate.attrs.r / simulator.plate_radius + plate.attrs.cy);

path2return[i-1] = "[\"M"+tmpx+","+tmpy+"\", ";

tmpx = (x[i] * plate.attrs.r / simulator.plate_radius + plate.attrs.cx); tmpy = (y[i] * plate.attrs.r / simulator.plate_radius + plate.attrs.cy);


path2return[i-1] += "\"L"+tmpx+","+tmpy+"\" ]";

path_in_coords.push({x: tmpx, y: tmpy});


} return path2return; }

function Attractant(x, y){ this.x = x; this.y = y; }

simuelegans.RandNorm = function(m, s){

this.mean = m; this.stdDev = s; this.isSpareReady = false; this.spare = 0; this.valuern = 0; }

simuelegans.RandNorm.prototype.getRandNorm = function() { if (this.isSpareReady) { this.isSpareReady = false; this.valuern = this.spare * this.stdDev + this.mean; } else { var u, v, s; do { u = Math.random() * 2 - 1; v = Math.random() * 2 - 1; s = u * u + v * v; } while (s >= 1 || s == 0); var mul = Math.sqrt(-2.0 * Math.log(s) / s); this.spare = v * mul; this.isSpareReady = true; this.valuern = this.mean + this.stdDev * u * mul; } return this.valuern; }; simuelegans.RandNorm = function(m, s){

this.mean = m; this.stdDev = s; this.isSpareReady = false; this.spare = 0; this.valuern = 0; }

simuelegans.RandNorm.prototype.getRandNorm = function() { if (this.isSpareReady) { this.isSpareReady = false; this.valuern = this.spare * this.stdDev + this.mean; } else { var u, v, s; do { u = Math.random() * 2 - 1; v = Math.random() * 2 - 1; s = u * u + v * v; } while (s >= 1 || s == 0); var mul = Math.sqrt(-2.0 * Math.log(s) / s); this.spare = v * mul; this.isSpareReady = true; this.valuern = this.mean + this.stdDev * u * mul; } return this.valuern; };

simuelegans.RandWalk = function(h, t, r0, a0){

this.tmax = t; this.h = h; a0 *= Math.PI / 180.0; this.x0 = r0 * Math.cos(a0); this.y0 = r0 * Math.sin(a0); this.tsize = this.tmax / h; this.x = new Array(this.tsize); this.y = new Array(this.tsize); this.v = new Array(this.tsize); this.g = new Array(this.tsize); this.dg = new Array(this.tsize); this.d = new Array(this.tsize); this.temp = new Array(this.tsize);

}


simuelegans.RandWalk.prototype.simulate = function(r0, a0) { //a0 *= Math.PI / 180.0; this.x0 = r0 * Math.cos(a0); this.y0 = r0 * Math.sin(a0); this.x[0] = this.x0; this.y[0] = this.y0; this.temp[0] = 0; this.v[0] = 0; this.g[0] = 2 * Math.PI * Math.random(); this.dg[0] = 0;


var rnd1 = new simuelegans.RandNorm(0.0152, 0.00702); var rnd2 = new simuelegans.RandNorm(0.861 * Math.PI / 180, 38.9 * Math.PI / 180); var rnd3 = new simuelegans.RandNorm(0.441 * Math.PI / 180, 2.12 * Math.PI / 180);

this.d[0] = rnd3.getRandNorm();

for (var i = 0; i < this.tsize - 1; i++) { this.temp[i + 1] = this.h * i; this.x[i + 1] = this.x[0] - 0.01; this.y[i + 1] = this.y[0] - 0.01; this.v[i + 1] = 0.01;

do { this.v[i + 1] = rnd1.getRandNorm();

           this.dg[i + 1] = rnd2.getRandNorm();

this.d[i + 1] = rnd3.getRandNorm();

var l = this.h * this.v[i + 1];

this.g[i + 1] = this.h * (this.dg[i + 1] + this.d[i + 1]) + this.g[i]; this.x[i + 1] = l * Math.cos(this.g[i + 1]) + this.x[i]; this.y[i + 1] = l * Math.sin(this.g[i + 1]) + this.y[i]; } while ((Math.sqrt(this.x[i + 1] * this.x[i + 1] + this.y[i + 1] * this.y[i + 1]) > simulator.plate_radius)); } }

var strpath; var path1; var pathcolor = {stroke : "#5a7881"};


var plate;

var circle; var arrow_radius; var arrow_title;

var c_elegans;


var gui = new dat.GUI({ autoPlace: false }); var customContainer = document.getElementById('simuelegans_gui'); customContainer.appendChild(gui.domElement);

function simulator(){ this.plate_radius = 1; this.steps = 2000; this.duration = 50; }


var simulator = new simulator();

 gui.add(simulator, 'plate_radius', 0.8, 4.5).name("Plate radius (cm)");
 gui.add(simulator, 'steps', 200, 4000).name("Duration ");

function initPlate(){ plate = canvas.circle(250, 250, 230); plate.attr("stroke", "#cac0b0"); plate.attr("fill", "#cac0b0"); plate.attr("fill-opacity", "0"); plate.attr("cursor", "crosshair"); plate.click(onclickplate); arrow_radius = canvas.arrow(250, 493, 470, 493, 10); arrow_title = canvas.text(360, 487, "Radius: "+simulator.plate_radius.toFixed(1)+"cm").attr({fill: '#000'}) }

function initCircle(x, y){ circle = canvas.circle(x, y, 3); circle.attr("stroke-width", 1); circle.attr("stroke", "#f00"); circle.attr("fill", "#f00");

//c_elegans = canvas.image("elegans.png", x - 120/7/2, y - 120/7/2, 120/7, 74/7); c_elegans = canvas.circle(x, y, 3); c_elegans.attr("stroke-width", 1); c_elegans.attr("stroke", "#5a7881"); }

function animateCircle(step, strpath){


if(step <= strpath.length){

path1 = canvas.path(strpath[step]).attr( { stroke: "#5a7881", fill: "none" });


//c_elegans.attr({guide : path1, along : 1}).animate({along : 0}, 50, "linear"); //c_elegans.attr({along: 0});

//c_elegans.rotate(Math.atan2(c_elegans.attrs.y, c_elegans.attrs.x))


c_elegans.animate({ cx: path_in_coords[step+1].x, cy: path_in_coords[step+1].y}, 50);


path1.animate({path: strpath[step+1]}, 50, function(){ animateCircle(step+1, strpath); }) }


} function simndraw(x, y){

initialx = x ; initialy = y;



initialr = (Math.sqrt( (initialx - plate.attrs.cx )*(initialx - plate.attrs.cx ) + (initialy - plate.attrs.cy)*(initialy - plate.attrs.cy ) ) / plate.attrs.r) * simulator.plate_radius;

initiala = Math.atan2(initialy - plate.attrs.cy, initialx - plate.attrs.cx)


rw = new simuelegans.RandWalk(1.0, simulator.steps.toFixed(), initialr, initiala);


rw.simulate(initialr, initiala);



strpath = xytopath(rw.x, rw.y);

animateCircle(-1, strpath);


}


var x0, y0;


initPlate(); initCircle(plate.attrs.cx, plate.attrs.cy); simndraw(plate.attrs.cx, plate.attrs.cy); var rw;

function onclickplate(e) {


circle.remove(); path1.remove(); path_in_coords.length = 0; canvas.clear();

initPlate();

x0 = e.clientX - $("#raphael").offset().left; y0 = e.clientY - $("#raphael").offset().top;


simndraw(x0, y0); initCircle(x0, y0);

circle.toFront(); plate.toFront();


};