Pregunta

Estoy trabajando en un juego 2D en XNA en torno flocado. He implementado Craig Reynolds de flocado técnica y ahora desee asignar dinámicamente un líder para el grupo para guiarla hacia un objetivo.

Para hacer esto, yo quiero encontrar un agente de juego que no tiene ningún otros agentes delante de él y lo convierten en el líder, pero estoy seguro de las matemáticas para ello.

Actualmente tengo:

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 es un archivo de valores radianes que he jugado con tratar de conseguir el efecto deseado, pero esto resulta en su mayoría todos los agentes están asignados como líderes.

me puede punto cualquiera en la dirección correcta para detectar si una entidad está dentro de un "cono" de vista de la otra entidad?

¿Fue útil?

Solución

necesidad de normalizar la entrada a la función Atan2. También hay que tener cuidado al restar ángulos porque el resultado puede estar fuera del rango pi-pi a. Yo prefiero usar vectores de dirección en lugar de ángulos para que pueda utilizar la operación de producto escalar para este tipo de cosas como que tiende a ser más rápido y usted no tiene que preocuparse de ángulos fuera del rango canónico.

El siguiente código debe lograr el resultado que está buscando:

    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;
    }

Otros consejos

Creo que desea probar +/- ángulo, no sólo + (es decir angleDifference >= -ViewAngle/2 && angleDifference <= ViewAngle/2). O utilizar valor absoluto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top