再来看看Flocking
Nature Of Code 这本书给我印象最深的就是Flocking示例, 当中的算法来源于Craig Reynolds 1986年 。
CodeOfNature很好的实现了该算法, 但是当中存在一些冗余的计算,以及为了清晰阐述Separation | Alignment | Cohesion这三条规则而采用分别遍历计算,对我来说,不够高效之余,还显得不够直观。这里我对该算法进行了简化。
Boid.prototype.steerToVel = function (desired) {
let steer = p5.Vector.sub(desired, this.velocity);
steer.limit(this.maxAcceleration);
return steer;
}
Boid.prototype.flock = function (boids) {
let sepRad = 25.0, aliRad = 50.0, cohRad = 50.0;
let sepCount = 0, aliCount = 0, cohCount = 0;
let sepAcc = createVector()
let aliAcc = createVector()
let cohAcc = createVector()
for (let i = 0; i < boids.length; i++) {
let diff = p5.Vector.sub(this.position, boids[i].position);
let d = diff.mag();
if (d === 0) continue;
if (d < sepRad) {
sepAcc.add(diff.normalize().div(d));
sepCount++;
}
if (d < aliRad) {
aliAcc.add(boids[i].velocity);
aliCount++;
}
if (d < cohRad) {
cohCount++;
cohAcc.add(boids[i].position);
}
}
let desiredVel
if (sepCount > 0 && sepAcc.mag() > 0) {
desiredVel = sepAcc.normalize().mult(this.maxspeed)
sepAcc = this.steerToVel(desiredVel);
}
if (aliCount > 0 && aliAcc.mag() > 0) {
desiredVel = aliAcc.normalize().mult(this.maxspeed)
aliAcc = this.steerToVel(desiredVel);
}
if (cohCount > 0 && cohAcc.mag() > 0) {
desiredVel = cohAcc
.div(cohCount)
.sub(this.position)
.normalize()
.mult(this.maxspeed)
cohAcc = this.steerToVel(desiredVel);
}
this.acceleration = sepAcc.mult(1.5).add(aliAcc).add(cohAcc);
}
Boid.prototype.update = function () {
this.velocity.add(this.acceleration).limit(this.maxspeed);
this.position.add(this.velocity);
}
3
Kudos
3
Kudos