9.7.6  ¿Y qué hay de los bucles anidados?

Aún cuando uno domine los bucles sencillos, los bucles anidados pueden ser temibles (o por lo menos difíciles de entender).

Los bucles anidados se usan por ejemplo en la creación de formaciones 2D -arrays o matrice- de objetos (con filas y columnas de objetos), etc. Por ejemplo, si usted quisiera crear una formación de 10x20 esferas en su escena, el bucle anidado es la herramienta para ello.

No hay nada especial acerca de los bucles anidados. Solamente tiene que poner atención en lo que respecta a donde inicializa y actualiza sus variables de índice.

Recordemos la forma de un bucle "for" sencillo:

#declare Index = valor_inicial;
#while(Index <= valor_final)

[algo aqui]

#declare Index = Index + paso_del_indice;
#end

La parte [algo aqui] puede ser cualquier cosa. Si es otro bucle, entonces tenemos un bucle anidado. El bucle interior debería tener la misma estructura que el externo.

Nótese que el sangrado con espacios nos ayuda a distinguir entre los bucles. Siempre es bueno utilizar un buen esuqema de sangrado:

#declare Index1 = valor_inicial1;
#while(Index1 <= valor_final1)

#declare Index2 = valor_inicial2;
#while(Index2 <= valor_final2)

[Algo aqui]

#declare Index2 = Index2 + paso_del_index2;
#end

#declare Index1 = Index1 + paso_del_index1;
#end

Es un error común de principiante romper esta estructura. Por ejemplo, es común declarar el 'Index2' antes del primer #while. Esto rompe la estructura del bucle, y es por eso que no funciona. Si sigue paso a paso lo que hace POV-Ray, como se explicó anteriormente, verá por qué no trabaja. No mezcle las estructuras de los bucles externo e interno juntos, o su código sencillamente no funcionará como lo espera.

Entonces, si deseamos hacer nuestra formación de esferas 10x20, será algo parecido a esto:

#declare Index1 = 0;
#while(Index1 <= 9)

#declare Index2 = 0;
#while(Index2 <= 19)

sphere { <Index1, Index2, 0>, .5 }

#declare Index2 = Index2 + 1;
#end

#declare Index1 = Index1 + 1;
#end

Note cómo comenzamos desde 0 y continuamos hasta 9 en el bucle externo, y desde 0 hasta 19 en el bucle interno. Esto se ha hecho para que la formación de esferas comience desde el origen (en vez de empezar desde <1, 1, 0>). Por supuesto que podriamos haber hecho el 'Index1' y el 'Index2' ir desde 1 a 10 y desde 1 a 20 respectivamente y haber creado la esfera de esta manera:

  sphere { <Index1-1, Index2-1, 0>, .5 }

Aunque no debería mezclar las estructuras de los bucles, puede perfectamente usar los valores del bucle externo en el interno (ej, en esta condición). Por ejemplo, si quisiéramos crear una formación triangular de esferas en vez de una rectangular (estos es, creamos sólo la mitad de las esferas) podríamos haber hecho el #while interno asi:

  #while(Index2 < Index1*2)

('Index2' irá desde 0 hasta el valor de 'Index1' multiplicado por 2.)

No hay razón por la que nos debamos limitar a sólo dos bucles anidados. Virtualmente no hay límite en la cantidad de bucles que se pueden anidar. Por ejemplo, si quisiéramos crear una forma de caja llena de esferas en columnas, filas y profundidad, sólo hacemos tres loops anidados, uno para el eje de las x, otro para el eje de las y, el tercero para el eje de las z.