Алгоритм разделения C ++, показывающий странные результаты - PullRequest
0 голосов
/ 03 июня 2018

Я реализую простой алгоритм управления разделением (для выровненных по оси 2D-прямоугольников).Алгоритм:

  • Для каждого прямоугольника (ячейки), проверьте все остальные на перекрытие
  • , если перекрываются, рассчитайте разницу в векторах положения (вектор указывает на верхний левый угол прямоугольника)
  • добавить к общему вектору

в конце, сила (ускорение) применяется в направлении, противоположном общему вектору, и положение прямоугольника обновляется с каждым кадром.

Это логика разделения:

bool Cell::seperateFrom(CellsContainer& cells) {
    Vector2D force_sum;
    int neighbor_count = 0;
    for (auto& other : cells) {
        if (!(*this == other) && this->overlaps(other)) {
            Vector2D position_diff = this->position - other.position;
            //normalize
            position_diff /= (float)sqrt(std::pow(position_diff.x,2) + std::pow(position_diff.y,2));
            force_sum += position_diff;
            neighbor_count++;
        }
    }
    if (neighbor_count > 0) {
      // calculate steer away vector;
      Vector2D steering = force_sum - this->velocity;
      //normalize
      steering /= (float) sqrt(std::pow(steering.x,2) + std::pow(steering.y,2));
      //move by tile size units
      steering *= static_cast<float> (TILE_SIZE);
      this->addForce(steering);
      return true;
    } else {
        // not overlapping, stop moving
        this->velocity *= 0.0f;
        return false;
    }
}

Я начинаю со случайно сгенерированных случайно скомпонованных прямоугольников, и похоже, что разделение работает, однако результат очень направленный и не очень однородный по размеру прямоугольника (как видно ниже)), и я не понимаю, почему.

enter image description here

enter image description here

РЕДАКТИРОВАТЬ:

Функция updatePosition:

void Cell::updatePosition() {
    this->velocity += this->acceleration;
    this->position += this->velocity;
    this->rectangle.setPosition(this->position);
    this->acceleration *= 0.0f;
}

addForce:

  void addForce(const Vector2D& force)              {this->acceleration += force;}

Основной цикл:

void main_loop(WindowType& window, CellsContainer& cells) {
    while (true) {
        window.clear();
        for (auto& cell_obj : cells) {
            cell_obj.seperateFrom(cells);
            cell_obj.updatePosition();
            window.draw(cell_obj.getRectangle());
        }
        window.display();    
    }
}
...