Tìm các ô trong phạm vi trên lưới lục giác


8

Đầu tiên - tôi biết tôi đang trở nên siêu dày đặc ở đây.

Ngoài ra, tôi đang cố gắng viết một triển khai C # của thuật toán này:

var results = []
for each -N  dx  N:
  for each max(-N, -dx-N)  dy  min(N, -dx+N):
    var dz = -dx-dy
    results.append(cube_add(center, Cube(dx, dy, dz)))

Tôi đã lấy cái này từ nguồn tài nguyên to lớn này .

Vấn đề của tôi là mọi việc thực hiện điều này tôi đã thử cho đến nay đều có kết quả điên rồ. Ví dụ: mã hiển thị bên dưới hiện đang dẫn đến kết quả này:

1

và điều này:

2

Mã của tôi hiện đang ngồi như thế này:

for (int x = this.CellPositionX - distance; x <= this.CellPositionX + distance; x++)
    {
        for (int y = this.CellPositionY - Math.Max(-distance, -x - distance); y <= this.CellPositionY + Math.Min(distance, -x + distance); y++)
        {
            HexPosition rangePosition = new HexPosition(x, y);
            range.Add(rangePosition);
        }
    }

Bất cứ ai có thể phát hiện ra một cái gì đó khủng khiếp ở đây? Mọi lời đề nghị đều được chào đón. Tôi đã đập đầu vào cái này một lúc rồi.

Cảm ơn!

Lưu ý cập nhật: Tôi đang sử dụng tọa độ Axial trong lưới. Cập nhật # 2: như được chỉ ra dưới đây, tôi đã sai vòng lặp for..each và không sử dụng deltas cho công việc. Cảm ơn đã giúp đỡ!

Tôi hiện đang có một vấn đề như được hiển thị bên dưới với việc thực hiện từ các câu trả lời: nhập mô tả hình ảnh ở đây

Tôi sẽ tiếp tục điều tra - nếu tôi nhận ra tôi sẽ đăng kết quả đầy đủ trở lại đây. Cảm ơn tất cả!


1
Cảm ơn tài nguyên đó có vẻ rất tốt! Tôi đã hơi thất vọng khi nhận ra hầu hết các đồ họa đều có thể tương tác. :)
Christer

3
Ví dụ anh ta đưa ra sử dụng tọa độ khối, trong khi có vẻ như bạn đang sử dụng tọa độ bù hoặc trục. Bạn cần chuyển đổi x, y, z từ tọa độ khối anh ta sang bất kỳ hệ tọa độ nào bạn đang sử dụng.
Alex Sherman

1
@ Vector57 Tôi đang sử dụng Axial. Từ phần chuyển đổi, có đề cập rằng tôi không cần phải làm gì với thuộc tính Z và rằng q / r và x / y có thể hoán đổi cho nhau ... hoặc tôi đã hiểu nhầm điều đó?
aaron-bond

Có vẻ như vậy, mặc dù trong các ví dụ anh ấy sử dụng r = z nhưng tôi không hiểu tại sao bạn nên chọn vấn đề nào.
Alex Sherman

Câu trả lời:


4

Vì vậy, khi kiểm tra thêm, vấn đề của bạn thực sự không liên quan gì đến việc chuyển đổi hệ thống. Điều này có thể đã được làm rõ hơn bằng cách không đặt tên tọa độ trục X và Y của bạn mà thay vào đó là Q và R. Vấn đề bạn thực sự gặp phải là điều kiện vòng lặp xấu. Mẫu mã ban đầu tạo ra các đồng bằng và r mà bạn cố gắng chuyển đổi, trong các vòng lặp của bạn, thành các tọa độ tuyệt đối và bạn đã mắc lỗi. Thay vào đó, thuật toán sẽ trông như sau:

for (int dx = -distance; dx <= distance; dx++)
{
    for (int dy = Math.Max(-distance, -dx - distance); dy <= Math.Min(distance, -dx + distance); dy++)
    {
        HexPosition rangePosition = new HexPosition(
            this.CellPositionX + dx, this.CellPositionY + dy);
        range.Add(rangePosition);
    }
}

Oh derp ... bài báo thậm chí còn đề cập rằng chúng là các giá trị delta :( Gonna hãy thử ngay bây giờ và xem nó diễn ra như thế nào. Cảm ơn :)
aaron-bond

Cám ơn vì cái này. Nó chắc chắn là rất gần với cách làm đúng. Tôi vẫn đang làm rối tung thứ gì đó với tọa độ nhưng ít nhất tôi có đúng số! Vì một số lý do, tôi kết thúc với một ô quá cao trên -x và một ô quá thấp trên + x. Tôi đã đăng một bức ảnh lên trên nếu bạn biết bất cứ điều gì về nó nhưng tôi vẫn sẽ tiếp tục điều tra bản thân mình :) cảm ơn vì sự giúp đỡ của bạn!
aaron-bond

Bạn đang giải thích chính xác các tọa độ trục? Hãy nhớ rằng bạn đã chọn sử dụng x và y thay vì x và z, vì vậy nếu phần còn lại của mã của bạn không tính đến sự thay đổi này từ các ví dụ thì điều đó có thể dẫn đến hành vi kỳ lạ.
Alex Sherman

Đúng, tôi đã chuyển đổi để nó là x và z. dx trở thành x và z = -dx - dy ...
aaron-bond

1
Hình ảnh mới bạn đăng lên cho thấy 7 hình lục giác được tô sáng. Đây là những gì bạn mong đợi với khoảng cách = 1. Hãy thử in ra các giá trị. Với CellPocation được đặt thành 0,0 và khoảng cách 1, các hình lục giác bạn nhận được phải là (-1, 0); (-1, 1); (0, -1); (0, 0); (0, 1); (1, -1); (1, 0)
amitp

7

Như Vector57 đã lưu ý, vấn đề là bạn đang sử dụng hệ tọa độ sai . Thuật toán được mô tả có nghĩa là được sử dụng với tọa độ khối , có các thành phần x, y và z :

tọa độ khối

Điều này có thể không rõ ràng từ mã giả của thuật toán, nhưng đó là vì nó đơn giản hóa điều này :

var results = []
for each -N  dx  N:
    for each -N  dy  N:
        for each -N  dz  N:
            if dx + dy + dz = 0:
                results.append(cube_add(center, Cube(dx, dy, dz)))

... một vòng lặp lồng nhau đơn giản trên x, y và z, những gì bạn mong đợi từ một thuật toán phạm vi.

Tôi không biết bạn đang sử dụng hệ tọa độ nào, nhưng tôi đoán đó là một trong những hệ thống "tọa độ bù", phổ biến vì chúng dễ thực hiện bằng cách đặt các ô lưới bên trong một mảng 2D:

bù q bố trí dọc

Điều này không có nghĩa là bạn không thể sử dụng các thuật toán khối này; nó chỉ có nghĩa là bạn cần chuyển đổi từ tọa độ khối sang riêng của bạn . Ví dụ: để chuyển đổi sang / từ bố cục dọc "lẻ-q", hãy sử dụng các cách sau:

# convert cube to odd-q offset
col = x
row = z + (x - (x&1)) / 2

# convert odd-q offset to cube
x = col
z = row - (col - (col&1)) / 2
y = -x-z

Tôi có cảm giác nó giống như thế này. Có một phần của trang đó đã đề cập đến việc chuyển đổi từ Cube sang Axial và nói rằng chỉ cần loại bỏ phần z và phần còn lại q và r trở thành x và y. Tôi nghĩ rằng tôi đã đơn giản hóa quá mức ở đó. Cám ơn vì cái này. Giải thích tuyệt vời về những gì tôi đã thiếu. Tôi sẽ cho nó đi sau! :)
aaron-bond

Tôi vừa mới xem qua và tôi đang sử dụng trục. Chắc chắn vì thuật toán không đề cập đến Z nên nó cũng là một hệ thống thẳng q = xr = yquá?
aaron-bond
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.