Nhận vòng gạch trong lưới lục giác


17

Nhờ bài đăng này: gạch hình lục giác và tìm hàng xóm liền kề của họ , tôi có thể thu thập các ô liền kề với một ô cụ thể. Nhưng tôi bị mắc kẹt khá nhiều trên một thuật toán chỉ cung cấp cho tôi một "vòng" gạch được chỉ định bởi một phần bù. Thuật toán được đưa ra trong bài viết Stack Overflow đó không quan tâm chính xác đến thứ tự mà nó thu thập các ô.

Tôi biết rằng với mỗi 6 gạch bù được thêm vào.

  • Offset 1 cung cấp cho bạn 6 gạch (gạch liền kề đầu tiên).
  • Offset 2 cung cấp cho bạn 12.
  • Offset 3 cung cấp cho bạn 18, v.v.

Có sự tăng trưởng liên tục là 6 với mỗi lần bù. Vì vậy, tôi cho rằng nên có một quy tắc thích nghi với những sự bù đắp này. Tôi không thể chính xác tìm ra cái này. Bất kỳ ai?

Câu trả lời:


23

Một vòng lục giác có bán kính N bao gồm 6 đường thẳng, mỗi đường thẳng có chiều dài N - xem ví dụ cực kỳ thô sơ của tôi bên dưới :) Với N = 2:

nhập mô tả hình ảnh ở đây

Các mũi tên bao gồm 2 hình lục giác mỗi.

Tôi giả sử bạn có một số hàm cung cấp cho bạn ô lân cận theo một hướng cụ thể, như hướng bắc (), đông nam (), v.v. Vì vậy, thuật toán của bạn, trong mã giả, nên giống như thế này:

var point = startingPoint.north(N)
for i = 0..N-1:
    result.add(point)
    point = point.southeast(1);
for i = 0..N-1:
    result.add(point)
    point = point.south(1);
for i = 0..N-1:
    result.add(point)
    point = point.southwest(1);
for i = 0..N-1:
    result.add(point)
    point = point.northwest(1);
for i = 0..N-1:
    result.add(point)
    point = point.north(1);
for i = 0..N-1:
    result.add(point)
    point = point.northeast(1);

Lưu ý rằng điều này cũng sẽ hoạt động đối với các trường hợp cạnh N = 1, trả về 6 ô và N = 0 trả về một tập hợp trống.

Tôi biết mã không hoàn hảo :) Có một số dư thừa ở đây. Trong các dự án của tôi sử dụng bản đồ được lát gạch thường xuyên (hình lục giác hoặc hình khác), tôi thường có một "Hướng" enum, cho phép tôi thực hiện việc này trơn tru hơn:

var point = startingPoint.inDir(N, Direction.North)
var dir = Direction.SouthEast.
for d = 0..Direction.count():
    for i = 0..N-1:
        result.add(point)
        point = point.inDir(1, dir);
    dir = nextDirection(dir);

Điều này sẽ đẩy tôi đi đúng hướng. Cảm ơn!
Sidar 18/03/13

2
Lưu ý rằng mẫu mã sẽ thêm các điểm trùng lặp cho năm phân đoạn đầu tiên. Tuy nhiên, đó là một câu trả lời tốt đẹp.
MichaelHouse

@ Byte56 Vâng tôi đã tìm ra. Nhưng ít nhất tôi thấy sự kết nối giữa các ca theo hướng!
Sidar 18/03/13

1
@ Byte56 Thật sao? Hừm. Tôi đã cố gắng tránh điều đó ... 0..N-1 cho 0..1 cho N = 2, vì vậy đó là i = 0 và i = 1, là 2 giá trị. 2 giá trị từ mỗi lần 6 hướng là 12 ô, vì nó phải là ...?
Liosan

Không. Bạn đúng. Vì mỗi vòng lặp được thêm một điểm từ vòng lặp cuối cùng, tôi đã tắt một điểm cho các vòng lặp, lỗi của tôi. Đó là một thuật toán thông minh.
MichaelHouse

2

Tôi đã tìm thấy bài viết này là một tài liệu tham khảo rất tốt cho các thuật toán lưới lục giác, và phần của nó về "Khoảng cách" cung cấp một phương pháp để xác định số bước giữa hai ô. Nếu bạn chuyển đổi tọa độ trục (xy) thành tọa độ khối (xyz), khoảng cách luôn bằng giá trị lớn nhất của các tọa độ giữa hai ô hoặc tối đa (| dx |, | dy |, | dz |).

Một tìm kiếm toàn diện của toàn bộ lưới cho gạch ở khoảng cách mong muốn là Ôi(n2) với kích thước lưới, nhưng nó là một triển khai đơn giản, hoạt động tốt cho các lưới nhỏ.

nhập mô tả hình ảnh ở đây

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.