8
votes

Comment transformer la souris Emplacement dans la carte de carrelage isométrique?

Donc, je me suis réussi à écrire la première partie (algorithme) pour calculer la position de chaque tuile où devrait-elle être placée tout en dessinant cette carte (voir ci-dessous). Cependant, je dois être capable de convertir l'emplacement de la souris vers la cellule appropriée et je tire presque mes cheveux parce que je ne pouvais pas comprendre comment obtenir la cellule de la souris. Mon inquiétude est que cela implique des mathématiques assez élevées ou quelque chose que je suis juste quelque chose de facile, je ne suis pas capable de remarquer.
Par exemple, si la position de la souris est 112; 35 Comment puis-je calculer / le transformer pour obtenir que la cellule est 2; 3 à cette position? Peut-être y a-t-il un très bon programmateur de pensée en mathématiques ici qui m'aiderait à ce sujet ou à quelqu'un qui sait comment le faire ou peut donner des informations?

 Entrez la description de l'image ici xxx

parle de la carte, chaque cellule (tuile transparente 56x28 pixels) est Placé au centre de la cellule précédente (ou à la position zéro pour la cellule 1; 1), ci-dessus est le code que j'utilise pour convertir la cellule-position. J'ai essayé beaucoup de choses et de calculs pour la position à cellule, mais chacun d'entre eux a échoué.

EDIT: Après avoir lu beaucoup d'informations il semble que l'utilisation de la carte de couleur d'écran désactivée (où les couleurs sont mappées sur des carreaux) est la solution la plus rapide et la plus efficace?


2 commentaires

Qu'est-ce que tu utilises pour dessiner? De nombreux frameworks graphiques (comme OpenGL) ont des méthodes d'assistance pour transformer la transformée de la souris au monde pour vous.


Voir Q: détection de clic-in-a-2d-isométrique-grille


6 Réponses :


7
votes
[1/56 -1/28  1 ]
[1/56  1/28  1 ]
[0      0    1 ]

x = 1/56*x` - 1/28y` + 1
y = 1/56*x` + 1/28y` + 1

12 commentaires

EN.Wikipedia.org/wiki/transformation_matrix .. Fondamentalement si vous connaissez un côté de la transformation , il est facile d'obtenir de l'autre côté .. Vous avez donc V * A = V` .. Multipliez A (-1) des deux côtés et vous obtenez V * 1 = V` * A (-1)


Qu'est-ce que je transforme? L'ensemble de la carte entière pour le rendre rectangle basé sur le rectangle, puis facile à calculer la cellule?


Existe-t-il un moyen de calculer la position de la souris à la cellule avec des mathématiques sans avoir à faire pivoter l'image de la carte?


@Yochai Timmer belle solution. N'est-ce pas juste une transformation affine?


Une telle transformation serait également une précision de pixel? Et à quel point il serait efficace de faire ces transformations sur le mouvement de la souris enveloppée?


@Richards: Si ce que vous nous avez donné est la transformation précise que vous deviez dessiner la carte, cela devrait alors être la transformation inverse et fonctionner sur n'importe quel pixel.


@Nikiton: Oui, c'est une transformation affine, mais il vaut mieux comprendre les mathématiques que de regarder aveuglément l'explication mathématique d'une transformation affine: EN.Wikipedia.org/wiki/affine_transformation


@Yochai, "transformation précise" Vous voulez dire la formule pour obtenir la position de dessiner la carte de mon message principal?


@Yochai, aussi cela transformerait-il l'ensemble de la carte entière ou s'applique uniquement à la transformation de la position de la souris?


@Richards: Cela fonctionne sur une paire de coordonnées (x, y). Pour transformer toute la carte, vous devez calculer pour toute la carte. La transformation consiste à calculer la position d'un pixel.


Je suppose que cela la bonne façon pour la table de transformation, mais je vais faire une nouvelle question concernant comment implémenter cela dans ActionScript 3 en Flash. Merci!


@Yochai je sais que c'est un vieux fil mais j'ai besoin de l'information. Mon problème est avec le math x` = 28x -28 + 28Y -28 = 28x + 28Y -48 ne devrait-il pas être x` = 28x -28 + 28Y -28 = 28x + 28Y -56? qui changerait tout? Donc, la finale X / Y serait-elle ce x = 1/56 * x` - 1 / 28Y` + 1 y = 1/56 * x` + 1 / 28Y` + 1 et je ne suis pas sûr de ce que x` et y `Sont-il seulement 1/256 * (28x + 28Y-56) +1/28 (-14x + 14Y) +1?



0
votes

Une manière de le faire pivoter à une projection carrée:

Traduire d'abord y afin que les dimensions soient relatives à l'origine: P>

 a = atan(2/1);   
 x_tile = x1 * cos(a) - y1 * sin(a);
 y_tile = y1 * cos(a) + x1 * sin(a);


3 commentaires

Rotation de l'image de la carte entière oui? Pour le faire rectangle basé sur le rectangle?


Vous n'auriez pas vraiment à faire pivoter toute la carte. Appliquez simplement la rotation à l'emplacement de la souris et vous obtenez l'emplacement équivalent en coordonnées comme si la carte avait été tournée. Cependant, je pense que la réponse de YOCHAI est une solution plus pratique.


Cela s'applique-t-il aussi la rotation de la souris dans l'exemple de @ Yochai? Ou pas? Parce que je ne vois pas comment puis-je incliner ou faire pivoter l'emplacement de la souris, par exemple (112,35).



0
votes

Bien que vous ne l'avez pas mentionné dans votre question initiale, je pense que vous avez dit que vous avez programmé cela en flash. Auquel cas Flash est livré avec des fonctions de transformation matricielle. La manière la plus robuste de convertir entre les systèmes de coordonnées (par exemple, sur les coordonnées isométriques) utilise des transformations matricielles:

http: //help.adobe. COM / EN_US / Flashplatform / Référence / ActionScript / 3 / Flash / Geom / matrix.html

Vous voudriez faire pivoter et mettre à l'échelle la matrice dans l'inverse de la pivotation et l'échec des graphiques.


0 commentaires

1
votes

J'ai trouvé un algorithme sur ce site http: //www.tonyypa.pri. ee / tbw / tut18.html . Je ne pouvais pas le faire travailler correctement pour moi, mais je le change d'essai et d'erreur à ce formulaire et cela fonctionne pour moi maintenant.

for(int x=0;x<max_X;x++)
for(int y=0;y<max_Y;y++)
map.drawImage(image, ((max_X - 1) * tile.width / 2) - ((tile.width - 1) / 2 * (y - x)), ((tile.height - 1) / 2) * (y + x));


0 commentaires

4
votes

Entrez la description de l'image ici

J'ai rendu les tuiles comme ci-dessus.

La Sollution est très simple!

première chose:

Ma largeur de tuile et ma hauteur sont toutes deux = 32 Cela signifie que dans la vue isométrique, la largeur = 32 et la hauteur = 16! La cartaphonique dans ce cas est de 5 (valeur max. Y)

y_iso & x_iso == 0 lorsque y_mouse = maillottight / tuileWidth / 2 et x_mouse = 0

Lorsque x_mouse + = 1, y_iso - = 1

Donc, tout d'abord, je calculez la "transformation par pixel"

Tiley = ((Y_Mouse * 2) - ((Mapheight * TileWidth) / 2) + x_mouse) / 2;

TILEX = X_Mouse-Tiley;

Pour trouver les coordonnées de tuiles, je viens de dévier les deux par TileWidth

Tiley = Tiley / 32; TILEX = TILEX / 32;

fait !! jamais eu aucun problème!


1 commentaires

Merci pour cela, recherchez une solution pour les âges!



11
votes

Je sais que c'est un ancien poste, mais je veux mettre à jour cela puisque certaines personnes pourraient toujours rechercher des réponses à cette question, comme j'étais plus tôt aujourd'hui. Cependant, je me suis compris moi-même. Il existe également un bien meilleur moyen de le rendre de sorte que vous ne recevez pas de tuiles qui se chevauchent de problèmes.

Le code est aussi simple que ceci: p> xxx pré>

souris_x code> et souris_y code> sont des coordonnées de l'écran de la souris. p>

tuile_height code> et tuile_width code> est la taille de tuile réelle, pas l'image lui-même. Comme vous le voyez sur mon exemple, j'ai ajouté de la saleté sous ma carreau, il s'agit simplement d'un rendu plus facile, la taille réelle est de 24 x 12. Les coordonnées sont également "plantées" pour garder la grille de résultat x et y arrondis. p>

remarquez également que je rends ces tuiles à partir du y = 0 et x = tuile_with / 2 (point rouge). Cela signifie que mon 0,0 commence réellement au coin supérieur de la tuile (inclinée) et non en plein air. Consultez ces carreaux sous forme de carrés rotatifs, vous souhaitez toujours commencer à partir de 0,0 pixel. P>

Les tuiles seront rendues commencées par le Y = 0 et X = 0 pour la taille de la carte. Après la première ligne, vous avez rendu, vous sautez quelques pixels vers le bas et à gauche. Cela rendra la prochaine ligne de carreaux chevauchant le premier, ce qui constitue un excellent moyen de conserver les couches qui se chevauchent coorectement. Vous devriez restituer des carreaux, alors tout ce que vous avez sur cette tuile avant de passer à la suivante. P>

Je vais également ajouter un exemple de rendu également: P>

for (yy = 0; yy < map_height; yy++)
{
     for (xx = 0; xx < map_width; xx++)
     {
          draw tiles here with tile coordinates:
          tile_x = (xx * 12) - (yy * 12) - (tile_width / 2)
          tile_y = (yy * 6) + (xx * 6)

          also draw whatever is on this tile here before moving on
     }
}


0 commentaires