C # / XNA - Оптимизация столкновений ограничивающих кругов (микро)?

Я работал над простым космическим шутером и дошел до того момента в проекте, когда мой ужасно написанный код действительно замедляет работу. После запуска EQATEC я вижу, что большая часть проблемы заключается в неприглядной проверке всего на всем при обнаружении столкновений. Я подумывал о установке QuadTree, но большинство столкновений происходит с астероидами, которые действительно много перемещаются (потребовало бы большого обновления). Следующей моей альтернативой была микрооптимизация самой проверки столкновений. Вот:

    public bool IsCircleColliding(GameObject obj) //simple bounding circle collision detection check
    {
        float distance = Vector2.Distance(this.WorldCenter, obj.WorldCenter);
        int totalradii = CollisionRadius + obj.CollisionRadius;

        if (distance < totalradii)
            return true;
        return false;
    }

Я слышал, что Vector2.Distance требует дорогостоящего Sqrt, так есть ли способ избежать этого? Или есть способ приблизить расстояние, используя какой-нибудь причудливый расчет? По сути, что-нибудь для большей скорости.

Кроме того, немного не связанный с фактическим вопросом, есть ли хороший метод (кроме QuadTrees) для пространственного разделения быстро движущихся объектов?


person Lexusjjss    schedule 13.05.2013    source источник


Ответы (1)


Вычислите квадрат расстояния вместо фактического расстояния и сравните его с квадратом порога столкновения. Это должно быть немного быстрее. Если большинство астероидов имеют одинаковый размер, вы можете повторно использовать одно и то же значение для порога столкновения без его пересчета.

Еще один полезный трюк - сначала выполнить простую проверку на основе ограничивающих прямоугольников и вычислить расстояние, только если ограничивающие прямоугольники пересекаются. Если они этого не делают, то вы знаете (по дешевке), что два объекта не сталкиваются.

person redtuna    schedule 13.05.2013
comment
Хорошо, заменил Vector2.Distance на DistanceSquared и умножил каждый радиус на себя, теперь радиусы столкновения, кажется, вышли из строя; все как бы тонут друг в друге. Я немного поиграю с точками останова. :П - person Lexusjjss; 14.05.2013
comment
вы должны возвести в квадрат общие радиусы, а не каждый радиус в отдельности. - person redtuna; 14.05.2013
comment
Ааа а теперь работает. Что ж, это заставляет меня чувствовать себя тупицей. Спасибо. - person Lexusjjss; 14.05.2013