Skip to content

Instantly share code, notes, and snippets.

@adamnew123456
Created April 30, 2015 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamnew123456/df9d3fa35e638fcf412f to your computer and use it in GitHub Desktop.
Save adamnew123456/df9d3fa35e638fcf412f to your computer and use it in GitHub Desktop.
Crowd
<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