美文网首页
群体行为(不要碰到对方)

群体行为(不要碰到对方)

作者: 大龙10 | 来源:发表于2022-07-10 17:01 被阅读0次

书名:代码本色:用编程模拟自然系统
作者:Daniel Shiffman
译者:周晗彬
ISBN:978-7-115-36947-5
第6章目录

6.11 群/体行为(不要碰到对方)

1、ArrayList

  • 在粒子系统类中,我们用ArrayList存放粒子的列表。我们会在本例中做同样的事情:把一组Vehicle对象存放到ArrayList中。
ArrayList<Vehicle> vehicles;   声明由小车对象组成的ArrayList
void setup() {
    vehicles = new ArrayList<Vehicle>; 用一系列小车对象填充ArrayList
    for (int i = 0; i < 100; i++) {
        vehicles.add(new Vehicle(random(width),random(height)));
    }
}

2、draw()函数

  • 如果要在draw()函数中处理所有小车对象,只需遍历这个ArrayList,并在对象上调用相应的方法。
void draw(){
      for (Vehicle v : vehicles) {
          v.update();
          v.display();
      }
}

3、添加行为

  • 我们要为小车添加一种行为。比如让小车寻找鼠标所在的目标位置:
v.seek(mouseX, mouseY);
  • 但这只是个体的行为,前面我们一直在研究个体的行为,现在要研究群体行为。让我们从分离(separate)行为开始。分离行为等同于以下命令:“请不要和你的邻居发生碰撞!”
v.separate();
  • 这个函数还有些问题,我们还少了一些东西。分离指的是“从其他个体上分开”,其他个体指的是列表中的其他小车。
v.separate(vehicles);

4、群体行为的实现

  • 相比于粒子系统,本例有很大不同。在粒子系统中,个体(粒子或小车)单独运作;
    但在本例中,我们会告诉个体:“现在轮到你操作了,你需要考虑系统中的每个个体,所以我要向你传入一个ArrayList,里面存放了所有其他个体。”
  • 为了实现群体行为,我们用以下代码实现setup()函数和draw()函数。
ArrayList&lt;Vehicle> vehicles;
void setup() {
    size(320,240);
    vehicles = new ArrayList&lt;Vehicle>();
    for (int i = 0; i < 100; i++) {
          vehicles.add(new Vehicle(random(width),random(height)));
      }
}
void draw() {
      background(255);
      for (Vehicle v : vehicles) {
          v.separate(vehicles); 这是本节加入的新东西,小车在计算分离转向力时需要检查其他所有对
          v.update();
          v.display();
      }
}

5、转向力

  • 这只是一个开头,真正的操作在separate()函数中实现。我们先思考这个函数的实现方式。Reynolds提到:“用转向避免拥堵”,也就是说,如果某辆小车和你的距离太近,你应该转向以远离它。对此你是否觉得很熟悉?“寻找行为”指的是朝着目标转向,将“寻找行为”的转向力反转,就能得到躲避行为的转向力。


    图6-33
  • 但如果同时有多辆小车的距离都很近,这时候该怎么做?在这种情况下,我们可以对所有远离小车的向量求平均值,用平均向量计算分离行为的转向力。


    图6-34

6、separate()函数的实现

  • 下面我们开始实现separate()函数,它的参数是一个ArrayList对象,里面存放了所有小车对象。
  • 在这个函数中,我们要遍历所有的小车,检查它们是否过于接近。
    float desiredseparation = 20; 这个变量指定最短距离
    for (Vehicle other : vehicles) {
        float d = PVector.dist(location, other.location); 当前小车和其他小车之间的距离
        if ((d > 0) && (d < desiredseparation)) { 如果小车的距离小于20像素,这里的代码就会执行
        }
    }

注意:在上面的代码中,我们不只检查距离是否小于desiredseparation(过于接近!),还要检查距离是否大于0。这么做是为了确保小车不会意图和自身分离。所有小车对象都在ArrayList中,一不小心你就会让一辆小车与自身发生比较。

  • 一旦发现和某辆小车过于接近,我们就应该记录远离这辆小车的向量。
if ((d > 0) && (d < desiredseparation)) {
      PVector diff = PVector.sub(location, other.location); 一个指向远离其他小车方向的向量
      diff.normalize();
}
  • 有了这个diff向量还不够,我们还要针对每辆靠近的小车计算diff向量,再计算它们的平均向量。将所有向量加在一起,再除以总数,就可以得到平均向量!
PVector sum = new PVector(); 从一个空向量开始
int count = 0;
for (Vehicle other : vehicles) { 我们还要记录有多少辆小车的距离过近
    float d = PVector.dist(location, other.location);
    if ((d > 0) && (d < desiredseparation)) {
        PVector diff = PVector.sub(location, other.location);
        diff.normalize();
        sum.add(diff); 将所有向量加在一起,并递增计数器
        count++;
      }
}
if (count > 0) { 必须确保至少找到一辆距离过近的小车,然后才执行除法操作(避免除零的情况!)
      sum.div(count);
}
  • 有了平均向量(sum向量)之后,我们将它延伸至最大速率,就可以得到所需速度——希望小车以最大速率朝着这个方向运动!一旦有了所需速度,我们就可以根据Reynolds的公式计算转向力:
    转向力 = 所需速度 - 当前速度。
if (count > 0) {
      sum.div(count);
      sum.setMag(maxspeed); 延伸至最大速率(使其成为所需速度)
      PVector steer = PVector.sub(sum,vel); Reynolds的转向力公式
      steer.limit(maxforce);
      applyForce(steer); 将力转化为小车的加速度
}

7、示例

示例代码6-7 群集行为:分离

void separate (ArrayList&lt;Vehicle> vehicles) {
      float desiredseparation = r*2; 分离的距离取决于小车的尺寸
      PVector sum = new PVector();
      int count = 0;
      for (Vehicle other : vehicles) {
            float d = PVector.dist(location, other.location);
            if ((d > 0) && (d < desiredseparation)) {
                  PVector diff = PVector.sub(location, other.location);
                  diff.normalize();
                  diff.div(d); 计算小车和其他小车之间的距离:距离越近,分离的幅度越大;距离越远,分离sum.add(diff);
                  count++;
              }
        }
        if (count > 0) {
            sum.div(count);
            sum.normalize();
            sum.mult(maxspeed);
            PVector steer = PVector.sub(sum, vel);
            steer.limit(maxforce);
            applyForce(steer);
        }
}

8、运行结果

相关文章

  • 群体行为(不要碰到对方)

    书名:代码本色:用编程模拟自然系统作者:Daniel Shiffman译者:周晗彬ISBN:978-7-115-3...

  • 请停止这样聊天

    相信很多人在聊天的时都会碰到这样的情况,当你说如何如何的时候,对方说不要这样,不要那样,这样不好,那样不好...

  • 16平台99.9%的人都喜欢这样的标题

    ? Hello,我是图卡师霍小编,用图卡传递知识,与你一起成长。 ? 林桂枝 《秒赞》 ⭐用群体行为来促使对方行动...

  • 摘录

    4.1 如果碰到对方爱憎分明,而且要求你跟他站在同一阵线,你只能让对方尽情宣泄他的不满。但是你要控制一下,不要忘形...

  • 群体行为

    第一在群体之间有很强大的传染性 传染,它对群体特征的外在表现起着决定性的作用,同时也决定着它们所呈现出的趋势。传染...

  • 社会心理学中的群体行为几项表现

    第一,群体行为有这些特征:冲动,易怒,不懂得思考,缺乏判断力,夸大感情。群体行为会笼统看待事物,分不清细微的区别,...

  • 不要伤害对方

    一段关系中,时间不是绝对因素。你说你们认识好几年,但没有深层次的沟通交流,也没有为彼此提供一些价值(例如情绪价、提...

  • 不要沦为群体行为下的工具人

    去个性化是由费斯廷格等人提出的。意思是,在群体中,人们有时会感到自己被淹没在群体之中,于是个人意识和理解评价感丧失...

  • 追逐热点投资对不对?羊群效应

    群体行为研究人与人的互动,加总以后的行为表现。个人投资者行为为何受他人影响,怎么正确看待群体行为并避免自己的错误。...

  • 碰到陌生人,先给予对方

    生活中,我们不知不觉就和一个素不相识的人僵持,也不知道为什么就开始互相伤害。但是,我们可能不知道,对方也在这么想。...

网友评论

      本文标题:群体行为(不要碰到对方)

      本文链接:https://www.haomeiwen.com/subject/tyjybrtx.html