2011-09-09 38 views
15

Tôi đang cố gắng làm phẳng mảng 3D thành mảng 1D cho hệ thống "chunk" trong trò chơi của mình. Đó là một trò chơi khối 3D và về cơ bản tôi muốn hệ thống chunk gần như giống hệt với hệ thống của Minecraft (tuy nhiên, đây không phải là bản sao của Minecraft bằng bất kỳ thước đo nào). Trong các trò chơi 2D trước đây của tôi, tôi đã truy cập mảng được làm phẳng bằng thuật toán sau:Làm cách nào để "làm phẳng" hoặc "chỉ mục" mảng 3D trong mảng 1D?

Tiles[x + y * WIDTH] 

Tuy nhiên, điều này rõ ràng không hoạt động với 3D vì thiếu trục Z. Tôi không có ý tưởng làm thế nào để thực hiện loại thuật toán này trong không gian 3D. Chiều rộng, chiều cao và chiều sâu là tất cả các hằng số (và chiều rộng chỉ lớn bằng chiều cao).

Chỉ là x + y*WIDTH + Z*DEPTH? Tôi khá xấu với toán học và tôi chỉ mới bắt đầu lập trình 3D vì vậy tôi khá mất: |

PS. Lý do cho điều này là tôi đang lặp lại và nhận được các công cụ theo chỉ mục từ nó khá nhiều. Tôi biết rằng mảng 1D nhanh hơn mảng đa chiều (vì lý do tôi không thể nhớ: P). Mặc dù điều này có thể không cần thiết, tôi muốn có hiệu suất tốt nhất có thể :)

+0

tôi thích hợp trong nói rằng bạn muốn có một mảng 3D để được phù hợp với một arr 1D ay? – DMan

+1

Tại sao bạn không sử dụng mảng 3D? – svick

+0

@DMan Vâng bạn là :) Tôi luôn luôn giải thích tất cả mọi thứ theo cách khó khăn nhất và dài nhất để không có bất ngờ bạn không hiểu: P – flai

Trả lời

24

Thuật toán hầu như giống nhau. Nếu bạn có một mảng 3D Original[HEIGHT, WIDTH, DEPTH] sau đó bạn có thể biến nó thành Flat[HEIGHT * WIDTH * DEPTH] bởi

Flat[x + WIDTH * (y + DEPTH * z)] = Original[x, y, z] 

Là một sang một bên, bạn nên chọn các mảng của mảng trên mảng đa chiều trong .NET. Sự khác biệt về hiệu suất là đáng kể

+3

Bạn có thể trỏ đến một số nguồn thảo luận về sự khác biệt hiệu suất? Ngoài ra, bạn không nên căn cứ vào quyết định của mình chỉ về hiệu suất. – svick

+0

http://stackoverflow.com/questions/597720/what-is-differences-between-multidimensional-array-and-array-of-arrays-in-c và http://stackoverflow.com/questions/468832/why mảng đa chiều-mảng-trong-net-chậm hơn so với bình thường – hatchet

+0

@svick: Một số nguồn có thể được nhìn thấy trong các liên kết được cung cấp. Lưu ý hiệu suất của tôi chỉ là một bên và không phải là gợi ý chính. Các mảng có răng cưa có cú pháp gần như giống hệt nhau (ban đầu [x] [y] [z]), nhưng hãy thực hiện nhiều công việc hơn để khởi tạo. Tuy nhiên, lợi ích hiệu suất có thể trở nên khá đáng chú ý (tăng tốc 2-5x) tùy thuộc vào cách sử dụng. –

5

Bạn sắp hoàn tất. Bạn cần phải nhân Z bởi WIDTHDEPTH:

Tiles[x + y*WIDTH + Z*WIDTH*DEPTH] = elements[x][y][z]; // or elements[x,y,z] 
10

x + y*WIDTH + Z*WIDTH*DEPTH. Trực quan hóa nó như là một hình chữ nhật vững chắc: đầu tiên bạn đi ngang dọc theo x, sau đó mỗi y là một "dòng" width bước dài và mỗi z là một "mặt phẳng" WIDTH*DEPTH các bước trong khu vực.

13

Tôi nghĩ rằng điều trên cần một chút chỉnh sửa. Giả sử bạn có HEIGHT là 10, và WIDTH là 90, mảng đơn chiều sẽ là 900. Theo logic trên, nếu bạn ở phần tử cuối cùng trên mảng 9 + 89 * 89, rõ ràng đây là lớn hơn 900.Thuật toán chính xác là:

Flat[x + HEIGHT* (y + WIDTH* z)] = Original[x, y, z], assuming Original[HEIGHT,WIDTH,DEPTH] 

Trớ trêu thay, nếu bạn HEIGHT> WIDTH bạn sẽ không gặp một tràn, chỉ cần hoàn thành kết quả bonkers;)

+3

Tôi không thể upvote hoặc nhận xét về câu trả lời đúng, nhưng Martin đã đúng, câu trả lời được chọn hiện tại là sai. Về cơ bản: dữ liệu [x] [y] [z] = dữ liệu [x + y * maxX + z * maxX * maxY] – jking

+0

câu trả lời yep hiện tại là sai, nên chiều cao không sâu. đã cho tôi quá lâu để con số này ra như là lần đầu tiên của nó ive thực sự sử dụng một câu trả lời SO sai để mã một cái gì đó>. < – chilleo

0

Để hiểu rõ hơn mô tả về mảng 3D trong 1D mảng sẽ là (I đoán chiều sâu trong câu trả lời tốt nhất là có nghĩa là kích thước Y)

IndexArray = x + y * InSizeX + z * InSizeX * InSizeY; 

IndexArray = x + InSizeX * (y + z * InSizeY); 
15

Dưới đây là một giải pháp trong Java cung cấp cho bạn cả hai:

  • từ 3D sang 1D
  • từ 1D sang 3D

Dưới đây là một minh họa đồ họa của con đường tôi đã chọn để đi qua ma trận 3D, các tế bào được đánh số theo thứ tự traversal của họ:

2 Examples of 3D matrices

chức năng chuyển đổi:

public int to1D(int x, int y, int z) { 
    return (z * xMax * yMax) + (y * xMax) + x; 
} 

public int[] to3D(int idx) { 
    final int z = idx/(xMax * yMax); 
    idx -= (z * xMax * yMax); 
    final int y = idx/xMax; 
    final int x = idx % xMax; 
    return new int[]{ x, y, z }; 
} 
Các vấn đề liên quan