再来看看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

Now read this

Play With KDTree

— source code in this page lies here 最近工作中实现了基于KDTree的3D空间划分,用于实时判断Mesh和Ray的相交,我现在依然惊讶于这个算法的优美和高效。 还是先从工作中逃离一会,试试用Clojure实现一下2D-KDtree,然后在quil框架来些与工作无关的东西看看。 先生成3000个点吧: (def pts (repeatedly 3000 #(vec2 (q/random (q/width)) (q/random... Continue →