Kareden altıgene kesintisiz dönüşüm


23

Bir ızgarada oynanan birçok oyun için altıgenler Clearly Superior Choice ™ 'dir. Maalesef, birçok bedava oyun sanatı sitesi yalnızca kare haritalar için dikişsiz döşeme setlerine sahiptir. Geçmiş bir projede bunlardan bazılarını kullandım ve bunları altıgenlere manuel olarak dönüştürdüm.

Ancak , yaşlandığımda tembelleşiyorum. Küçük bir komut dosyasıyla işlemi otomatikleştirmek kolay olmalı.

Ancak , yaşlandığımda tembelleşiyorum. Bu yüzden size dış kaynak veriyorum ve kod golf mücadelesi 1 olarak gizlerim .


Giriş

Giriş, 24 bit RGB renkli herhangi bir ortak görüntü biçiminde kare bir görüntüdür. Resim verisinin kendisi yerine girdi olarak bir dosya adı da alabilirsiniz.

Görüntünün kare olduğunu ve yan uzunluğun dörtün katı olduğunu varsayabilirsiniz.

Çıktı

Çıktı, giriş kutucuğudur, ancak altıgen bir köşeye dönüştürülür (görüntünün kendisi saydam alanlarla kare olacaktır). Bir dosyaya kaydedebilir veya ekrana görüntüleyebilirsiniz.

Yine, herhangi bir ortak görüntü formatı yapacak. Kullandığınız biçim saydamlığı destekliyorsa, arka plan alanlarının saydam olması gerekir. Olmazsa, stand-in olarak # FF00FF (bu korkunç fuşya biri) rengini kullanabilirsiniz.

Yöntem

Peki nasıl yapıyoruz? 2 kullandığım yöntem görüntüyü biraz dikey olarak sıkıştırıyor, ancak genel olarak çoğu şey için oldukça iyi görünüyor. Bu girdi resmiyle bir örnek yapacağız:

giriş

  • Ölçek: Görüntüyü 3: 2 oranına ölçeklendir. Resimlerimiz kareler olacağından, onları basitçe% 75 genişliğe ve% 50 yüksekliğe ölçeklendireceğiniz anlamına gelir. Örnek girişimiz 200x200'dür, bu yüzden bu 150x100 resimle sonuçlanır:

ezilmiş

  • Döşeme: Ölçekli görüntünüzün kopyalarını 2x2 ızgaraya yerleştirin:

Kafes

  • Kırpma: Bu 2x2 ızgarasının herhangi bir yerinden uygun büyüklükte bir altıgen yakala. Şimdi, döşeme kolaylığı için, bu altıgen tam olarak düzenli değil. Orijinal boyutta bir kare kırptıktan sonra (burada 200x200), sonra köşeleri kırpın. Kırpma çizgileri sol / sağ tarafların ortasından (kabaca) yukarıdan aşağıya doğru bir çeyrekten başlamalıdır:

büyü

Ve bu sizin çıktınız!

İşte, döşendiğinde nasıl görünebileceklerine bir örnek (buraya yakınlaştırılmış):

kiremitli

Bu kod golf, bayt cinsinden en kısa kod kazanır. Standart boşluklar vb. Uygulanır.


1 Buna inanmak ya da inanmaktan çekinmeyin.
2 Bu faydalı siteden bir tane yöntem .


13
Bu soru bir Altıgenli cevap için yalvarıyor .
Sanchises

22
@sanchises İyi şanslar.
Martin Ender,

17
Hex Agony'nin ikinci bölümünün önem kazandığı nokta budur .
kusur

2
@ mbomb007 Muhtemelen, bazen kullanılan # 00FF00 yeşil bunun yerine neredeyse hiç de fena değil. Onlar fuşya daha sık kullanmak gibi aklı başında kimse tam olarak o renk istiyorum çünkü Yine de, duygu içinde kendi sprite oldukça evrensel yüzden,: P
Geobits

3
# 3 - Oluşturduğum serin algoritmaları görmek için sabırla bekliyorum ... sonra yavaşça ve sevgiyle benim kullanımlarım için onları "ödünç aldım" ;-)
scunliffe

Yanıtlar:


10

Matlab, 223 215 209 184 163 bayt

Kireç çözme oldukça yalındır. Köşeleri kırpmak için, piksellerin üzerine bir koordinat sistemi yerleştiriyorum ve altıgen alanını belirleyen dört doğrusal eşitsizlik üzerinden bir maske yapıyorum.

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

görüntü tanımını buraya girin

Not: Bu , @ MartinBüttner'ın gönderdiği bir codegolf nim oyununa dönüştü: Alternatif olarak kodunuzu kısaltmanız gerekiyor (aynı işlevselliği sağlarken) - son 'kısaltmayı' kazandırabilecek olan = =


Yeniden boyutlandırma ölçeği hesaplamasını değiştirerek 5 bayt tasarruf edebilirsiniz [k.*[2 3]/4].
kabı

4
Arka plan alanları fuşya değil, siyah değil mi?
Karadelik

@Blackhole Bana haber verdiğin için teşekkür ederim, şimdi düzelttim, hatta bana bir sürü bayt kurtardım =)
kusur

12

Mathematica, 231 211 209 208 201 188 173 bayt

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

Bu, bir resim nesnesini alan ve bir resim nesnesi döndüren adsız bir işlevdir:

görüntü tanımını buraya girin

Burada açıklayacak çok şey olduğunu sanmıyorum, ancak not edilen bazı detaylar:

  • Normal olarak, bir resmi 2x2 döşemek için kullanırsınız ImageAssemble[{{#,#},{#,#}}], yani ImageAssemblegörüntünün kopyalarını içeren 2x2'lik bir matris verirsiniz . Bununla birlikte, ImageCollagebir grup resmi olabildiğince "iyi" olarak düzenlemeye çalışan bir çeşit sihir işlevi vardır (bunun anlamı ne olursa olsun… bireysel görüntülere ağırlık ve malzeme bile verebilirsiniz). Her neyse, eşit boyutta ve eşit (veya hiç) ağırlığa sahip dört görüntü veriyorsunuz, bunları 2x2 ızgarada da düzenleyecektir. Bu, işlev adının yanı sıra matrisin yerleştirilmesi için bazı baytları kaydetmeme izin verir.
  • Altıgen, üzerinden tek bir çokgen olarak oluşturulur Graphics. Yerleşik'i kullanıyorum RegularPolygon@6, ancak 1gerektiği kadar germek için en boy oranını zorluyorum. Maalesef, Graphicsdolguyu önlemek için birkaç pahalı seçeneğe ihtiyaç duyulmaktadır ve bunun tersi yerine siyahı beyaz hale getirmektedir. Sonuç, ile sabitlenir ColorNegateve ardından görüntünün orijinal kanallarına eklenir SetAlphaChannel.
  • Graphicsaltıgenin etrafına az miktarda dolgu maddesi koyar, ancak alfa altıgenin oyuğun tüm boyutunu kaplamasını istiyoruz. Ancak, SetAlphaChannelfarklı boyutlardaki görüntüleri, birbirlerinin üstüne ortalayarak ve en küçük boyutlara kırparak birleştirebilir. Bu, manuel olarak ayarlamak yerine PlotRangePadding->0, altıgen görüntüyü biraz ölçeklendirmek anlamına gelir ImageSize->1.05e(ve yine de `ImageSize seçeneğine ihtiyacımız var).

5

HTML5 + Javascript, 562 bayt

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

Metin kutusuyla resim URL’si olarak giriş yapar (URL, umarım bir dosya adı olarak sayılır). Verileri tuvale çıkarır.

Tüm tarayıcılarda çalışan sürüm (580 bayt):

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

Bu URL üzerinden önceki "bloklar" resmiyle test edin: http://i.stack.imgur.com/gQAZh.png


İyi iş! Ekleyerek epeyce byte tasarruf edebilirsinizid=A için <form>ve id=Biçin <canvas>, sonra değiştirilmesi l[0]ile Ave l[1]ile Bve kaldırarak l=document.body.children;. (Firefox 41'de çalışır; diğer tarayıcıların bunu desteklediğinden emin değilim.) Ayrıca, sağ kaşlı ayraçların yanında birkaç gereksiz noktalı virgül ve birkaç ekstra boşluk olduğuna inanıyorum.
ETHProductions 17:15

Diğer ipuçları: Ben Eklemek inanıyorum id=Ciçin<input> daha sonra değiştirin e.target.children[0]ile C. 0.75eşittir 3/4, 1/0.75eşittir 4/3, d/4+d/2eşittir d*3/4, ve diğer ondalıklarında bir sıfır gerekli değildir. Ben de ilk yerini alabilir inanıyoruz c.drawImageile c[p="drawImage"], daha sonra sonraki her biri ile c[p]; aynı şeyi yapabilirsin c.lineTo.
ETHProductions 17:15

4

Python 2 + PIL, 320

Resim dosyasının adını stdin'den okur.

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

Doğru, bunun için üzgünüm, PILdenemek için kullanışlı değildi ve yeterince düşünmedim. Yine de newline
ifademin yanındayım

2

PHP, 293 bayt

Okunabilirlik için bazı yeni satırlar ekledim:

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

İşte ungolfed versiyonu:

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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.