web-dev-qa-db-fra.com

Algorithme de calcul d'une trajectoire de balle à une cible avec max. 2 ricochets

Désolé pour le vrai titre mais je n'avais pas de meilleure façon de le former ...

Donc, il y a Ce jeu étonnant de Nintendo (oui!) Sur Wii appelé WiiPlay . Il y a 9 mini-miniotes, et mon préféré est appelé tanks ! . Il s'agit de détruire des réservoirs ennemis de com sans vous détruire. Voici une capture d'écran d'un niveau:

enter image description here

Une façon de détruire des chars consiste à tirer des balles. Il y a ce réservoir ennemi vert citron-vert qui incendie des balles à grande vitesse qui ricochet (contre les murs et blocs) deux fois. Vous pouvez voir comment le réservoir de joueur peut être détruit instantanément s'il reste là où il se trouve maintenant, car ce réservoir de chaux au centre peut tirer une balle qui suit le chemin vert que j'ai dessiné sur l'image.

En tant que programmeur amateur, je me demandais comment le char de la chaux peut-il déterminer à quelle direction il devrait tirer dessus pour frapper le réservoir de joueur.

J'y ai pensé moi-même mais je n'ai pas trouvé d'algorithme possible. Je vais expliquer mes conclusions au cas où ils inspireront quelqu'un. Juste pour la simplicité pendant mon explication, je suppose un mur pour être toute surface contre laquelle une balle peut ricochet . Un rectangle isolé de blocs formant ainsi quatre murs.

J'ai conclu que les 2 points au cours desquels les ricachets de balle se trouvent toujours sur un côté d'un parallélogramme ou deviennent des sommets opposés d'un parallélogramme. Le réservoir ennemi de tir et le réservoir de joueur informatique ne sont pas nécessairement les 2 autres sommets, mais se trouvent certainement sur les lignes colinéaires à l'un des quatre côtés du parallélogramme. Voici une illustration des 4 manières possibles qu'un parallélogramme peut être formé:

enter image description here

Hor-Ver signifie que la balle frappe d'abord une paroi horizontale, puis il frappe une paroi verticale.

Et puis je suis coincé. J'ai pensé à se déplacer autour d'une ligne qui relie le réservoir ennemi et le réservoir de joueur autour de la carte pour voir s'il constitue un parallélogramme avec deux coups de parallèle avec n'importe quel mur, mais cela ne fonctionne pas toujours car le réservoir ennemi et le réservoir de joueur ne sont pas toujours. nécessairement une coïncidence avec les sommets du parallélogramme.

En outre, je ne suis pas sûr du flux général de l'algorithme. L'algorithme prend-il l'une des 2 structures suivantes, ou peut-être que je me trompe avec ces deux?

  • Continuez à déterminer les chemins possibles et marquez toujours un comme le meilleur (peut être le plus court, la plus obscure, la plus obscure, la plus inévitable, ou une évaluation combinée et pondérée basée sur plusieurs critères) et oubliez le reste. Celui qui reste après tout calcul est le meilleur à prendre.
  • Déterminez d'abord tous les murs d'abord accessibles avec la balle (la balle n'a pas besoin de ricochet contre aucun autre mur afin d'atteindre chacun de ces murs), puis de déterminer toutes les gammes accessibles sur chacun de ces murs (il est parfois impossible d'atteindre un point éloigné. Un mur sans ricochet Si un autre mur se situe près de vous), puis déterminez à nouveau toutes les murs accessibles avec un ricochet et toutes les gammes accessibles sur ces murs. Ces 4 procédés peuvent être effectués par une manière similaire à la traçabilité des rayons. Pendant chaque processus, si le réservoir de joueur est touché par n'importe quel rayon, déterminez le chemin de la balle selon ce rayon.

À mon avis, cet algorithme est difficile à comprendre parce que:

  • une balle peut être tirée dans n'importe quelle direction; et
  • il existe infiniment de nombreux points sur n'importe quel mur, comme en mathématiques, où il y a infiniment de points sur une ligne.

Mais Nintendo Les gens l'ont fait de toute façon, alors ... quiconque avec une idée?

21
hello all

Étant donné une ligne de vue directe, le problème est évidemment trivial. Cependant, nous avons affaire à la réflexion. Trouver correctement quelles parties de la scène sont perçues est difficile lors de la mise en œuvre de la réflexion dans le cadre d'un rayon traceur, car cela pourrait manquer des ouvertures. Une "recherche binaire" entre deux angles prometteurs n'est pas non viable: en raison des réflexions, l'espace réellement visible n'est pas continu, de sorte que la heuristique "Si c'est à droite de A et à la gauche de B, il doit y avoir une cible Solution entre A et B "est non autorisée et manqueront des solutions" créatives ". Je recommanderais plutôt de mettre en œuvre la réflexion en réorganisant le traceur d'une position virtuelle - la position où notre réservoir de cuisson semble Pour être vu dans le miroir:

target |obstacle
   X   |
    \  |  X real position
     \   /
      \ /
   ----------- mirror surface
        \
         \
          X virtual position

L'avantage est que le rayon miroir est maintenant une ligne droite provenant de la position virtuelle. J'ai essayé d'illustrer la technique dans le croquis suivant:

shooting around corners

X marque la position de tir, (x) la cible. Les zones colorées sont visibles.

  1. Ligne de visée directe: la cible n'est pas visible. Cependant, nous pouvons frapper des surfaces (1) et (2).

  2. Une réflexion. Il y a deux positions de tir virtuel dans les obstacles. La position la plus basse a direct LOS à la cible, nous avons donc notre première solution de tir: le chemin de la balle est la partie du rayon entre la cible et la surface du miroir inférieur, et entre le rayon point de collision miroir et la position de tir réel.

  3. Deux réflexions: la position virtuelle supérieure de la première réflexion peut voir une partie de l'obstacle inférieur à travers sa surface de miroir. Étant donné que deux réflexions sont autorisées, nous pouvons refléter cette position dans l'obstacle inférieur. Les positions sont marquées comme (i) la position réelle, (ii) la position virtuelle de la première réflexion, et (iii) la position virtuelle de la deuxième réflexion.

    De (iii), nous avons direct LOS à la cible (x), nous avons donc trouvé une autre solution de tir. Le chemin de bullet est le long de la ligne X-III jusqu'au deuxième point de collision de miroir, Ensuite, le long de la ligne III-II entre les points de collision miroir, et enfin le long de la ligne II-I du premier point de collision miroir à la position réelle I.

    En fait, la position virtuelle inférieure de la première réflexion pourrait également être reflétée dans l'obstacle supérieur, mais cela ne conduira à aucune solution directe.

Une fois que vous pouvez déterminer quelles parties des obstacles sont visibles (et peuvent donc être utilisées pour refléter la balle), mettre en œuvre la mise en miroir via une première recherche de profondeur semblerait simple. Pour trouver des surfaces de miroir appropriées, les techniques décrites dans Nicky Cash's's's's's's's's's's's's's's's's Sight & Light Peut être utilisé: plutôt que d'essayer 360 vecteurs - ce qui pourrait manquer des ouvertures, et c'est aussi PASSANT - Nous ne lancons que des rayons uniquement aux bords des obstacles.

9
amon

Il suffit de prolonger l'idée de Karl Bielefeldt pour une réflexion de 2 murs: -enter image description here

A et B sont donnés (les chars). Vous devez d'abord répertorier tous les murs qui peuvent voir et une liste de tous les murs b peuvent voir. Ensuite, vous faites des paires où le premier mur est dans la liste des poings et que le second mur est différent de la première paroi et se trouve dans la deuxième liste. Vous devez faire ce test pour toutes les paires de murs possibles (sauf si vous ne trouvez un moyen d'éliminer les candidats). Une fois que vous avez trouvé R et S pour une paire de murs donnée, vous vérifiez

1) Si une vision directe de r

2) Si r appartient au mur1 (le mur est juste un segment, pas de la ligne entière)

3) Si r a un accès direct à S

4) Si s appartient au mur2 (le mur est juste un segment, pas de la ligne entière)

5) Si S a un accès direct à B.

Pour trouver r et s: Etant donné que vous connaissez Wall1, vous pouvez déterminer l'équation de ligne tangente à Wall1, car R appartient à la ligne tangente au mur 1, vous avez une relation entre les 2 coordonnées de R (Se terminant par un degré de liberté pour R) de la même manière que s (vous avez une relation entre les coordonnées S puisque ce point appartient à la ligne tanget à Wall2). Ainsi, vous avez maintenant 2 degrés de liberté et vous devez avoir 2 autres équations indépendantes pour déterminer une solution. Une équation est:

(AA')/(RA')=(SS')/(RS')

l'autre équation est:

(BB')/(SB')=(RR')/(SR')

notez que dans les équations ci-dessus, A, A ', B, B', sont connus ou peuvent être calculés directement. R 'et S' sont la fonction des coordonnées de R et S et des équations murales. Je n'ai pas fini les mathématiques alors je ne sais pas comment les équations ressembleront.

7
Mandrill

Vous pouvez profiter du fait que l'angle sortant du ricochet doit être identique à celui de l'entrée. Pour une paroi horizontale donnée avec coordonnée Y c et deux réservoirs fixes avec des coordonnées (a,b) et (d,e), il n'y a qu'un seul angle qui satisfait à l'équation ci-dessous.

diagram of equation

Il suffit de résoudre x pour obtenir la distance le long du mur à laquelle vous devez visez. Deux murs fonctionnent de la même manière. Vous avez juste deux équations et deux inconnus.

3
Karl Bielefeldt