Dapatkan cincin ubin di kotak segi enam

17

Berkat pos ini: Ubin heksagonal dan menemukan tetangga yang berdekatan , saya dapat mengumpulkan ubin yang berdekatan dengan ubin yang diberikan. Tapi saya cukup banyak terjebak pada algoritma yang hanya memberi saya "cincin" ubin yang ditentukan oleh offset. Algoritme yang diberikan dalam post Stack Overflow tidak terlalu peduli dengan urutan pengumpulan ubin.

Saya tahu bahwa dengan setiap offset 6 ubin ditambahkan.

  • Offset 1 memberi Anda 6 ubin (ubin berdekatan pertama).
  • Offset 2 memberi Anda 12.
  • Offset 3 memberi Anda 18, dll.

Ada pertumbuhan konstan 6 dengan masing-masing offset. Jadi saya berasumsi harus ada aturan yang menyesuaikan dengan offset ini. Saya tidak tahu persis yang ini. Siapa saja?

Sidar
sumber

Jawaban:

23

Cincin heksagonal dengan jari-jari N terdiri dari 6 garis lurus, masing-masing dengan panjang N - lihat contoh saya yang sangat kasar di bawah ini :) Untuk N = 2:

masukkan deskripsi gambar di sini

Panah masing-masing menutupi 2 heks.

Saya berasumsi Anda memiliki beberapa fungsi yang memberi Anda ubin tetangga dalam arah tertentu, seperti utara (), tenggara () dll. Jadi algoritma Anda, dalam pseudocode, harus seperti ini:

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

Perhatikan bahwa ini harus bekerja juga untuk kasus tepi N = 1, mengembalikan 6 ubin, dan N = 0 mengembalikan set kosong.

Saya tahu kode ini tidak sempurna :) Ada beberapa redundansi di sini. Dalam proyek saya menggunakan peta ubin teratur (heksagonal atau sebaliknya) saya biasanya memiliki enum "Direction", yang memungkinkan saya untuk melakukan ini dengan lebih lancar:

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);
Liosan
sumber
Ini seharusnya mendorong saya ke arah yang benar. Terima kasih!
Sidar
2
Perhatikan bahwa sampel kode akan menambahkan titik duplikat untuk lima segmen pertama. Namun, itu jawaban yang bagus.
MichaelHouse
@ Byte56 Ya saya pikir. Tapi setidaknya saya melihat hubungan antara pergeseran arah!
Sidar
1
@ Byte56 Benarkah? Hm Saya mencoba menghindari yang satu itu ... 0..N-1 memberi 0..1 untuk N = 2, jadi itu adalah i = 0 dan i = 1, yang merupakan 2 nilai. 2 nilai dari setiap kali 6 arah adalah 12 ubin, sebagaimana mestinya ...?
Liosan
Nggak. Kamu benar. Karena setiap loop menambahkan titik dari loop terakhir saya tidak aktif oleh satu untuk loop, kesalahan saya. Ini algoritma yang cerdas.
MichaelHouse
2

Saya telah menemukan artikel ini menjadi referensi yang sangat baik untuk algoritma grid heksagonal, dan bagian tentang "Jarak" menyediakan metode untuk menentukan jumlah langkah antara dua ubin. Jika Anda mengubah koordinat aksial (xy) menjadi koordinat kubus (xyz), jarak selalu sama dengan yang terbesar dari offset koordinat antara dua petak, atau maks (| dx |, | dy |, | dz |).

Pencarian lengkap seluruh kotak untuk ubin pada jarak yang diinginkan adalah HAI(n2) dengan dimensi grid, tetapi ini adalah implementasi sederhana yang bekerja dengan baik untuk grid kecil.

masukkan deskripsi gambar di sini

KPM
sumber