Поле зрения XNA в 2D - PullRequest
       44

Поле зрения XNA в 2D

4 голосов
/ 09 ноября 2010

Я работаю над 2D-игрой в XNA, основанной на флокировании.Я реализовал технику флокирования Крейга Рейнольда, и теперь я хочу динамически назначить лидера в группу, чтобы направить его к цели.

Для этого я хочу найти игрового агента, у которого нет другогоагенты перед ним и делают его лидером, но я не уверен в математике для этого.

В настоящее время у меня есть:

Vector2 separation = agentContext.Entity.Position - otherAgent.Entity.Position;

float angleToAgent = (float) Math.Atan2(separation.Y, separation.X);
float angleDifference = Math.Abs(agentContext.Entity.Rotation - angleToAgent);
bool isVisible = angleDifference >= 0 && angleDifference <= agentContext.ViewAngle;

agentContext.ViewAngle - это значения в радианах, которые у меня естьиграл, чтобы попытаться получить правильный эффект, но это в основном приводит к тому, что все агенты назначаются лидерами.

Может ли кто-нибудь указать мне правильное направление, чтобы определить, находится ли объект в «конусе» зрения другогообъект

Ответы [ 2 ]

1 голос
/ 11 ноября 2010

Вам необходимо нормализовать вход для функции Atan2.Также вы должны быть осторожны при вычитании углов, потому что результат может быть вне диапазона от пи до -pi.Я предпочитаю использовать векторы направления, а не углы, чтобы вы могли использовать операцию точечного произведения для такого рода вещей, поскольку это имеет тенденцию быть быстрее, и вам не нужно беспокоиться об углах вне канонического диапазона.

Следующий код должен достичь желаемого результата:

    double CanonizeAngle(double angle)
    {
        if (angle > Math.PI)
        {
            do
            {
                angle -= MathHelper.TwoPi;
            }
            while (angle > Math.PI);
        }
        else if (angle < -Math.PI)
        {
            do
            {
                angle += MathHelper.TwoPi;
            } while (angle < -Math.PI);
        }

        return angle;
    }

    double VectorToAngle(Vector2 vector)
    {
        Vector2 direction = Vector2.Normalize(vector);
        return Math.Atan2(direction.Y, direction.X);
    }

    bool IsPointWithinCone(Vector2 point, Vector2 conePosition, double coneAngle, double coneSize)
    {
        double toPoint = VectorToAngle(point - conePosition);
        double angleDifference = CanonizeAngle(coneAngle - toPoint);
        double halfConeSize = coneSize * 0.5f;

        return angleDifference >= -halfConeSize && angleDifference <= halfConeSize;
    }
1 голос
/ 09 ноября 2010

Я думаю, что вы хотите проверить угол +/-, а не только + (т.е. angleDifference >= -ViewAngle/2 && angleDifference <= ViewAngle/2).Или используйте абсолютное значение.

...