Почему мои бои стремятся к мировому происхождению, когда соответствуют скорости?

У меня проблема с реализацией псевдокода Конрада Паркера.

Я реализую правило1, правило2 и правило3. Проблема в том, что всякий раз, когда правило 3 активно (то есть matchSpeed ​​в моем коде ниже), боиды стремятся к центру мира (0, 0, 0), а затем стекаются вокруг этого места. Это происходит независимо от того, где они начинаются в мире.

Но когда rule3 не работает, boids стекаются и дрейфуют, как и ожидалось. Что я делаю неправильно?

Мой код написан на Scala, и я использую jMonkeyEngine, но я подозреваю, что проблема носит общий характер.

  val sepDistance = 10f
  val clumpFactor = 100f
  val avoidFactor = 3f
  val alignFactor = 800f

  val speedLimit = 2f

  def moveAgents(target: Node)
  {
    agents.foreach(a => {
      a.velocity.addLocal(clump(a))        //rule1
      a.velocity.addLocal(keepAway(a))     //rule2
      a.velocity.addLocal(matchSpeed(a))   //rule3
      a.velocity = limitSpeed(a.velocity)
      a.move(a.velocity)
      })
  }

  def clump (a: Agent): Vector3f = // rule1
  {
    val centre = Vector3f.ZERO.clone
    for (oA <- agents if oA != a) yield 
      centre.addLocal(oA.position)

    centre.divideLocal(agents.length.toFloat - 1f)
    centre.subtractLocal(a.position)
    centre.divideLocal(clumpFactor)
    return centre
  }

  def keepAway (a: Agent): Vector3f = // rule2
  {
    val keepAway = Vector3f.ZERO.clone
    for (oA <- agents if oA != a) {
      if (Math.abs(oA.position.distance(a.position)) < sepDistance) 
        keepAway.subtractLocal(oA.position.subtract(a.position))
    }

    return keepAway.divide(avoidFactor)
  }

  def matchSpeed (a: Agent): Vector3f = // rule3
  {
    val matchSpeed = Vector3f.ZERO.clone
    for (oA <- agents if oA != a)
      matchSpeed.addLocal(oA.velocity)

    matchSpeed.divideLocal(agents.length.toFloat - 1f)
    matchSpeed.subtractLocal(a.position)
    matchSpeed.divideLocal(alignFactor)

    return matchSpeed
  }

1 ответ

Решение

Проблема состоит в том, что метод matchSpeed ​​вычитает положение фокального стержня из средней скорости, а не его скорости.

Так:

matchSpeed.subtractLocal(a.position)

Должно быть:

matchSpeed.subtractLocal(a.velocity)
Другие вопросы по тегам