Created
April 30, 2015 19:09
-
-
Save adamnew123456/df9d3fa35e638fcf412f to your computer and use it in GitHub Desktop.
Crowd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<canvas id="canvas" width="600" height="600"> | |
</canvas> </br> | |
Method: <input id="algorithm" type="text"> </input> <br/> | |
Timestep (Hz): <input id="timestep" type="text"> </input> <br/> | |
<input id="start_stop" type="button" value="Start" onclick="run()"> </input> <br/> | |
<script> | |
//////////////////// | |
var PERSON_RADIUS = 1; | |
var PERSON_SPEED = 5; | |
var PEOPLE = 100; | |
var STEPS = 200; | |
var SPEED_HZ = 15; | |
var SIM_IS_RUNNING = false; | |
var SIM_STEPS = 0; | |
var SIM_HANDLE = null; | |
function sim_started() { | |
SIM_IS_RUNNING = true; | |
SIM_STEPS = 0; | |
document.getElementById('start_stop').value = 'Stop'; | |
} | |
function sim_stopped(reporter) { | |
SIM_IS_RUNNING = false; | |
SIM_HANDLE = null; | |
document.getElementById('start_stop').value = 'Start'; | |
console.log(reporter.toString()); | |
} | |
function sim_wrapper(reporter, plotter, f) { | |
var stepper = function() { | |
if (SIM_STEPS < STEPS) { | |
plotter.reset(); | |
SIM_STEPS++; | |
f(); | |
SIM_HANDLE = setTimeout(stepper, 1000 / SPEED_HZ); | |
} else { | |
sim_stopped(reporter); | |
} | |
}; | |
sim_started(); | |
stepper(); | |
} | |
function randInt(min, max) { | |
return Math.floor(Math.random() * (max - min) + min); | |
} | |
var ReporterProto = { | |
collide: function(n) { | |
this.collissions += n; | |
}, | |
spawn: function(n) { | |
this.spawned += n; | |
}, | |
succeed: function(n) { | |
this.succeeded += n; | |
}, | |
toString: function() { | |
return "[" + this.succeeded + "/" + this.spawned + "] " + this.collissions; | |
} | |
}; | |
function newReporter() { | |
var obj = Object.create(ReporterProto); | |
obj.collissions = 0; | |
obj.spawned = 0; | |
obj.succeeded = 0; | |
return obj; | |
} | |
var PlotterProto = { | |
reset: (function() { | |
this.context.clearRect(0, 0, this.widget_width, this.widget_height); | |
}), | |
plot: (function(center_x, center_y) { | |
var left_x = center_x - PERSON_RADIUS; | |
var top_y = center_y - PERSON_RADIUS; | |
var width = PERSON_RADIUS * 2; | |
var height = PERSON_RADIUS * 2; | |
this.context.fillRect(left_x, top_y, width, height); | |
}) | |
}; | |
function newPlotter(canvas) { | |
var obj = Object.create(PlotterProto); | |
obj.widget_width = canvas.width; | |
obj.widget_height = canvas.height; | |
obj.context = canvas.getContext('2d'); | |
obj.context.fillStyle = 'blue'; | |
return obj; | |
} | |
// All the simulation algorithms, indexed by name | |
ALGORITHMS = {} | |
/** | |
* This planning algorithm just moves people about randomly. | |
*/ | |
ALGORITHMS.random = (function(reporter, plotter) { | |
var people_x = []; | |
var people_y = []; | |
console.log('Spawning...'); | |
for (var person = 0; person < PEOPLE; person++) { | |
people_x.push(randInt(200, 400)); | |
people_y.push(randInt(200, 400)); | |
} | |
reporter.spawn(PEOPLE); | |
var simulation = function() { | |
var succeeded = 0; | |
var collissions = 0; | |
var spawned = 0; | |
for (var person = 0; person < people_x.length; person++) { | |
people_x[person] += randInt(-PERSON_SPEED, PERSON_SPEED); | |
people_y[person] += randInt(-PERSON_SPEED, PERSON_SPEED); | |
var target = person % 2 == 0 ? 'up' : 'down'; | |
if ((people_y[person] < 0 && target == 'up') | |
|| people_y[person] > 600 && target == 'down') { | |
succeeded++; | |
spawned++; | |
people_x[person] = randInt(200, 400); | |
people_y[person] = randInt(200, 400); | |
} | |
plotter.plot(people_x[person], people_y[person]); | |
} | |
for (var person_A = 0; person_A < PEOPLE; person_A++) { | |
for (var person_B = 0; person_B < PEOPLE; person_B++) { | |
if (person_A == person_B) continue; | |
var a_x = people_x[person_A]; | |
var a_y = people_y[person_A]; | |
var b_x = people_x[person_B]; | |
var b_y = people_y[person_B]; | |
var dist = (Math.pow(a_x - b_x, 2) + Math.pow(a_y - b_y, 2)); | |
if (dist <= (PERSON_RADIUS * PERSON_RADIUS)) collissions++; | |
} | |
} | |
reporter.collide(collissions); | |
reporter.spawn(spawned); | |
reporter.succeed(succeeded); | |
}; | |
console.log('Running...'); | |
sim_wrapper(reporter, plotter, simulation); | |
}); | |
/** | |
* This planning algorithm moves the person up. | |
*/ | |
ALGORITHMS.upward = (function(reporter, plotter) { | |
var people_x = []; | |
var people_y = []; | |
console.log('Spawning...'); | |
for (var person = 0; person < PEOPLE; person++) { | |
people_x.push(randInt(200, 400)); | |
people_y.push(randInt(200, 400)); | |
} | |
reporter.spawn(PEOPLE); | |
var simulation = function() { | |
var succeeded = 0; | |
var collissions = 0; | |
var spawned = 0; | |
for (var person = 0; person < people_x.length; person++) { | |
var target = person % 2 == 0 ? 'up' : 'down'; | |
if (target == 'up') | |
people_y[person] -= PERSON_SPEED; | |
else | |
people_y[person] += PERSON_SPEED; | |
if ((people_y[person] < 0 && target == 'up') | |
|| people_y[person] > 600 && target == 'down') { | |
succeeded++; | |
spawned++; | |
people_x[person] = randInt(200, 400); | |
people_y[person] = randInt(200, 400); | |
} | |
plotter.plot(people_x[person], people_y[person]); | |
} | |
for (var person_A = 0; person_A < PEOPLE; person_A++) { | |
for (var person_B = 0; person_B < PEOPLE; person_B++) { | |
if (person_A == person_B) continue; | |
var a_x = people_x[person_A]; | |
var a_y = people_y[person_A]; | |
var b_x = people_x[person_B]; | |
var b_y = people_y[person_B]; | |
var dist = (Math.pow(a_x - b_x, 2) + Math.pow(a_y - b_y, 2)); | |
if (dist <= (PERSON_RADIUS * PERSON_RADIUS)) collissions++; | |
} | |
} | |
reporter.collide(collissions); | |
reporter.spawn(spawned); | |
reporter.succeed(succeeded); | |
}; | |
console.log('Running...'); | |
sim_wrapper(reporter, plotter, simulation); | |
}); | |
function idToValue(id) { | |
var e = document.getElementById(id); | |
if (!e) return null; | |
return e.value; | |
} | |
function run() { | |
if (SIM_IS_RUNNING) { | |
clearTimeout(SIM_HANDLE); | |
SIM_HANDLE = null; | |
return; | |
} | |
var alg = ALGORITHMS[idToValue('algorithm')]; | |
SPEED_HZ = Number(idToValue('timestep')); | |
var reporter = newReporter(); | |
var canvas = document.getElementById('canvas'); | |
var plotter = newPlotter(canvas); | |
console.log('Running ' + idToValue('algorithm') + ' at ' + SPEED_HZ + 'Hz'); | |
alg(reporter, plotter); | |
} | |
//////////////////// | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment