Voy a simplificar el problema en 2D, porque no se hacer arte ASCII en 3D, después lo extrapolamos a tres dimensiones.
Suponiendo una cuadrícula de 3×3:
0 1 2 3
0 +---+---+---+
| | | |
1 +---+---+---+
| | | |
2 +---+---+---+
| | | |
3 +---+---+---+
La celda en la coordenada (0, 0) tiene cuatro vértices: (0, 0), (0, 1), (1, 0), (1, 1). Con esto podemos extrapolar que dada una coordenada de celda, sus vértices serán todas las combinaciones de +1 vértice en todas las dimensiones:
| Celda | desplazamiento | vértices |
| (0, 0) | (0, 0), (0, 1), (1, 0), (1, 1) | (0, 0), (0, 1), (1, 0), (1, 1) |
| (0, 2) | (0, 0), (0, 1), (1, 0), (1, 1) | (0, 2), (0, 3), (1, 2), (1, 3) |
| (2, 2) | (0, 0), (0, 1), (1, 0), (1, 1) | (2, 2), (2, 3), (3, 2), (3, 3) |
En 3D sucede igual. De hecho sucede igual en cualquier dimensión, la celda 3D en (0, 0, 0) tiene ocho vértices: (0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)
0,0,0 1,0,0
+---------+
/| /|
/ | / |
0,0,1 +---------+ | 1,0,1
0,1,0 | +------|--+ 1,1,0
| / | /
|/ |/
0,1,1 +---------+ 1,1,1
Sabiendo eso…
si lanzo aleatoriamente un punto deseo saber en qué cubo está usando sus coordenadas.
Un punto cualquiera (x, y, z) es un cubo compuesto por: (x, y, z), (x, y, z + 1), (z, y + 1, z), (x, y + 1, z + 1), (x + 1, y, z), (x + 1, y, z + 1), (x + 1, y + 1, z), (x + 1, y + 1, z + 1)
Edición 14-febrero-2020.
Para poder identificar cada celda por un índice, se pueden seguir las siguientes fórmulas:
Posición = (Ancho * Y) + X
X = Posición % Ancho
Y = Posición / Alto
+---+---+---+
| 0 | 1 | 2 |
+---+---+---+
| 3 | 4 | 5 |
+---+---+---+
| 6 | 7 | 8 |
+---+---+---+
Sabemos que la celda del centro de la cuadrícula 3×3 es 4 porque:
Posición = (3 × 1) + 1 ⇒ 4
Sabemos que la celda 7 es X = 1, Y = 2 porque:
X = (7 % 3) ⇒ 1, Y = (7 / 3) ⇒ 2
En tres dimensiones las fórmulas son:
Posición = (Ancho × Z) + (Ancho × Alto × Y) + X
X = Posición % Ancho
Y = Posición / (Ancho × Alto)
Z = (Posición / Ancho) % Alto
+---+---+---+\
| 0 | 1 | 2 | \
+---+---+---+ +---+---+---+\
| 9 | 10| 11| | 3 | 4 | 5 | \
+---+---+---+ +---+---+---+ +---+---+---+
| 18| 19| 20| | 12| 13| 14| | 6 | 7 | 8 |
+---+---+---+ +---+---+---+ +---+---+---+
\ | 21| 22| 23| | 15| 16| 17|
\+---+---+---+ +---+---+---+
\ | 24| 25| 26|
\+---+---+---+
Sabemos que la celda del centro de la cuadrícula 3×3×3 es 13 porque:
Posición = (3 × 1) + (3 × 3 × 1) + 1 ⇒ 3 + 9 + 1 ⇒ 13
Sabemos que la celda 16 es X = 1, Y = 1, Z = 2 porque:
X = 16 % 3 ⇒ 1, Y = 16 / (3 × 3) ⇒ 1, Z = (16 / 3) % 3 ⇒ 5 % 3 ⇒ 2
Detalles a tener en cuenta.
Tu código tiene errores y espacio de mejora:
- Las cabeceras
<stdio.h>
, <math.h>
, <stdlib.h>
y <conio.h>
pertenecen al lenguaje C, no al lenguaje C++. Si necesitases usarlas (que la mayoría de veces no es necesario y ciertamente no es tu caso) deberías usar la versión adaptada a C++; lee este hilo para más detalles.
- La definición
int Mcub[1][1][1]
crea una formación tridimensional de un elemento en cada dimensión. Es decir: en total tienes tres enteros (int
) y acceder a cualquier valor que no esté en el índice cero provocará comportamiento indefinido.
- No inicializas ninguna variable, y no usas las variables
X
, Y
ni Z
.
- La instrucción
Mcub[i][j][k];
no hace nada, además de estar accediendo a valores fuera de la formación, provocando comportamiento indefinido.
Edición 26-febrero-2020.
Voy a intentar responder a tus comentarios en mi respuesta, por favor añádelos a tu pregunta.
Lo que genera mi código es una estructura de 10 cubos a partir de las combinaciones de (i, j, k), estas combinaciones representan los vértices de los 10 cubos de tamaño 1, cada cubo tiene 8 vértices, cada vértice es un punto (i,j,k) que se relaciona con cubos diferentes; si lanzo un punto aleatoriamente y cae por ejemplo dentro del cubo número 6, este punto tendrá las mismas coordenadas (x,y,z) que dicho cubo. Esto último de saber qué numero de cubo y qué coordenadas tiene es lo que no sé hacer.
Para empezar, no hay ninguna combinación de ancho, alto y largo que tenga como resultado 10 a no ser que uno de los componentes sea 1… que es lo mismo que no tener uno de dichos componentes. Si no tenemos claro cuál es el rango sobre el que te mueves, difícilmente podremos hacer cálculos.
Estás confundiendo índices y coordenadas, diferentes índices tienen diferentes coordenadas dependiendo de los rangos de tu colección de cubos… así pues si aseguras tener 10 cubos y están distribuidos en 2×5×1:
+-+-+
|0|1|
+-+-+
|2|3|
+-+-+
|4|5|
+-+-+
|6|7|
+-+-+
|8|9|
+-+-+
El cubo 6 tendrá la coordenada (0, 3, 0), pero si están distribuidos en 5×2×1:
+-+-+-+-+-+
|0|1|2|3|4|
+-+-+-+-+-+
|5|6|7|8|9|
+-+-+-+-+-+
El cubo 6 tendrá la coordenada (1, 1, 0). Es normal que no sepas lo que hacer si no tienes claros los conceptos ni tienes una idea clara de lo que quieres; estas carencias en tu comprensión son evidentes en tus comentarios:
Las fórmulas que me diste están un poco extrañas y no logro hacer que quede por ejemplo para una estructura de 5 cubos en cada eje, da un total de 25 cubos, entonces.
Cinco cubos en cada eje no da 25 cubos si no 125 (5 ancho, 5 alto y 5 largo o 5×5×5 o 53). Lo extraño no es la fórmula si no tu manera de entender el problema. Te comparto una implementación de las fórmulas de índice a coordenada y viceversa:
struct punto { unsigned x{},y{},z{}; };
std::ostream &operator<<(std::ostream &o, const punto &p)
{
return o << '{' << p.x << ", " << p.y << ", " << p.z << '}';
}
template <unsigned ALTO, unsigned ANCHO, unsigned LARGO>
punto indice_a_coordenada(unsigned indice)
{
unsigned x = indice % ANCHO;
unsigned y = indice / (ANCHO * ALTO);
unsigned z = (indice / ANCHO) % ALTO;
return {x, y, z};
}
template <unsigned ALTO, unsigned ANCHO, unsigned LARGO>
unsigned coordenada_a_indice(const punto &coordenada)
{
return {(ANCHO * coordenada.z) + (ANCHO * ALTO * coordenada.y) + coordenada.x};
}
En tu distribución de cinco cubos en cada eje, el sexto cubo 6 está en (1, 0, 1):
std::cout << indice_a_coordenada<5, 5, 5>(6); // Muestra {1, 0, 1}
Unas coordenadas aleatorias deberán estar entre 0 y 4 en cada eje, el cubo del centro de tu colección 5×5×5 tiene el índice 26:
std::cout << coordenada_a_indice<5, 5, 5>({2, 2, 2}); // Muestra 26
Puedes ver el código funcionando en Try it online!.