Domanda

Sto lavorando su un gioco in 2D in XNA basato intorno affollano. Ho implementato Craig Reynold di tecnica floccaggio e ora voglio assegnare dinamicamente un capo al gruppo per guidarlo verso un obiettivo.

Per fare questo, voglio trovare un agente di gioco che non ha altri agenti di fronte ad essa e lo rendono il leader, ma io sono sicuro della matematica per questo.

Attualmente ho:

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 è un valori radianti che ho giocato con per cercare di ottenere l'effetto giusto, ma questo si traduce per lo più in tutti gli agenti essere designato come leader.

Qualcuno può punto nella giusta direzione me per rilevare se un soggetto è all'interno di un "cono" di vista di un'altra entità?

È stato utile?

Soluzione

È necessario normalizzare l'input per la funzione atan2. Inoltre bisogna stare attenti quando sottraendo gli angoli, perché il risultato può essere al di fuori del campo di pi greco a-pi. Io preferisco usare vettori direzione piuttosto che gli angoli in modo da poter utilizzare l'operazione di prodotto scalare per questo genere di cose come che tende ad essere più veloce e non si deve preoccupare di angoli al di fuori della gamma canonica.

Il seguente codice dovrebbe raggiungere il risultato che stai cercando:

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

Altri suggerimenti

Credo che si desidera testare +/- angolo, non solo + (es angleDifference >= -ViewAngle/2 && angleDifference <= ViewAngle/2). Oppure utilizzare valore assoluto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top