2011-09-09 29 views
15

Estoy tratando de aplanar matriz 3D en matriz 1D para el sistema "trozo" en mi juego. Es un juego de bloques en 3D y, básicamente, quiero que el sistema de fragmentos sea casi idéntico al sistema de Minecraft (sin embargo, esto no es un clon de Minecraft por ninguna medida). En mis anteriores 2D-juegos que he accedido a la gama aplanado con algoritmo siguiente:¿Cómo "aplanar" o "indexar" 3D-array en 1D array?

Tiles[x + y * WIDTH] 

Sin embargo, esto obviamente no funciona con 3D, ya que le falta el eje Z. No tengo idea de cómo implementar este tipo de algoritmo en el espacio 3D. El ancho, la altura y la profundidad son todas constantes (y el ancho es tan grande como la altura).

¿Es solo x + y*WIDTH + Z*DEPTH? Soy bastante malo con las matemáticas y recién comienzo la programación en 3D, así que estoy bastante perdido: |

PS. La razón de esto es que estoy haciendo bucles y obteniendo cosas por índice bastante. Sé que las matrices 1D son más rápidas que las matrices multidimensionales (por razones que no puedo recordar: P). Aunque esto puede no ser necesario, quiero el mejor rendimiento posible :)

+0

Estoy en lo correcto al decir que desea una matriz 3D que se encaja en un arr 1D ¿sí? – DMan

+1

¿Por qué no solo usa una matriz 3D? – svick

+0

@DMan Sí, lo eres :) Siempre explico todo de la manera más dura y larga, así que no hay sorpresa que no entiendas: P – flai

Respuesta

24

El algoritmo es casi el mismo. Si usted tiene una matriz 3D Original[HEIGHT, WIDTH, DEPTH] entonces se podría convertirlo en Flat[HEIGHT * WIDTH * DEPTH] por

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

Dicho sea de paso, se debe preferir matrices de matrices sobre matrices multidimensionales en .NET. Las diferencias de rendimiento son significativas

+3

¿Podría indicar alguna fuente que discuta las diferencias de rendimiento? Además, no debe basar sus decisiones solo en el rendimiento. – svick

+0

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

+0

@svick: Algunas fuentes se pueden ver en los enlaces de hacha proporcionados. Mi nota de rendimiento fue solo un aparte y no la sugerencia principal. Las matrices dentadas tienen una sintaxis casi idéntica (original [x] [y] [z]), pero requieren más trabajo para inicializarse. Sin embargo, los beneficios de rendimiento pueden ser bastante notorios (aceleración de 2 a 5 veces) según el uso. –

5

Ya casi está. Es necesario multiplicar por Z WIDTH y DEPTH:

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

x + y*WIDTH + Z*WIDTH*DEPTH. Visualícelo como un sólido rectangular: primero recorre x, luego cada y es una "línea" width pasos largos, y cada z es un "plano" WIDTH*DEPTH pasos en el área.

13

Creo que lo anterior necesita una pequeña corrección. Digamos que tienes una ALTURA de 10, y un ANCHO de 90, una matriz dimensional única será de 900. Por la lógica anterior, si estás en el último elemento de la matriz 9 + 89 * 89, obviamente esto es mayor que 900.El algoritmo correcto es:

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

Irónicamente si la ALTURA> ancho que no va a experimentar un desbordamiento, simplemente complete resultados Bonkers;)

+3

No puedo votar ni comentar sobre el respuesta correcta real, pero Martin lo tiene correcto, la respuesta seleccionada actual es incorrecta. Esencialmente: datos [x] [y] [z] = datos [x + y * maxX + z * maxX * maxY] – jking

+0

sí, la respuesta actual es incorrecta, debe ser altura no profundidad. Me tomó demasiado tiempo resolver esto ya que es la primera vez que usé una respuesta SO incorrecta para codificar algo>. < – chilleo

0

Para comprender mejor descripción de la matriz 3D en 1D matriz sería de (I supongo Profundidad en la mejor respuesta se entiende el tamaño Y)

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

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

Aquí es una solución en Java que proporciona tanto:

  • de 3D a 1D
  • de 1D a 3D

a continuación es una ilustración gráfica de la trayectoria he elegido para atravesar la matriz 3D, las células están numeradas en el orden de recorrido:

2 Examples of 3D matrices

funciones de conversión:

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 }; 
}