Question

Je travaille sur un jeu 2D XNA basé autour de flocage. J'ai mis en flocage technique de Craig Reynold et maintenant je veux attribuer dynamiquement un chef de file au groupe pour le guider vers une cible.

Pour ce faire, je veux trouver un agent de jeu qui n'a pas d'autres agents devant elle et en font le leader, mais je ne suis pas sûr des mathématiques pour cela.

À l'heure actuelle je:

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 est une valeur radians que j'ai joué avec pour essayer d'obtenir l'effet escompté, mais cela se traduit surtout dans tous les agents affectés comme étant responsables.

point Quelqu'un peut-moi dans la bonne direction pour détecter si une entité est dans un « cône » de vue d'une autre entité?

Était-ce utile?

La solution

Vous devez normaliser l'entrée à la fonction atan2. Aussi, vous devez être prudent lors de la soustraction des angles car le résultat peut être hors de portée pi à -pi. Je préfère utiliser des vecteurs de direction plutôt que des angles de sorte que vous pouvez utiliser l'opération de produit de points pour ce genre de chose que ce qui tend à être plus rapide et vous n'avez pas à vous soucier des angles en dehors de la plage canonique.

Le code suivant devrait atteindre le résultat que vous êtes après:

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

Autres conseils

Je pense que vous voulez tester +/- angle, non seulement + (c.-à-angleDifference >= -ViewAngle/2 && angleDifference <= ViewAngle/2). Ou utiliser la valeur absolue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top