Menemukan sel dalam jangkauan pada kisi heksagonal

8

Pertama - saya tahu saya sangat padat di sini.

Dengan itu, saya mencoba untuk menulis implementasi C # dari algoritma ini:

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

Saya telah mengambil ini dari sumber yang luar biasa ini .

Masalah saya adalah bahwa setiap implementasi yang telah saya coba sejauh ini memiliki hasil gila. Misalnya, kode yang ditunjukkan di bawah saat ini menghasilkan ini:

1

dan ini:

2

Kode saya saat ini duduk seperti ini:

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

Adakah yang bisa melihat sesuatu yang salah di sini? Semua saran diterima. Saya telah membenturkan kepala saya pada yang satu ini sekarang.

Terima kasih!

Catatan yang diperbarui: Saya menggunakan koordinat Aksial dalam kisi. Perbarui # 2: seperti yang ditunjukkan di bawah ini, saya punya for..each loop salah dan tidak menggunakan delta untuk bekerja. Terima kasih untuk bantuannya!

Saat ini saya memiliki masalah seperti yang ditunjukkan di bawah ini dengan implementasi dari jawaban: masukkan deskripsi gambar di sini

Saya akan terus menyelidiki - jika saya mengetahuinya saya akan memposting hasil lengkap di sini. Terima kasih semuanya!

ikatan aaron
sumber
1
Terima kasih atas sumber dayanya, itu terlihat sangat bagus! Saya agak terpesona ketika saya menyadari bahwa hampir semua gambar dapat berinteraksi. :)
Christer
3
Contoh yang ia berikan menggunakan koordinat kubus, sedangkan tampaknya Anda menggunakan koordinat offset atau aksial. Anda perlu mengonversi x, y, z dari koordinat kubik yang ia miliki ke sistem koordinat apa pun yang Anda gunakan.
Alex Sherman
1
@ Vector57 Saya menggunakan Axial. Dari bagian konversi disebutkan bahwa saya tidak perlu melakukan apa pun dengan properti Z dan bahwa q / r dan x / y dapat dipertukarkan ... atau apakah saya salah paham?
aaron-bond
Tampaknya seperti itu, meskipun dalam contoh dia menggunakan r = z tapi saya tidak mengerti mengapa itu penting yang Anda pilih.
Alex Sherman

Jawaban:

4

Jadi setelah pemeriksaan lebih lanjut masalah Anda sebenarnya tidak ada hubungannya dengan mengoordinasikan konversi sistem. Ini bisa dibuat lebih jelas dengan tidak menyebutkan koordinat aksial Anda X dan Y melainkan Q dan R. Masalah yang sebenarnya Anda miliki adalah kondisi loop buruk. Sampel kode asli menghasilkan delta q dan r yang Anda coba konversi, dalam loop Anda, ke koordinat absolut dan Anda membuat kesalahan. Algoritma seharusnya terlihat sebagai berikut:

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);
    }
}
Alex Sherman
sumber
Oh derp ... artikel itu bahkan menyebutkan bahwa itu adalah nilai delta :( Akan coba ini sekarang dan lihat bagaimana kelanjutannya. Terima kasih :)
aaron-bond
Terima kasih untuk ini. Ini jelas jauh lebih dekat dengan cara yang benar untuk melakukannya. Saya masih mengacaukan sesuatu dengan koordinat tetapi setidaknya saya memiliki nomor yang tepat! Untuk beberapa alasan saya berakhir dengan satu sel terlalu tinggi pada -x dan satu terlalu rendah pada + x. Saya telah memposting pic di bagian atas jika Anda tahu sesuatu tentang itu tetapi saya akan terus menyelidiki sendiri :) terima kasih atas bantuan Anda!
aaron-bond
Apakah Anda benar menafsirkan koordinat aksial? Ingatlah bahwa Anda memilih untuk menggunakan x dan y daripada x dan z, jadi jika sisa kode Anda tidak memperhitungkan perubahan ini dari contoh, itu dapat menghasilkan perilaku aneh.
Alex Sherman
Yap, saya sudah beralih sehingga itu x dan z. dx menjadi x dan z = -dx - dy ...
aaron-bond
1
Gambar baru yang Anda poskan menunjukkan 7 heks yang disorot. Inilah yang Anda harapkan dengan jarak = 1. Coba cetak nilainya. Dengan CellPosition diatur ke 0,0 dan jarak 1, heks yang Anda dapatkan seharusnya (-1, 0); (-1, 1); (0, -1); (0, 0); (0, 1); (1, -1); (1, 0)
amitp
7

Seperti yang dicatat Vector57 , masalahnya adalah Anda menggunakan sistem koordinat yang salah . Algoritma yang dijelaskan dimaksudkan untuk digunakan dengan koordinat kubus , yang memiliki komponen x, y dan z :

koordinat kubus

Ini mungkin tidak jelas dari pseudocode algoritma, tapi itu karena ini penyederhanaan dari ini :

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

... loop bersarang polos di atas x, y dan z, apa yang Anda harapkan dari algoritma rentang.

Saya tidak tahu sistem koordinat apa yang Anda gunakan, tapi saya kira itu salah satu sistem "offset koordinat", yang populer karena mudah diimplementasikan dengan menempatkan sel-sel jaringan di dalam array 2D:

mengimbangi tata letak vertikal

Ini tidak berarti Anda tidak dapat menggunakan algoritma kubus ini; itu hanya berarti Anda perlu mengkonversi dari koordinat kubus ke Anda sendiri . Misalnya, untuk mengkonversi ke / dari tata letak vertikal "odd-q", gunakan ini:

# 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
congusbongus
sumber
Saya merasa itu adalah sesuatu seperti ini. Ada bagian dari halaman itu yang menyebutkan konversi dari Cube ke Axial dan mengatakan untuk menghapus bagian z dan q dan r yang tersisa menjadi x dan y. Saya pikir saya pasti terlalu disederhanakan di sana. Terima kasih untuk ini. Penjelasan bagus tentang apa yang saya lewatkan. Saya akan mencobanya nanti! :)
aaron-bond
Saya baru saja melihat dan saya menggunakan aksial. Tentunya karena algoritma tidak menyebutkan Z, itu juga lurus q = xdan r = ysistem juga?
aaron-bond