Konversi tanpa batas dari kotak ke segi enam

23

Untuk banyak game yang dimainkan di grid, hexagon adalah Clearly Superior Choice ™. Sayangnya, banyak situs seni permainan gratis hanya memiliki set ubin yang mulus untuk peta persegi. Pada proyek sebelumnya, saya menggunakan beberapa di antaranya, dan secara manual mengubahnya menjadi segi enam.

Namun , saya sudah malas di usia tua saya. Seharusnya mudah untuk mengotomatiskan proses dengan skrip kecil.

Namun , saya sudah malas di usia tua saya. Jadi saya outsourcing untuk Anda, dan menyamarkannya sebagai tantangan kode golf 1 .


Memasukkan

Input adalah gambar persegi dalam format gambar umum apa pun yang mampu warna RGB 24-bit. Anda juga dapat menggunakan nama file sebagai input dan bukan data gambar itu sendiri.

Anda dapat menganggap gambar itu persegi, dan panjang sisi adalah kelipatan empat.

Keluaran

Output adalah ubin input, tetapi dikonversi ke segi enam (gambar itu sendiri akan persegi, dengan area transparan). Anda dapat menyimpannya ke file atau tampilan ke layar.

Sekali lagi, format gambar umum apa pun akan dilakukan. Jika format yang Anda gunakan mendukung transparansi, area latar belakang harus transparan. Jika tidak, Anda dapat menggunakan warna # FF00FF (yang fuchsia mengerikan) sebagai pengganti.

metode

jadi bagaimana kita melakukannya? Metode yang saya gunakan 2 squash gambar sedikit vertikal, tetapi secara keseluruhan terlihat cukup bagus untuk sebagian besar hal. Kami akan melakukan contoh dengan gambar input ini:

memasukkan

  • Skala: Skala gambar ke rasio 3: 2. Karena gambar kami akan berbentuk bujur sangkar, ini berarti Anda cukup menskalakannya menjadi 75% lebar dan 50% tinggi. Input contoh kami adalah 200x200, jadi kami menghasilkan gambar 150x100 ini:

tergencet

  • Tile: Taruh salinan gambar yang Anda diskalakan dalam kisi 2x2:

kisi

  • Pangkas: Ambil hexagon berukuran tepat dari mana saja di kisi 2x2 ini. Sekarang, untuk kemudahan pemasangan, segi enam ini tidak terlalu teratur. Setelah memotong kuadrat dari ukuran aslinya (di sini 200x200), Anda kemudian memotong sudut. Garis pangkas harus berjalan dari (kira-kira) pusat dari setiap sisi kiri / kanan ke seperempat dari tepi di atas / bawah:

hex

Dan itu adalah hasil Anda!

Berikut ini contoh tampilannya saat ubin (diperbesar di sini):

ubin

Ini adalah kode golf, jadi kode terpendek dalam byte menang. Celah standar berlaku, dll.


1 Jangan ragu untuk percaya ini atau tidak.
2 Metode satu dari situs bermanfaat ini.

Geobit
sumber
13
Pertanyaan ini meminta jawaban Hexagony.
Sanchises
22
semoga berhasil.
Martin Ender
17
Di situlah bagian kedua Hex Agony menjadi penting.
flawr
2
@ mbomb007 Mungkin, meskipun hijau # 00FF00 yang terkadang digunakan malah tidak terlalu buruk. Namun, saya merasa mereka lebih sering menggunakan fuchsia karena tidak ada orang waras yang menginginkan warna yang tepat dalam sprite mereka, jadi itu sangat universal: P
Geobits
3
# 3 - Saya menunggu ini dengan sabar untuk melihat algoritma keren yang dihasilkan ... kemudian dengan lembut dan penuh cinta "pinjam" untuk saya gunakan ;-)
scunliffe

Jawaban:

10

Matlab, 223 215 209 184 163 byte

Penyalinan kembali cukup lurus ke depan. Untuk memotong sudut saya overlay sistem koordinat atas piksel, dan membuat topeng melalui empat ketidaksetaraan linier, yang menentukan luas segi enam.

​l=imread(input(''));
u=size(l,1);
L=imresize(l,u*[2 3]/4);
L=[L,L;L,L];L=L(1:u,1:u,:);
[x,y]=meshgrid(1:u);
r=u/2;x=x*2;
set(imshow(L),'Al',y<x+r&y+x>r&y+x<5*r&y>x-3*r)

masukkan deskripsi gambar di sini

PS: Ini berubah menjadi permainan codegolf nim dengan pengajuan @ MartinBüttner: Anda secara bergantian harus membuat kode Anda lebih pendek (sambil memberikan fungsionalitas yang sama) - yang dapat membuat 'pemendekan' terakhir menang =)

cacat
sumber
Anda dapat menyimpan 5 byte dengan mengubah perhitungan skala ukuran ke [k.*[2 3]/4].
Gelas
4
Bukankah seharusnya area latar belakang fuchsia, bukan hitam?
Lubang Hitam
@ Blackhole Terima kasih telah memberi tahu saya, saya memperbaikinya sekarang, bahkan menyelamatkan saya cukup banyak byte =)
flawr
12

Mathematica, 231 211 209 208 201 188 173 byte

ImageCrop[ImageCollage@{#,#,#,#},e,Left]~SetAlphaChannel~ColorNegate@Graphics[RegularPolygon@6,ImageSize->1.05e,AspectRatio->1]&@ImageResize[#,{3,2}(e=ImageDimensions@#)/4]&

Ini adalah fungsi tanpa nama yang mengambil objek gambar dan mengembalikan objek gambar:

masukkan deskripsi gambar di sini

Saya rasa tidak banyak yang bisa dijelaskan di sini, tetapi beberapa detail yang perlu diperhatikan:

  • Biasanya, untuk memasang gambar 2x2, Anda akan menggunakan ImageAssemble[{{#,#},{#,#}}], yaitu Anda menyerahkan ImageAssemblematriks 2x2 dengan salinan gambar. Namun adaImageCollage yang semacam fungsi sihir yang mencoba untuk mengatur banyak gambar "sebaik" mungkin (apa pun artinya ... Anda bahkan dapat memberikan bobot dan barang gambar individu). Bagaimanapun, jika Anda memberikannya empat gambar dengan ukuran yang sama dan dengan bobot yang sama (atau tidak sama), itu juga akan mengaturnya dalam kisi 2x2. Itu memungkinkan saya untuk menyimpan beberapa byte untuk bersarang dari matriks, serta nama fungsi.
  • Hexagon diberikan sebagai satu poligon via Graphics. Saya menggunakan built-in RegularPolygon@6, tetapi menerapkan rasio aspek 1untuk meregangkannya jika diperlukan. Sayangnya, Graphicsperlu beberapa opsi mahal untuk menghindari bantalan dan semacamnya, dan itu juga menjadikan hitam putih bukannya sebaliknya. Hasilnya diperbaiki dengan ColorNegatedan kemudian dilampirkan ke saluran asli gambar denganSetAlphaChannel .
  • Graphicsmenempatkan sejumlah kecil padding di sekitar segi enam, tetapi kami ingin alpha hexagon untuk menutupi ukuran penuh potongan itu. Namun, SetAlphaChanneldapat menggabungkan gambar dengan ukuran berbeda, dengan memusatkannya di atas satu sama lain dan memotong ke ukuran terkecil. Itu berarti, alih-alih mengatur secara manual PlotRangePadding->0, kita cukup meningkatkan skala gambar segi enam dengan ImageSize->1.05e(dan kita tetap memerlukan opsi `ImageSize).
Martin Ender
sumber
5

HTML5 + Javascript, 562 byte

<html><form><input type=text></form><canvas><script>l=document.body.children;l[0].addEventListener("submit",e=>{e.preventDefault();c=l[1].getContext("2d");i=new Image();i.onload=q=>{l[1].width=l[1].height=d=i.width;c.scale(0.75,0.5);c.drawImage(i,0,0);c.drawImage(i,d,0);c.drawImage(i,0,d);c.drawImage(i,d,d);c.globalCompositeOperation="destination-in";c.scale(1/0.75,2);c.beginPath();c.moveTo(d/4,0);c.lineTo(d/4+d/2,0);c.lineTo(d, d/2);c.lineTo(d/4+d/2, d);c.lineTo(d/4, d);c.lineTo(0, d/2);c.closePath();c.fill();};i.src=e.target.children[0].value;})</script>

Mengambil input sebagai URL gambar melalui kotak teks (URL semoga dianggap sebagai nama file). Output data ke kanvas.

Versi yang berfungsi di semua browser (580 byte):

<html><form><input type=text></form><canvas><script>l=document.body.children;l[0].addEventListener("submit",function(e){e.preventDefault();c=l[1].getContext("2d");i=new Image();i.onload=function(){l[1].width=l[1].height=d=i.width;c.scale(0.75,0.5);c.drawImage(i,0,0);c.drawImage(i,d,0);c.drawImage(i,0,d);c.drawImage(i,d,d);c.globalCompositeOperation = "destination-in";c.scale(1/0.75,2);c.beginPath();c.moveTo(d/4, 0);c.lineTo(d/4+d/2,0);c.lineTo(d, d/2);c.lineTo(d/4+d/2, d);c.lineTo(d/4, d);c.lineTo(0, d/2);c.closePath();c.fill();};i.src=e.target.children[0].value;})</script>

Uji dengan gambar "blok" dari sebelumnya melalui URL ini: http://i.stack.imgur.com/gQAZh.png

adroit whiz
sumber
Kerja bagus! Anda dapat menyimpan beberapa byte dengan menambahkan id=Ake <form>dan id=Bke <canvas>, kemudian mengganti l[0]dengan Adan l[1]dengan B, dan menghapus l=document.body.children;. (Bekerja di Firefox 41; tidak yakin browser mana yang mendukung ini.) Juga, saya percaya ada beberapa titik koma yang tidak perlu di sebelah tanda kurung kurawal, dan beberapa ruang ekstra.
ETHproduksi
Kiat lainnya: Saya yakin Anda bisa menambahkan id=C ke <input>, kemudian ganti e.target.children[0]dengan C. 0.75sama dengan 3/4, 1/0.75sama dengan 4/3, d/4+d/2sama dengan d*3/4, dan memimpin nol pada desimal lainnya tidak diperlukan. Saya juga yakin Anda bisa mengganti yang pertama c.drawImagedengan c[p="drawImage"], lalu setiap yang berikutnya dengan c[p]; Anda dapat melakukan hal yang sama dengannya c.lineTo.
ETHproduksi
4

Python 2 + PIL, 320

Membaca nama file gambar dari stdin.

from PIL import ImageDraw as D,Image as I
i=I.open(raw_input())
C=A,B=i.size
i,j=i.resize((int(.75*A),B/2)),I.new('RGBA',C)
W,H=i.size
for a,b in[(0,0),(0,H),(W,0),(W,H)]:j.paste(i,(a,b,a+W,b+H))
p,d=[(0,0),(A/4,0),(0,B/2),(A/4,B),(0,B)],lambda p:D.Draw(j).polygon(p,fill=(0,)*4)
d(p)
d([(A-x,B-y)for x,y in p])
j.show()
pelaku diet
sumber
Benar, maaf soal itu, tidak ada PILgunanya mencoba dan saya tidak cukup memikirkannya. Saya masih mendukung pernyataan baris baru saya: P
FryAmTheEggman
2

PHP, 293 byte

Saya telah menambahkan beberapa baris baru untuk keterbacaan:

function($t){$s=imagesx($t);imagesettile($i=imagecreatetruecolor($s,$s),$t=imagescale
($t,$a=$s*3/4,$b=$s/2));imagefill($i,0,0,IMG_COLOR_TILED);$z=imagefilledpolygon;$z($i,
[0,0,$s/4,0,0,$b,$s/4,$s,0,$s],5,$f=imagecolorallocate($i,255,0,255));$z($i,[$s,0,$a,
0,$s,$b,$a,$s,$s,$s],5,$f);return$i;}

Ini adalah versi yang tidak dikoleksi:

function squareToHexagon($squareImage)
{
    $size = imagesx($squareImage);
    $tileImage = imagescale($squareImage, $size * 3/4, $size/2);

    $hexagonImage = imagecreatetruecolor($size, $size);
    imagesettile($hexagonImage, $tileImage);
    imagefill($hexagonImage, 0, 0, IMG_COLOR_TILED);

    $fuchsia = imagecolorallocate($hexagonImage, 255, 0, 255);
    imagefilledpolygon(
        $hexagonImage,
        [
            0,       0,
            $size/4, 0,
            0,       $size/2,
            $size/4, $size,
            0,       $size,
        ],
        5,
        $fuchsia
    );
    imagefilledpolygon(
        $hexagonImage,
        [
            $size,       0,
            $size * 3/4, 0,
            $size,       $size/2,
            $size * 3/4, $size,
            $size,       $size,
        ],
        5,
        $fuchsia
    );

    return $hexagonImage;
}

header('Content-type: image/gif');
$squareImage = imagecreatefrompng('squareImage.png');
$hexagonImage = squareToHexagon($squareImage);
imagegif($hexagonImage);
Lubang hitam
sumber