Ligne de visée diagonale à deux coins

9

En ce moment, j'utilise l'algorithme de ligne de Bresenham pour la ligne de vue. Le problème est que j'ai trouvé un boîtier de bord où les joueurs peuvent regarder à travers les murs. Se produit lorsque le joueur regarde entre les deux coins d'un mur avec un espace de l'autre côté à des angles spécifiques.

Cas de bord de ligne de vue

Le résultat que je veux, c'est que la tuile entre deux murs soit marquée comme non valide.

Résultat désiré

Quel est le moyen le plus rapide de modifier l'algorithme de ligne de Bresenham pour résoudre ce problème? S'il n'y a pas de bonne solution, existe-t-il un algorithme mieux adapté? Toutes les idées sont les bienvenues. Veuillez noter que la solution devrait également être capable de prendre en charge la 3D.

Edit: Ma solution simple était de vérifier si les deux coins sont fermés lorsque les coordonnées x et y d'une ligne changent. Pour le code source de travail et une démonstration interactive du produit terminé, veuillez consulter http://ashblue.github.io/javascript-pathfinding/

Bleu cendré
la source
2
Cela fait-il une différence si vous changez de point de départ et de fin? Peut-être que vous pourriez alors accepter les résultats si les deux calculs renvoient une ligne de vue non obstruée. Vous pouvez également trouver certains des articles LOS utiles sur RogueBasin.
thalador
1
Quoi qu'il en soit, ces deux blocs noirs en diagonale à 4-5 ne sont pas connectés à un mur en premier lieu, et je dis cela parce que vous autorisez implicitement le mouvement en diagonale. Vous devez soit quadriller cette diagonale pour en faire un mur contigu, soit faire en sorte que votre marcheur de ligne s'éloigne de ses mouvements diagonaux au lieu de devenir purement diagonal comme 2-3 et 4-5.
Patrick Hughes
Le retourner semblait une bonne idée, mais cela ne résout pas le problème. La seule chose à laquelle je peux penser est de vérifier et de voir si l'un des deux coins est vide. Semble cher cependant.
Ash Blue
5
«Semble cher» n'est jamais une justification suffisante pour ne pas essayer quelque chose. «Sera trop cher» est généralement, en supposant que vous pouvez prouver que quelque chose sera trop lent.
Mokosha
3
Le seul changement à l'algorithme requis est que si X et Y changent à la même étape, changez d'abord X puis changez Y, cela éliminerait complètement les diagonales.
Patrick Hughes

Réponses:

7

Eric Lippert a écrit une excellente série sur la génération de lignes de visée en C # avec Shadow Casting sur une grille plane rectangulaire.

Entre autres questions, Eric a traité diverses questions auxquelles il faut répondre au sujet des exigences en matière de visibilité directe, qui donnent des résultats différents et donne des exemples de quelques résultats différents. Un des articles traite en profondeur d'une circonstance de "regarder au coin de la rue" qui s'est produite dans une première version de son algorithme.

J'ai adapté l'algorithme d'Eric à une grille hexagonale ici , et je l'ai utilisé avec succès sur de grandes grilles hexagonales (> 400 x 700) avec un rayon de visibilité étendu (> 60 hexs). Cette implémentation calcule et affiche un champ de vision complet aussi vite que je peux cligner des yeux, en utilisant un seul processeur i7. C'est certainement assez rapide pour toutes les utilisations auxquelles je m'attends.

Mise à jour - Ligne de visée avec élévation:
L'implémentation de la grille hexadécimale liée à ci-dessus calcule la ligne de visée avec élévation, pas seulement les obstacles. Les notes de documentation discutent également d'une décision supplémentaire qui doit être prise en ce qui concerne les calculs d'élévation: la hauteur cible et la hauteur de l'observateur. La sélection par défaut consiste à rendre les deux égaux, ce qui crée un champ de vision symétrique, mais le sol au sol et les observateurs au sol peuvent également être sélectionnés. (Le code est Open Source sous licence MIT)

Pieter Geerkens
la source
Je suis vraiment en train de creuser Shadow Casting, mais j'ai rencontré un problème. Ayant du mal à trouver des informations sur la mise à l'échelle de l'algorithme pour fonctionner avec un axe z. Désolé de le mentionner, mais avez-vous des ressources suggérées pour le faire fonctionner en 3D?
Ash Blue
@AshBlue: voir l'addenda ci
Pieter Geerkens
Je regarde votre base de code. Il contient beaucoup de choses, mais je ne semble pas trouver d'algorithme de dessin au trait de type Bresenham adapté aux hexagones. Le faites-vous avec LOS?
MLProgrammer-CiM
@EfEs: FieldOfView est l'objet renvoyé; ShadowCastingFov * .cs génère le champ de vision en projetant des ombres. Si vous avez des questions spécifiques sur le code, il est préférable de les poser dans la section Discussions du site; des questions plus générales, je suis heureux de répondre ici.
Pieter Geerkens
@PieterGeerkens Vous pouvez trouver la question ici gamedev.stackexchange.com/questions/57087/…
MLProgrammer-CiM
1

Que se passe-t-il si pour le calcul de la LOS, vous avez une grille distincte de «résolution plus élevée» qui remplit les espaces vides Je pensais à quelque chose comme ça:

entrez la description de l'image ici

La gauche est la section de bloc d'origine de 4 carrés.

La droite est la version "haute résolution", comme vous pouvez le voir, chaque carré d'origine a été subdivisé en quatres et l'un des coins a été rempli. Je ne suis pas sûr de l'algorithme pour le générer, mais il peut être pré-calculé de la carte actuelle.

Cela signifie que l'espace de coordonnées est quadruplé, mais je n'envisage pas que ce soit un problème de performance important.

Davy8
la source
Je suis sûr que la résolution la plus élevée aurait exactement la même apparence que l'original. Lorsque vous divisez une grille en une grille plus petite, vous obtenez la même représentation visuelle, juste avec une grille plus petite. Chaque carré devient simplement 4 carrés plus petits au même endroit.
MichaelHouse
@ Byte56 Correct, je voulais dire qu'une logique supplémentaire serait appliquée après la division pour ajouter les blocs supplémentaires à cette copie. La logique pour cela est un exercice laissé au lecteur.
Davy8
Vous pouvez facilement générer la grille haute résolution en brouillant l'original. Définissez ensuite un seuil de, disons, 0.5de remplissage ou non des cellules haute résolution. Ainsi, l'utilisation d'une grille haute résolution me semble assez hacky du tout.
danijar