2011-09-09 3 views
15

J'essaye d'aplatir la rangée 3D dans la rangée 1D pour le système de «morceau» dans mon jeu. C'est un jeu de blocs en 3D et je veux essentiellement que le système de morceaux soit presque identique au système de Minecraft (cependant, ce n'est pas un clone de Minecraft). Dans mes précédents 2D jeux que j'ai accédé au tableau aplaties avec l'algorithme suivant:Comment "aplatir" ou "indexer" un tableau 3D dans une matrice 1D?

Tiles[x + y * WIDTH] 

Cependant, cela ne fonctionne évidemment pas avec 3D car il manque l'axe Z. Je ne sais pas comment implémenter ce type d'algorithme dans l'espace 3D. La largeur, la hauteur et la profondeur sont toutes des constantes (et la largeur est tout aussi grande que la hauteur).

Est-il juste x + y*WIDTH + Z*DEPTH? Je suis assez mauvais avec les maths et je commence juste la programmation 3D donc je suis assez perdu: |

PS. La raison en est que je suis en train de faire des boucles et d'obtenir beaucoup de choses par index. Je sais que les tableaux 1D sont plus rapides que les tableaux multidimensionnels (pour des raisons que je ne me souviens pas: P). Même si cela peut ne pas être nécessaire, je veux aussi bonne performance que possible :)

+0

Ai-je raison de dire que vous voulez un tableau 3D à insérer dans un 1D arr oui? – DMan

+1

Pourquoi n'utilisez-vous pas simplement la matrice 3D? – svick

+0

@DMan Oui, vous êtes :) Je vous explique toujours tout de la manière la plus dure et la plus longue donc pas de surprise que vous n'avez pas compris: P – flai

Répondre

24

L'algorithme est essentiellement le même. Si vous avez un tableau 3D Original[HEIGHT, WIDTH, DEPTH] alors vous pouvez le transformer en Flat[HEIGHT * WIDTH * DEPTH] par

Flat[x + WIDTH * (y + DEPTH * z)] = Original[x, y, z] 

En aparté, vous devriez préférer des tableaux de tableaux sur les tableaux multidimensionnels dans .NET. Les différences de performance sont significatives

+3

Pourriez-vous pointer vers une source discutant des différences de performance? En outre, vous ne devriez pas baser vos décisions uniquement sur la performance. – svick

+0

http://stackoverflow.com/questions/597720/what-is-differences-between-multidimensional-array-and-array-of-arrays-in-c et http://stackoverflow.com/questions/468832/why -are-multi-dimensional-arrays-in-net-slow-than-normal-arrays – hatchet

+0

@svick: Certaines sources peuvent être vues dans la hache de liens fournie. Ma note de performance était seulement un aparté et non la suggestion principale. Les tableaux dentelés ont une syntaxe presque identique (original [x] [y] [z]), mais nécessitent plus de travail pour s'initialiser. Cependant, les avantages de performance peuvent devenir tout à fait perceptibles (accélération de 2-5x) en fonction de l'utilisation. –

5

Vous y êtes presque. Vous devez multiplier par Z WIDTHetDEPTH:

Tiles[x + y*WIDTH + Z*WIDTH*DEPTH] = elements[x][y][z]; // or elements[x,y,z] 
10

x + y*WIDTH + Z*WIDTH*DEPTH. Visualisez-le comme un solide rectangulaire: d'abord vous traversez le long de x, puis chaque y est une "ligne" width étapes de long, et chaque z est un "plan" WIDTH*DEPTH étapes dans la zone.

13

Je pense que ce qui précède a besoin d'une petite correction. Disons que vous avez une hauteur de 10, et une largeur de 90, tableau unidimensionnel sera 900. Selon la logique ci-dessus, si vous êtes au dernier élément sur le tableau 9 + 89 * 89, évidemment, il est supérieur à 900.L'algorithme correct est:

Flat[x + HEIGHT* (y + WIDTH* z)] = Original[x, y, z], assuming Original[HEIGHT,WIDTH,DEPTH] 

Ironie du sort si vous la HAUTEUR> WIDTH vous ne rencontrerez pas un trop-plein, il suffit de remplir les résultats Bonkers;)

+3

Je ne peux pas exprimer ou commenter vraie réponse correcte, mais Martin a raison, la réponse sélectionnée actuellement est fausse. Essentiellement: données [x] [y] [z] = données [x + y * maxX + z * maxX * maxY] – jking

+0

yep réponse actuelle est faux, devrait être la hauteur pas la profondeur. Il m'a fallu trop de temps pour comprendre cela car c'était la première fois que j'utilisais une mauvaise réponse SO pour coder quelque chose. – chilleo

0

Pour mieux comprendre la description du tableau 3D dans le tableau 1D serait (I deviner la profondeur dans la meilleure réponse est censée taille Y)

IndexArray = x + y * InSizeX + z * InSizeX * InSizeY; 

IndexArray = x + InSizeX * (y + z * InSizeY); 
15

Voici une solution en Java qui vous donne à la fois:

  • de 3D à 1D
  • de 1D à 3D

ci-dessous est une illustration graphique de la voie I choisi pour traverser la matrice 3D, les cellules sont numérotées dans l'ordre de traversée:

2 Examples of 3D matrices

fonctions de conversion:

public int to1D(int x, int y, int z) { 
    return (z * xMax * yMax) + (y * xMax) + x; 
} 

public int[] to3D(int idx) { 
    final int z = idx/(xMax * yMax); 
    idx -= (z * xMax * yMax); 
    final int y = idx/xMax; 
    final int x = idx % xMax; 
    return new int[]{ x, y, z }; 
} 
Questions connexes