Je fais un jeu basé sur une grille 2D, avec certaines cellules passables et d'autres non. Les objets dynamiques peuvent se déplacer en continu, indépendamment de la grille, mais doivent entrer en collision avec des cellules infranchissables.
J'ai écrit un algorithme pour tracer un rayon sur la grille, qui me donne toutes les cellules que le rayon intersecte. Cependant, les objets réels ne sont pas de taille ponctuelle; Je les représente actuellement sous forme de cercles. Mais je ne peux pas trouver d'algorithme efficace pour tracer un cercle en mouvement. Voici une photo de ce dont j'ai besoin:
Les nombres indiquent dans quel ordre le cercle entre en collision avec les cellules de la grille. Quelqu'un connaît-il l'algorithme pour trouver ces collisions? De préférence en C #.
Mettre à jour Le cercle peut être plus grand qu'une seule cellule de grille.
la source
Réponses:
Je pense que votre dessin est un peu trompeur car vous choisissez de dessiner des traits à partir du point du cercle tangent à votre direction de déplacement. Je peux voir que les collisions avec les bords de votre grille se produisent lorsque les points HAUT et GAUCHE de votre cercle touchent un bord.
Soit C votre centre et r le rayon donc P ' = C + ( r , 0) et P " = C + (0, r).
Si D est votre vecteur de direction (le verseur), vous avez deux lignes:
R '= D · t + P' ,
R "= D · t + P"
Vous devez simplement trouver l'intersection de ces lignes avec les lignes d'équation:
y = i et y = i qui sont les bords de votre grille!
La solution est simple car il suffit de considérer la composante x ou y de R 'et R ". Vous trouverez la valeur t s pour chaque insertion, et les points pour ces t s, il vous suffit de trier ces points par t et vous sont fait.
Je crois que vous pouvez facilement dire quelle cellule est touchée si vous connaissez le point d'intersection.
Cela fonctionne si r <1 (la largeur et la hauteur des cellules).
Cela fonctionne également pour les autres cas en faisant simplement une réflexion sur P ' et P " . Nous choisissons TOP et LEFT en raison de la direction, BOTTOM et RIGHT doivent être pris en compte pour la direction opposée, vous comprenez pourquoi.
Regardez maintenant cette image:
Le cercle est plus grand qu'une seule cellule et nous supposons qu'il va dans la même direction que votre dessin. P1 est le premier point qui va toucher, P2 est le second, P3 est inutile car se trouve dans la moitié inférieure. Ce que vous devez faire est de projeter des rayons de P1 et P2 comme nous l'avons vu précédemment et de faire de même pour les lignes verticales.
En général, vous aurez d'autres points de départ avec le TOP et le GAUCHE d'où tirer vos rayons, plus votre cercle est grand, plus il y a de rayons à lancer.
Pour être honnête, vous pouvez éviter de tirer sur tous ces rayons en tenant compte de la géométrie, mais cela peut rendre les choses plus difficiles à comprendre.
la source
Si vous souhaitez utiliser votre algorithme de collision de rayons, vous pouvez choisir huit points sur chaque cercle (par incréments de 45 degrés, alignés avec votre grille carrée), et utiliser la collision de rayons entre les points correspondants (c'est-à-dire du haut d'un cercle en haut de l'autre). L'union de toutes ces collisions de rayons est l'ensemble des cellules intersectées.
Vous pourriez probablement améliorer un peu cela - par exemple en utilisant le segment de ligne du centre d'un cercle au centre de l'autre, mais prolongé de chaque côté par le rayon du cercle, ainsi que les segments de ligne parallèles sur de chaque côté aux extrémités des cercles.
la source
Je ne dis pas que c'est une analogie parfaite, mais vous pourriez penser à l' algorithme de ligne de Bresenham . Une modification de cet algorithme ou de l'une de ses extensions pourrait être utile, surtout si vous l'associez à certains des autres articles et commentaires. En règle générale, cet algorithme ne concerne pas la commande, mais je pense que vous seriez en mesure d'ajouter cela de manière assez triviale.
la source