{{ message }}

Instantly share code, notes, and snippets.

# HarryStevens/.block

Last active Jul 27, 2020
Good Boids
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

This is my version of Craig Reynolds’s boids, using Vladimir Agafonkin’s RBush as a spatial index to improve efficiency. Compare to Bad Boids.

Click and drag to add boids.

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

Alignment
1.0
Steer towards the average heading of local flockmates
Cohesion
1.0
Steer towards the average position of local flockmates
Separation
1.0
Steer to avoid crowding local flockmates
Perception
20
Maximum distance of other boids to consider
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
 // Add vector w to vector v function add(v, w) { let out = []; for (let i = 0; i < v.length; i++){ out[i] = v[i] + w[i]; } return out; } // Subtract vector w from vector v function sub(v, w) { let out = []; for (let i = 0; i < v.length; i++){ out[i] = v[i] - w[i]; } return out; } // Multiply vector v by w, either a vector of equal length or a number function mult(v, w) { let that = []; if (typeof w === "number"){ for (let i = 0; i < v.length; i++){ that[i] = w; } } else { that = w; } let out = []; for (let i = 0; i < v.length; i++){ out[i] = v[i] * that[i]; } return out; } // Divide vector v by w, either a vector of equal length or a number function div(v, w) { let that = []; if (typeof w === "number"){ for (let i = 0; i < v.length; i++){ that[i] = w; } } else { that = w; } let out = []; for (let i = 0; i < v.length; i++){ out[i] = v[i] / that[i]; } return out; } // Limit the magnitude of this vector to the value used for the n parameter. function limit(v, n) { let out = v; const sq = Math.pow(getMag(v), 2); if (sq > n * n){ out = div(out, Math.sqrt(sq)); out = mult(out, n); } return out; } // Normalize the vector to length 1 (make it a unit vector). function normalize(v) { const m = getMag(v), l = v.length; return m ? mult(v, 1 / m) : v.map(d => 1 / l); } // Get the magnitude of a vector function getMag(v) { let l = v.length, sums = 0; for (let i = 0; i < l; i++){ sums += v[i] * v[i]; } return Math.sqrt(sums); } // Set the magnitude of this vector to the value used for the n parameter. function setMag(v, n) { return mult(normalize(v), n); } // Angle from vector v to vector w in radians function ang(v, w) { return Math.atan2(w[1] - v[1], w[0] - v[0]); } // Distance from position of vector v to position of vector w in pixels function dist(v, w) { return Math.sqrt(Math.pow(w[0] - v[0], 2) + Math.pow(w[1] - v[1], 2)); } // Translate position of vector v by an angle in radians and a distance in pixels function trans(v, ang, dist) { return [v[0] + dist * Math.cos(ang), v[1] + dist * Math.sin(ang)]; } const vecmath = { add, sub, mult, div, limit, normalize, getMag, setMag, ang, dist, trans }