2011-04-29 20 views
7

Đây giống như một câu hỏi liên quan đến toán học.JavaScript: Tự động đặt một mảng đa chiều biến theo đường chéo

Tôi đang cố gắng tạo hiệu ứng mờ dần dễ thương với jQuery, bằng cách tách phần tử trong một số khối nhất định, sau đó làm mờ từng khối, nhưng làm chậm hiệu ứng mờ dần dựa trên mảng khác.

Vì vậy, để tạo ra các bảng khối Tôi có hai biến:

var rows = 4, 
    cols = 10; 

này sẽ chia phần tử thành các khối như:

   0 1 2 3 4 5 6 7 8 9 
      10 11 12 13 14 15 16 17 18 19 
      20 21 22 23 24 25 26 27 28 29 
      30 31 32 33 34 35 36 37 38 39 

Sau đó, tôi là tạo ra một mảng mà quyết định như thế nào các khối sẽ hoạt hình. Ví dụ, đối với một phim hoạt hình đường chéo từ trái sang bên phải mảng này sẽ như thế nào:

order = [0, 10, 1, 20, 11, 2, 30, 21, 12, 3, 31, 22, 13, 4, 32, 23, 14, 5, 33, 24, 15, 6, 34, 25, 16, 7, 35, 26, 17, 8, 36, 27, 18, 9, 37, 28, 19, 38, 29, 39]; 

và đối với trường hợp cụ thể này nó hoạt động: D

Câu hỏi của tôi là làm thế nào tôi có thể tạo ra các mảng order tự động, không phải bằng tay, dựa trên số khối (hàng x cột), có thể thay đổi?

Cảm ơn bạn

+0

Nó sẽ luôn luôn cho hoạt hình đường chéo từ trái qua phải không? – Diego

+0

không, tôi cũng muốn làm điều này r-t-l chéo, hoặc xoay từ trung tâm vv Nhưng bây giờ tôi muốn hiểu làm thế nào tôi có thể làm điều này cho trường hợp này, l-t-r chéo – Alexandra

Trả lời

4

này sẽ làm điều đó:

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

} 

fiddle: http://jsfiddle.net/BmXpy/

EDIT: Đây là nỗ lực của tôi trong việc giải thích làm thế nào tôi đến với điều này. QUAN TRỌNG, sử dụng bảng số ở trên để hình dung và nếu cần, hãy in nó và vẽ các đường chéo.

Đầu tiên, hãy nghĩ về những gì chúng tôi muốn, về cơ bản là đường chéo. Trong ví dụ trên đường chéo đầu tiên là 0, sau đó 10, 1, sau đó 20, 11, 2, sau đó 30, 21, 12, 3, v.v. Bây giờ nếu bạn nghĩ về số lượng các đường chéo đó, đó là rows + cols - 1. Đó là nơi chúng tôi nhận được vòng lặp đầu tiên:

for(var i = 0; i < rows + cols - 1; i++){ 

Bây giờ, bỏ qua một giây. Trong trường hợp chung (toàn bộ trung tâm), mỗi đường chéo là "hàng" dài. Và kể từ khi chúng tôi muốn đi dưới lên, chúng tôi muốn có một vòng lặp ngược lại. Điều đó sẽ giống như thế này cho vòng lặp bên trong:

for(var j = rows - 1; j >= 0; j--){ 

Bây giờ, chúng ta phải đối phó với cả hai ranh giới (trái và phải).

Đối với khung giới hạn bên trái, nếu chúng ta nhìn vào số lượng đường chéo nhỏ hơn "hàng", chúng ta sẽ thấy rằng nó là rows - 1. Và đối với những đường chéo này, chúng ta sẽ thấy rằng chiều dài của mỗi đường là i + 1. Vòng lặp bên trong sau sẽ xử lý các trường hợp nói chung và ranh giới trái:

for(var j = Math.min(rows, i + 1) - 1; j >= 0; j--){ 

Bạn sẽ thấy rằng đối với đường chéo 0, điều này sẽ chạy một lần, trong vòng 1 nó sẽ chạy hai lần, vv Và đối với trường hợp chung (i >= rows) nó sẽ chạy "hàng" lần.

Bây giờ, giới hạn bên phải. Nếu chúng ta nhìn vào đường chéo nào bên phải ngắn hơn "hàng", chúng ta sẽ thấy nó là tất cả đường chéo lớn hơn "cols" (trong ví dụ nơi cols là 10, 0 được lập chỉ mục, đó là hàng 10 và cao hơn).Thay thế j >= 0 bằng j >= Math.max(0, i - cols + 1) sẽ chạy tới 0 cho trường hợp chung và khung giới hạn bên trái nhưng rút ngắn cho giới hạn bên phải. Chúng tôi nhận được điều này:

for(var j = Math.min(rows, i + 1) - 1; j >= Math.max(0, i - cols + 1); j--){ 

Và cuối cùng, tính toán thực tế của số ở mỗi vị trí. i đại diện cho đường chéo và j đại diện cho chỉ số của số trên đường chéo j = 0 là số đầu nếu bạn đang xem bảng số đã đăng. Đối với j = 0 (hàng trên cùng của số), số đơn giản là i, đối với mỗi hàng bên dưới đầu, chúng tôi cần nhân số bằng "cols" để lấy số trực tiếp bên dưới số hàng đầu tiên, sau đó số cần phải điều chỉnh sang trái. Điều này được thực hiện bằng cách trừ j là số hàng. Vì vậy, đối với j = 1 (hàng thứ 2), chúng ta cần phải di chuyển số sang trái một (trừ 1). Vì vậy, chúng tôi có i cho vị trí nằm ngang trên hàng đầu tiên, + (j * cols) để di chuyển nó xuống hàng thích hợp và sau đó -j để điều chỉnh nó thành đường chéo (nếu bạn vẽ đường chéo, hãy theo dõi điều này cho một trong số chúng trực quan). Chúng tôi nhận được điều này:

(j * cols) + i - j 

Đặt tất cả lại với nhau và bạn nhận được mã cuối cùng ở trên. Hy vọng rằng thực hiện một số ý nghĩa.

+0

Brilliant..Too tốt !! –

+0

@kingjiv: rất đẹp! Bằng cách này, bạn nên sử dụng ´ [] ´ thay vì ´Array() ´ – Diego

+0

đẹp! nhưng xin vui lòng giải thích rằng với tôi, tôi hoàn toàn bị mất sau khi 'i Alexandra

1

Ở đây có một mã http://jsfiddle.net/paska/FhLnu/3/

var rows = 4, 
    cols = 10, 
    getValue = function(x, y) { 
     return (y * cols) + x; 
    }, 
    addValue = function(x, y) { 
     $("#arr").append(getValue(x, y) + ", "); 
    }, 
    max = rows + cols - 1, 
    updateRow = 0; 

for(var i = 0; i < max; i++) { 
    if(i >= rows) 
     updateRow++; 
    for(var x = 0; x <= i; x++) { 
     //$("#arr").append(x + " " + (i - x) + "<br />"); 
     var row = (i - x), 
      col = x; 
     if(updateRow) { 
      row = row - updateRow; 
      col = col + updateRow; 
     } 
     if(col >= cols) 
      break; 
     if(row >= 0 && col >= 0) 
      addValue(col, row); 
    } 
} 

Tôi biết @kingjiv đang làm việc, tôi chỉ muốn thêm một cách khác để làm việc đó.

2

Tuy nhiên, một cách khác để thực hiện điều đó.

function diagonalized_block (rows, cols) { 
    blocks = []; 
    for (var i = 0; i < rows * cols; i++) { 
     blocks.push(i); 
    } 
    blocks.sort(function (a, b) {return a/cols + a%cols - b/cols - b%cols}); 
    return blocks; 
} 

Ý tưởng rất đơn giản. Viết mảng rõ ràng của tất cả các khối, và sau đó sắp xếp theo một chức năng của khối đó là tăng dần theo thứ tự chính xác mà bạn muốn. Chức năng đó là x/cols + x%cols. Đó là row + ascending error on diagonal + col. Vì vậy, bạn sắp xếp những thứ đầu tiên mà theo đó đường chéo họ đang trên, và sau đó tăng dần trên đường chéo.

Đối với các mẫu khác, bạn sẽ phải tìm các chức năng khác xảy ra để sắp xếp chính xác. (Hoặc viết một chức năng sắp xếp phức tạp hơn để thực hiện chính xác những gì bạn muốn nó làm.)

Các vấn đề liên quan