Esto lo hará:
var arr = [];
var rows = 4;
var cols = 10;
for(var i = 0; i < rows + cols - 1; i++){
for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){
arr.push((j * cols) + i - j);
}
}
violín: http://jsfiddle.net/BmXpy/
EDIT: Aquí está mi intento de explicar la forma en que se me ocurrió esto. IMPORTANTE: utilice la tabla de números anterior para visualizar y, si es necesario, imprimirlo y dibujar las diagonales.
Primero, piense en lo que queremos, es básicamente diagonales. En el ejemplo anterior, la primera diagonal es 0, luego 10, 1, luego 20, 11, 2, luego 30, 21, 12, 3, etc. Ahora, si piensas cuántas de esas diagonales hay, es rows + cols - 1
. Ahí es donde obtenemos el primer ciclo:
for(var i = 0; i < rows + cols - 1; i++){
Ahora, ignore por un segundo los límites. En el caso general (todo el centro), cada una de estas diagonales tiene "filas" largas. Y como queremos ir hacia abajo, queremos un ciclo inverso. Que se vería así para el bucle interno:
for(var j = rows - 1; j >= 0; j--){
Ahora, tenemos que hacer frente a ambos limites (izquierda y derecha).
Para el límite izquierdo, si miramos el número de diagonales que son menos que "filas" de largo, veremos que es rows - 1
. Y para estas diagonales veremos que la longitud de cada una es i + 1
. El siguiente bucle interno manejará el caso general y el sitio limítrofe izquierda:
for(var j = Math.min(rows, i + 1) - 1; j >= 0; j--){
Usted verá que para diagonal 0, este se ejecutará una vez, durante 1 se ejecutará dos veces, etc, y para el caso general (i >= rows
) ejecutará "filas" veces.
Ahora, la boundry correcta. Si miramos qué diagonales de la derecha son más cortas que "filas", veremos que todas las diagonales son mayores que "cols" (en el ejemplo donde cols está indexado en 10, 0, es decir, en la fila 10 y más adelante).Reemplazando j >= 0
con j >= Math.max(0, i - cols + 1)
se ejecutará a 0 para el caso general y el límite izquierdo, pero se acortará para el límite derecho. Obtenemos esto:
for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){
Y, por último, el cálculo real del número en cada ubicación. i
representa la diagonal y j
representa el índice del número en la diagonal j = 0
es el número superior si está mirando la tabla de números publicada. Para j = 0
(fila superior de números) el número es simplemente i
, para cada fila debajo de la parte superior, necesitamos multiplicar el número por "cols" para obtener el número directamente debajo del número de la primera fila, luego el número debe ser ajustado a la izquierda. Esto se hace restando j
que es el número de fila. Entonces, para j = 1
(la 2da fila) necesitamos mover el número que queda en uno (restar 1). Entonces tenemos i
para la posición horizontal en la primera fila, + (j * cols)
para moverlo a la fila apropiada y luego -j para ajustarlo a diagonal (si ha dibujado las diagonales, trace esto para una de ellas para obtener una buena visual). Obtenemos esto:
(j * cols) + i - j
Ponlo todo junto y obtienes mi código final anterior. Espero que tenga algo de sentido.
¿Siempre sería para animación diagonal de izquierda a derecha? – Diego
no, también quiero hacer esta diagonal r-t-l, o rotar desde el centro, etc. Pero por ahora me gustaría entender cómo puedo hacer esto en este caso, l-t-r diagonal – Alexandra