Conversione senza soluzione di continuità da quadrato a esagono


23

Per molte partite giocate su una griglia, gli esagoni sono Clearly Superior Choice ™. Sfortunatamente, molti siti di arte di gioco gratuiti hanno solo set di tessere senza soluzione di continuità per le mappe quadrate. In un progetto passato, ho usato alcuni di questi e li ho convertiti manualmente in esagoni.

Tuttavia , sono diventato pigro nella mia vecchiaia. Dovrebbe essere facile automatizzare il processo con un piccolo script.

Tuttavia , sono diventato pigro nella mia vecchiaia. Quindi lo sto esternalizzando a te e lo camuffo come una sfida di golf del codice 1 .


Ingresso

L'input è un'immagine quadrata in qualsiasi formato immagine comune in grado di colori RGB a 24 bit. Puoi anche prendere un nome file come input invece dei dati dell'immagine stessa.

Si può presumere che l'immagine sia quadrata e che la lunghezza laterale sia un multiplo di quattro.

Produzione

L'output è il riquadro di input, ma convertito in un esagono (l'immagine stessa sarà quadrata, con aree trasparenti). È possibile salvarlo in un file o visualizzarlo sullo schermo.

Ancora una volta, qualsiasi formato di immagine comune farà. Se il formato che stai utilizzando supporta la trasparenza, le aree di sfondo devono essere trasparenti. In caso contrario, puoi usare il colore # FF00FF (quello orribile fucsia) come stand-in.

Metodo

Quindi come lo facciamo? Il metodo che uso 2 schiaccia l'immagine un po 'verticalmente, ma nel complesso sembra abbastanza buono per la maggior parte delle cose. Faremo un esempio con questa immagine di input:

ingresso

  • Ridimensiona: ridimensiona l'immagine in un rapporto 3: 2. Poiché le nostre immagini saranno quadrate, ciò significa che le ridimensionerai semplicemente al 75% in larghezza e al 50% in altezza. Il nostro esempio di input è 200x200, quindi finiamo con questa immagine 150x100:

schiacciata

  • Affianca: posiziona le copie dell'immagine ridimensionata in una griglia 2x2:

griglia

  • Ritaglia: prendi un esagono di dimensioni adeguate da qualsiasi punto di questa griglia 2x2. Ora, per facilità di piastrellatura, questo esagono non è esattamente regolare. Dopo aver ritagliato un quadrato delle dimensioni originali (qui 200x200), ritaglia gli angoli. Le linee di ritaglio dovrebbero andare dal (approssimativamente) il centro di ciascun lato sinistro / destro a un quarto dal bordo in alto / in basso:

esadecimale

E questo è il tuo risultato!

Ecco un esempio di come potrebbe apparire quando piastrellato (ingrandito qui):

piastrelle

Questo è il codice golf, quindi vince il codice più breve in byte. Si applicano scappatoie standard, ecc. Ecc.


1 Sentiti libero di crederci o no.
2 Metodo uno da questo sito utile.


13
Questa domanda è l'accattonaggio per una risposta Hexagony.
Sanchises,

22
@sanchises Buona fortuna.
Martin Ender,

17
È qui che diventa importante la seconda parte di Hex Agony .
Flawr

2
@ mbomb007 Probabilmente, anche se il verde # 00FF00 a volte usato invece non è poi così male. Tuttavia, sento che usano la fucsia più spesso perché nessuno nella loro mente giusta vorrebbe quel colore esatto nei loro sprite, quindi è abbastanza universale: P
Geobits

3
# 3 -
Aspetto

Risposte:


10

Matlab, 223 215 209 184 163 byte

Il riscalaggio è piuttosto semplice. Per ritagliare gli angoli sovrappongo un sistema di coordinate sopra i pixel e realizzo una maschera tramite quattro disuguaglianze lineari, che determinano l'area dell'esagono.

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

inserisci qui la descrizione dell'immagine

PS: questo si è trasformato in un gioco codegolf nim con l'invio di @ MartinBüttner: alternativamente devi accorciare il tuo codice (fornendo allo stesso tempo la stessa funzionalità) - quello che può rendere vincente l'ultimo 'accorciamento' =)


È possibile salvare 5 byte modificando il calcolo della scala di ridimensionamento in [k.*[2 3]/4].
becher

4
Le aree di sfondo non dovrebbero essere fucsia, non nere?
Blackhole,

@Blackhole Grazie per avermelo fatto sapere, l'ho risolto ora, mi ha anche salvato un bel po 'di 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]&

Questa è una funzione senza nome che accetta un oggetto immagine e restituisce un oggetto immagine:

inserisci qui la descrizione dell'immagine

Non credo che ci sia molto da spiegare qui, ma alcuni dettagli che sono importanti:

  • Normalmente, per affiancare un'immagine 2x2, useresti ImageAssemble[{{#,#},{#,#}}], cioè ImageAssembleporgi una matrice 2x2 con copie dell'immagine. Tuttavia, c'è ImageCollageuna sorta di funzione magica che cerca di organizzare un gruppo di immagini il più "possibile" (qualunque cosa significhi ... puoi persino dare alle singole immagini pesi e cose). Ad ogni modo, se le dai quattro immagini di uguali dimensioni e con pesi uguali (o no), le disporrà anche in una griglia 2x2. Ciò mi consente di salvare alcuni byte per l'annidamento della matrice, nonché il nome della funzione.
  • L'esagono è reso come un singolo poligono via Graphics. Sto usando il built-in RegularPolygon@6, ma impongo un rapporto di 1allungamento come necessario. Sfortunatamente, ha Graphicsbisogno di un paio di opzioni costose per evitare l'imbottitura e simili, e rende anche il nero su bianco anziché il contrario. Il risultato viene corretto con ColorNegatee quindi collegato ai canali originali dell'immagine con SetAlphaChannel.
  • Graphicsmette una piccola quantità di imbottitura attorno all'esagono, ma vogliamo che l'esagono alfa copra l'intera dimensione del ritaglio. Tuttavia, SetAlphaChannelpuoi combinare immagini di dimensioni diverse, centrandole una sopra l'altra e ritagliandole alla dimensione più piccola. Ciò significa che, invece di impostare manualmente PlotRangePadding->0, possiamo semplicemente ImageSize->1.05eingrandire leggermente l'immagine esagonale con (e abbiamo comunque bisogno dell'opzione `ImageSize).

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>

Accetta input come URL di immagine tramite casella di testo (si spera che l'URL contenga come nome file). Invia i dati su tela.

Versione che funziona su tutti i 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>

Provalo con l'immagine "blocchi" di prima tramite questo URL: http://i.stack.imgur.com/gQAZh.png


Bel lavoro! È possibile salvare alcuni byte aggiungendo id=Aa <form>e id=Ba <canvas>, quindi sostituendo l[0]con Ae l[1]con Be rimuovendo l=document.body.children;. (Funziona in Firefox 41; non sono sicuro di quali altri browser supportano questo.) Inoltre, credo che ci siano un paio di punti e virgola non necessari accanto alle parentesi graffe a destra e alcuni spazi extra.
ETHproductions

Altri suggerimenti: credo che potresti aggiungere id=Ca <input>, quindi sostituire e.target.children[0]con C. 0.75è uguale a 3/4, 1/0.75è uguale a 4/3, d/4+d/2è uguale a d*3/4e gli zero iniziali sugli altri decimali non sono necessari. Credo anche che potresti sostituire il primo c.drawImagecon c[p="drawImage"], poi ogni successivo con c[p]; potresti fare lo stesso con c.lineTo.
ETHproductions

4

Python 2 + PIL, 320

Legge il nome del file immagine da 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()

Vero, mi dispiace, non ho avuto a PILportata di mano e non ci ho pensato abbastanza.
Resto comunque fedele alla

2

PHP, 293 byte

Ho aggiunto alcune nuove righe per la leggibilità:

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

Ecco la versione ungolfed:

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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.