If you're seeing this message, it means we're having trouble loading external resources on our website.

如果你被网页过滤器挡住,请确保域名*.kastatic.org*.kasandbox.org 没有被阻止.

主要内容

相互吸引

希望你会发现从简单的场景开始 一个对象吸引另一个对象 ,到 一个对象吸引很多对象 对理解很有帮助。但是,你可能会发现更复杂的情况 很多对象互相吸引 。换句话说,这个系统中的每个对象都在吸引该系统中的所有对象(除了它本身)。
我们几乎已经做完这个情况的所有工作了。让我们考虑一个包含Mover 对象数组的程序:
var movers = [];

for (var i = 0; i < 5; i++) {
    movers[i] = new Mover(
        random(0.1, 2),
        random(width),
        random(height));
}

draw = function() {
    background(255, 255, 255);
    for (var i = 0; i < movers.length; i++) {
        movers[i].update();
        movers[i].display();
    }
};
draw() 函数是我们需要施展一些魔术的地方。 目前,我们说:“对于每个 mover i,更新并显示自己。” 现在我们需要说的是:“对于每个mover i,被每一个mover j吸引,更新并显示自己。”
for (var i = 0; i < movers.length; i++) {
    // 检查每个Mover
    for (var j = 0; j < movers.length; j++) {
        var force = movers[j].calculateAttraction(movers[i]);
        movers[i].applyForce(force);
    }
}

for (var i = 0; i < movers.length; i++) {
    movers[i].update();
    movers[i].display();
}
注意我们在更新并显示的基础上建立了一个全新的 for 循环。这是因为我们想要确保计算 所有 吸引力 之前 更新每个mover。如果我们不小心更新了第一个 for 循环中的每个mover,那么之后的吸引力运算将会被影响,变得不再精确。
我们的代码还没有完成,因为我们需要每个 Mover 对象拥有一个 calculateAttraction() 方法来计算吸引力。在之前的例子中,我们有 Attractor 对象中的 calculateAttraction()方法。现在,因为我们的movers在吸引movers,我们要将这个方法复制到Mover 对象中:
Mover.prototype.calculateAttraction = function(m) {
  var force = PVector.sub(this.position, m.position);
  var distance = force.mag();
  distance = constrain(distance, 5.0, 25.0);                        
  force.normalize();

  var strength = (G * this.mass * m.mass) / (distance * distance);
  force.mult(strength);
  return force;
};
当然,这里有一个小问题。当我们在看每个mover i和每个mover j,我们考虑了i等于j的情况吗? 比如说,mover #3 应该吸引 mover #3吗?答案当然是不。如果我们有五个对象,我们只应该让mover #3吸引 0,1,2,和4号,跳过它自己。然而我们想要计算并应用mover #3作用到mover #1的力以及mover #1作用到mover #3的力。计算出来的力应该是相等的,但是作用后的加速度会根据各自的质量和不同。我们的吸引力表格应该是这样子的:
0 ⇢ 1, 2, 3, 4
1 ⇢ 0, 2, 3, 4
2 ⇢ 0, 1, 3, 4
3 ⇢ 0, 1, 2, 4
因此,我们通过修改 for 循环来完成这个例子,以便内部的循环会防止mover吸引自己。
for (var i = 0; i < movers.length; i++) {
    for (var j = 0; j < movers.length; j++) {
       if (i !== j) {
         var force = movers[j].calculateAttraction(movers[i]);
         movers[i].applyForce(force);
       }
    }
}
让我们将所有内容整合起来:

“自然模拟”系列课程是由 Daniel Shiffman 的 "编程的本质" 衍生而来,基于 知识共享 著名-非商用性 3.0 本地化许可协议

想加入讨论吗?

尚无帖子。
你会英语吗?单击此处查看更多可汗学院英文版的讨论.