Path-following
by roman01la
HTML
<script src="http://static.tumblr.com/m2xstox/Qavmutvbs/gl-matrix-min.js"></script>
<canvas class="viewport" width=480 height=320></canvas>
CSS
body {
margin: 0;
padding: 0;
overflow: hidden;
}
canvas {
background: #eee;
}
JavaScript
var Path = function() {
this.points = [];
this.radius = 0;
this.addPoint = function (x, y) {
var point = vec2.fromValues(x, y);
this.points.push(point);
};
this.display = function() {
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = '#e7e7e7';
ctx.lineWidth = this.radius * 2;
ctx.beginPath();
for (var i = 0; i < this.points.length; i++) {
ctx.lineTo(this.points[i][0], this.points[i][1]);
}
ctx.closePath();
ctx.stroke();
};
};
var Vehicle = function (location, mass) {
this.location = location;
this.initMass = mass;
this.mass = mass;
this.maxspeed = 4 * 1 / this.mass;
this.maxforce = 1 / (this.mass * this.maxspeed);
this.radius = this.mass * 2;
this.acceleration = vec2.create();
this.velocity = vec2.fromValues(this.maxspeed, 0);
this.bouncesNum = 0;
this.applyBehaviors = function (vehicles, path) {
var f = this.follow(path);
var s = this.separate(vehicles);
if (this.bouncesNum >= 300 && this.bouncesNum % 100 === 0) {
if (this.maxspeed < 3) {
this.maxspeed += 0.1;
this.maxforce += 0.1;
}
}
vec2.scale(f, f, 2);
vec2.scale(s, s, 4);
var forces = vec2.add(vec2.create(), f, s);
vec2.scale(forces, forces, 1/this.mass);
this.applyForce(forces);
};
this.applyForce = function (force) {
vec2.add(this.acceleration, this.acceleration, force);
};
this.run = function() {
this.update();
this.borders();
this.render();
};
this.follow = function (path) {
var predict = vec2.clone(this.velocity);
vec2.normalize(predict, predict);
vec2.scale(predict, predict, 25);
var predictLoc = vec2.create();
vec2.add(predictLoc, predictLoc, this.location);
vec2.add(predictLoc, predictLoc, predict);
var normal = null;
var target = null;
var worldRecord = 1000000;
for (var i = 0; i < path.points.length; i++) {
var a = vec2.clone(path.points[i]);
...