Permalink
Browse files

Merge pull request #38 from jmaygarden/master

This is just to keep in sync.
  • Loading branch information...
2 parents 6549621 + 02656fe commit 7264f0a8714e270255001382c584d768f0e5e259 @derekgates derekgates committed May 7, 2012
Showing with 131 additions and 47 deletions.
  1. +127 −46 Experiments/coltest.js
  2. +3 −0 Experiments/libjudge.js
  3. +1 −1 Tanks.js
View
173 Experiments/coltest.js
@@ -15,30 +15,31 @@ var getNextColor = (function() {
hue = (hue + 23.0) % 360.0;
- return 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
+ return "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";
}
})();
-function Box(x, y) {
+function Boid(x, y) {
var state = new PhysicsState();
state.position[0] = x;
state.position[1] = y;
- state.momentum[0] = 40.0 * Math.random() - 20.0;
- state.momentum[1] = -90.0 * Math.random() - 45.0;
+ state.momentum[0] = 50.0 * Math.random() - 25.0;
+ state.momentum[1] = -30.0 * Math.random() - 120.0;
state.recalculate();
this.color = getNextColor();
this.state = state;
}
-Box.prototype = {
- width: 10,
- height: 10,
+Boid.prototype = {
+ radius: 5,
render: function(ctx) {
+ ctx.beginPath();
+ ctx.arc(this.state.position[0], this.state.position[1], this.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = this.color;
- ctx.fillRect(this.state.position[0], this.state.position[1], this.width, this.height);
+ ctx.fill();
},
forces: function(state, t) {
@@ -52,60 +53,140 @@ Box.prototype = {
return box.forces(state, t);
});
- if (canvas.height - 10 < this.state.position[1]) {
- this.state.position[1] = canvas.height - 11;
+ if (canvas.width < this.state.position[0] + this.radius) {
+ this.state.position[0] = canvas.width - this.radius;
+ this.state.momentum[0] = -0.2 * Math.abs(this.state.momentum[0]);
+ this.state.recalculate();
+
+ } else if (0 > this.state.position[0] - this.radius) {
+ this.state.position[0] = this.radius;
+ this.state.momentum[0] = 0.2 * Math.abs(this.state.momentum[0]);
+ this.state.recalculate();
+ }
+
+ if (canvas.height < this.state.position[1] + this.radius) {
+ this.state.position[1] = canvas.height - this.radius;
this.state.momentum[1] = -0.2 * Math.abs(this.state.momentum[1]);
this.state.recalculate();
+
+ } else if (0 > this.state.position[1] - this.radius) {
+ this.state.position[1] = this.radius;
+ this.state.momentum[1] = 0.2 * Math.abs(this.state.momentum[1]);
+ this.state.recalculate();
}
},
};
-(function() {
- setInterval((function() {
- var next = (new Date).getTime(),
- dt = TIMESTEP / 1000, max = 10,
- canvas = document.getElementById("canvas"),
- ctx = canvas.getContext("2d"),
- boxes = [],
- timer = 0.0;
+function collide(a, b) {
+ // separation vector
+ var n = V2.sub(b.state.position, a.state.position);
- canvas.width = window.innerWidth;
- canvas.height = window.innerHeight;
+ // distance between circle centres, squared
+ var d2 = V2.lengthSquared(n);
- function update() {
- timer += dt;
- if (0.5 < timer) {
- boxes.push(new Box(canvas.width * 0.5, canvas.height - 10.0));
- timer = 0.0;
- }
+ // combined radius squared
+ var r = b.radius + a.radius;
+ var r2 = r * r;
- for (var i = 0; i < boxes.length; ++i) {
- boxes[i].update((new Date).getTime() / 1000.0, dt)
- }
+ // circles too far apart
+ if(d2 > r2)
+ return false;
+
+ // distance between circle centres
+ var d = Math.sqrt(d2);
+
+ // normal of collision
+ V2.scale(n, 1 / d, n);
+
+ // penetration distance
+ var p = (r - d);
+
+ // separation vector
+ var s = V2.scale(n, p / (a.state.inverseMass + b.state.inverseMass));
+
+ // separate the circles
+ V2.sub(a.state.position, V2.scale(s, a.state.inverseMass), a.state.position);
+ V2.add(b.state.position, V2.scale(s, b.state.inverseMass), b.state.position);
+
+ // combines momentum
+ var v = V2.sub(b.state.momentum, a.state.momentum);
+
+ // impact momentum
+ var vn = V2.dot(v, n);
+
+ // obejcts are moving away. dont reflect momentum
+ if (vn > 0.0)
+ return true; // we did collide
+
+ // coefficient of restitution in range [0, 1].
+ var cor = 0.95;
+
+ // collision impulse
+ var j = -(1.0 + cor) * (vn) / (a.state.inverseMass + b.state.inverseMass);
+
+ // collision impusle vector
+ var impulse = V2.scale(n, j);
+
+ // change momentum of the circles
+ V2.sub(a.state.momentum, impulse, a.state.momentum);
+ V2.add(b.state.momentum, impulse, b.state.momentum);
+ a.state.recalculate();
+ b.state.recalculate();
+
+ // collision reported
+ return true;
+}
+
+window.onload = function() {
+ var next = (new Date).getTime(),
+ dt = TIMESTEP / 1000, max = 10,
+ canvas = document.getElementById("canvas"),
+ ctx = canvas.getContext("2d"),
+ boids = [],
+ timer = 0.0;
+
+ canvas.width = window.innerWidth;
+ canvas.height = window.innerHeight;
+
+ function update() {
+ timer += dt;
+ if (0.33 < timer) {
+ boids.push(new Boid(canvas.width * 0.5, canvas.height - 10.0));
+ timer = 0.0;
}
- function render() {
- ctx.fillStyle = 'black';
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- for (var i = 0; i < boxes.length; ++i) {
- boxes[i].render(ctx)
+ for (var i = 0; i < boids.length; ++i) {
+ boids[i].update((new Date).getTime() / 1000.0, dt)
+
+ for (var j = i + 1; j < boids.length; ++j) {
+ collide(boids[i], boids[j]);
}
}
+ }
- render();
+ function render() {
+ ctx.fillStyle = "black";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ for (var i = 0; i < boids.length; ++i) {
+ boids[i].render(ctx)
+ }
+ }
- return function() {
- var i = 0;
+ function step() {
+ var i = 0;
- while ((new Date).getTime() > next && i < max) {
- update();
- next += TIMESTEP;
- i++;
- }
+ window.requestAnimationFrame(step);
- if (0 < i)
- render();
+ while ((new Date).getTime() > next && i < max) {
+ update();
+ next += TIMESTEP;
+ i++;
}
- })(), 0);
-})();
+
+ if (0 < i)
+ render();
+ }
+
+ step();
+};
View
3 Experiments/libjudge.js
@@ -40,6 +40,9 @@ V2.scale = function V2_scale(a, k, r) {
r[1] = k * a[1];
return r;
}
+V2.dot = function(a, b) {
+ return a[0] * b[0] + a[1] * b[1];
+}
V2.lengthSquared = function V2_lengthSquared(a) {
return a[0] * a[0] + a[1] * a[1];
}
View
2 Tanks.js
@@ -1945,7 +1945,7 @@ function Tank(x_init, y_init, team, type, teamnum) {
{
canvasContext.lineTo(x2, y2);
var degrees = getAngleFromPoint(x2,y2,X,Y)/(Math.PI/180) + 180;
- //var xdist =
+ //var xdist =
}
}
else

0 comments on commit 7264f0a

Please sign in to comment.