从正方形到六角形的无缝转换


23

对于在网格上进行的许多游戏来说,六边形是“明显优越的选择”。不幸的是,许多免费游戏美术网站仅具有用于正方形地图的无缝磁贴集。在过去的项目中,我使用了其中一些,并将其手动转换为六边形。

但是,我在晚年变得懒惰。用一个小的脚本来自动化该过程应该很容易。

但是,我在晚年变得懒惰。因此,我将其外包给您,并将其伪装成高尔夫挑战赛1


输入项

输入是具有24位RGB颜色的任何常见图像格式的正方形图像。您也可以将文件名而不是图像数据本身作为输入。

您可以假设图像是正方形的,并且边长是四的倍数。

输出量

输出是输入图块,但转换为六边形(图像本身将是正方形,带有透明区域)。您可以将其保存到文件或显示在屏幕上。

同样,任何常见的图像格式都可以。如果您使用的格式支持透明,则背景区域必须是透明的。如果不是,您可以使用#FF00FF颜色(可怕的紫红色)作为替代。

方法

那么我们该怎么做呢?我使用2的方法在垂直方向上稍微挤压图像,但总体而言,对于大多数情况而言,它看起来都不错。我们将使用此输入图像做一个示例:

输入

  • 缩放:将图像缩放到3:2的比例。由于我们的图像将是正方形,这意味着您只需将它们缩放到75%的宽度和50%的高度即可。我们的示例输入为200x200,因此最终得到以下150x100的图片:

压扁

  • 平铺:将缩放后的图像的副本放到2x2的网格中:

格线

  • 裁剪:从2x2网格中的任意位置抓取大小适当的六边形。现在,为了便于平铺,此六角形并非完全规则。在裁剪了原始大小的正方形(此处为200x200)后,您便裁剪了角落。裁剪线应从(大约)每个左侧/右侧的中心延伸到顶部/底部边缘的四分之一:

十六进制

这就是您的输出!

这是平铺时的外观示例(此处放大):

平铺

这是代码高尔夫,因此以字节为单位的最短代码获胜。适用标准漏洞,依此类推。


1信不信由你。
2 此帮助站点中的方法一


13
这个问题恳求一个六角答案。
桑奇斯

22
@sanchises祝你好运。
马丁·恩德

17
这就是十六进制痛苦的第二部分变得重要的地方。
瑕疵的

2
@ mbomb007可能,尽管有时使用的#00FF00绿色并不是很差。不过,我觉得他们紫红色更频繁地使用,因为没有人在他们的脑子会想,准确的颜色他们的精灵,所以这是很普遍的:P
Geobits

3
#3-我耐心等待,看看生成的很酷的算法...然后轻轻地和有爱心地“借用”它们以供我使用;-)
scunliffe

Answers:


10

Matlab,223215209184163字节

重新缩放非常直接。为了裁剪角点,我在像素上覆盖了一个坐标系,并通过四个线性不等式进行了遮罩,这些不等式确定了六边形的面积。

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

在此处输入图片说明

PS:这变成了带有@MartinBüttner提交的codegolf nim游戏:您不得不交替地缩短代码(同时提供相同的功能)-可以使最后一次“缩短”的胜利=)


通过将调整大小比例计算更改为,可以节省5个字节[k.*[2 3]/4]
烧杯

4
背景区域不应该是紫红色而不是黑色吗?
Blackhole,2015年

@Blackhole感谢您让我知道,我现在将其修复,甚至为我节省了很多字节=)
更加糟糕的

12

Mathematica,231 211 209 208 201 188 173字节

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

这是一个未命名的函数,它接受一个图像对象并返回一个图像对象:

在此处输入图片说明

我认为这里没有太多要说明的内容,但是有一些值得注意的细节:

  • 通常,要平铺2x2的图像,请使用ImageAssemble[{{#,#},{#,#}}],即ImageAssemble将2x2矩阵与图像副本一起。但是,ImageCollage其中有一种神奇的功能,它试图尽可能“好”地排列一堆图片(这意味着……您甚至可以赋予单个图像权重和填充物)。无论如何,您给它提供了四个大小相等,权重相等(或没有权重)的图像,它也会将它们排列在2x2的网格中。这使我可以为矩阵的嵌套以及函数名称节省一些字节。
  • 通过将六边形呈现为单个多边形Graphics。我使用的是内置的RegularPolygon@6,但1必须根据需要实施的高宽比以进行拉伸。不幸的是,Graphics需要一些昂贵的选择来避免填充等问题,并且它还会在白色上呈现黑色,而不是相反。将结果固定为ColorNegate,然后使用将其附加到图像的原始通道SetAlphaChannel
  • Graphics在六边形上放置少量填充,但是我们希望Alpha六边形覆盖切口的整个尺寸。但是,SetAlphaChannel可以通过将不同尺寸的图像彼此居中并裁剪为最小尺寸来组合不同尺寸的图像。这意味着,不用手动设置PlotRangePadding->0,我们可以简单地将六边形图像放大一点ImageSize->1.05e(而且我们仍然需要`ImageSize选项)。

5

HTML5 + Javascript,562个字节

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

通过文本框将输入作为图像URL(希望将该URL作为文件名)。将数据输出到画布。

适用于所有浏览器的版本(580字节):

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

通过以下URL,使用之前的“块”图像进行测试:http//i.stack.imgur.com/gQAZh.png


干得好!您可以通过添加节省不少字节id=A<form>id=B<canvas>,然后替换l[0]A,并l[1]B和删除l=document.body.children;。(在Firefox 41中工作;不确定其他浏览器是否支持此功能。)此外,我相信右花括号旁边有几个不必要的分号和一些额外的空格。
ETHproductions 2015年

更多提示:我相信您可以添加id=C<input>,然后替换e.target.children[0]C0.75等于3/41/0.75等于4/3d/4+d/2等于d*3/4,并且不需要其他小数点前的零。我也相信,你可以更换一次c.drawImagec[p="drawImage"],那么以后每一个使用c[p]; 您可以使用进行相同的操作c.lineTo
ETHproductions 2015年

4

Python 2 + PIL,320

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

的,很抱歉,没有PIL方便的尝试,我对此也没有足够的考虑。我仍然坚持我的换行声明:P
FryAmTheEggman

2

PHP,293字节

我添加了一些换行符以提高可读性:

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

这是非高尔夫版本:

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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.