4.4. Bucles anidados
Una técnica que se utiliza con mucha frecuencia en proyectos de computación creativa es la de crear un bucle anidado dentro de otro para tener no una sucesión lineal de elementos como hemos hecho hasta ahora, sino un patrón bidimensional, con elementos que se repiten tanto en el eje horizontal como en el vertical.

Fuente: elaboración propia.
Un primer acercamiento para dibujar el patrón de la figura 48 podría ser crear un bucle para una fila (o columna) y repetirlo todas las veces que necesitemos:
// Fila 0 (0px en Y) for (let i = 0; i <= width; i += 50) { circle(i, 0, 25); } // Fila 1 (50px en Y) for (let i = 0; i <= width; i += 50) { circle(i, 50, 25); } // ...y así para el resto de las filas
Sin embargo, ya seréis capaces de detectar que seguramente haya una manera más eficiente y flexible de realizar esta tarea. Es aquí donde entran en juego los bucles anidados:

Fuente: elaboración propia.
Centrémonos en cómo hemos construido el set de bucles anidados:
let separation = 50; let circleSize = separation * 0.5; for (let i = 0; i <= width; i += separation) { for (let j = 0; j <= height; j += separation) { circle(i, j, circleSize); } }
Primero, hemos definido un par de variables que almacenan la distancia entre los círculos y su tamaño. A continuación, hemos creado un bucle de la misma manera que lo hicimos antes para dibujar una fila de círculos: damos un valor de inicio, una condición que ese valor tiene que cumplir para ejecutar el cuerpo del bucle y una actualización del valor cada vez que el bucle se complete.
La novedad estriba en que en el cuerpo del bucle hemos creado otro bucle. En este nuevo bucle creamos una nueva variable, una nueva condición y una nueva actualización, que nos ayudarán a dibujar las columnas de nuestro patrón.
En el cuerpo de este segundo bucle es donde esta vez escribiremos el código que dibujará los círculos. Para definir las coordenadas x e y de los círculos, utilizaremos los valores de las variables i y j que hemos definido en los respectivos bucles.
De esta manera, entramos en el primer bucle e inmediatamente entramos en el segundo. En la primera iteración i vale 0 y j también vale 0, por lo que nos dibujará el primer círculo en las coordenadas (0, 0). A continuación, actualiza el valor de j y, como se cumple que j <= height, entramos de nuevo en el segundo bucle. Ahora j vale 50 e i sigue valiendo 0, por lo que nos dibujará el segundo círculo en las coordenadas (0, 50). La variable j seguirá incrementándose hasta que j <= height no se cumpla, momento en el que saldrá del segundo bucle y pasará a la fase de actualización del primer bucle, incrementando i, por lo que pasaremos a tener una i con valor 50 y entraremos de nuevo en el segundo bucle con una j valor 0. De esta manera, nos creará la segunda columna. Este proceso se repetirá hasta rellenar todo el canvas.
De nuevo, podemos usar nuestra función eye() para dibujar los ojos dentro de los bucles anidados:

Fuente: elaboración propia.