정사각형에서 육각형으로 원활한 변환


23

그리드에서 플레이하는 많은 게임에서 육각형은 Clearly Superior Choice ™입니다. 불행히도, 많은 무료 게임 아트 사이트에는 정사각형 맵에 대한 완벽한 타일 세트 만 있습니다. 과거 프로젝트에서 나는 이것들 중 일부를 사용하여 수동으로 육각형으로 변환했습니다.

그러나 나는 노년기에 게으르다. 작은 스크립트로 프로세스를 쉽게 자동화 할 수 있어야합니다.

그러나 나는 노년기에 게으르다. 그래서 나는 그것을 당신에게 아웃소싱하고 코드 골프 챌린지 1 로 위장합니다 .


입력

입력은 24 비트 RGB 색상이 가능한 일반적인 이미지 형식의 정사각형 이미지입니다. 이미지 데이터 자체 대신 파일 이름을 입력으로 사용할 수도 있습니다.

이미지가 정사각형이고 측면 길이가 4의 배수라고 가정 할 수 있습니다.

산출

출력은 입력 타일이지만 육각형으로 변환됩니다 (이미지 자체는 정사각형이며 투명 영역이 있음). 파일로 저장하거나 화면에 표시 할 수 있습니다.

다시 말하지만 모든 일반적인 이미지 형식이 수행됩니다. 사용중인 형식이 투명도를 지원하면 배경 영역이 투명해야합니다. 그렇지 않은 경우 색상 # FF00FF (끔찍한 자홍색)를 독립형으로 사용할 수 있습니다.

방법

그래서 우리는 어떻게합니까? 2를 사용하는 방법 은 이미지를 세로로 약간 스쿼시하지만 전반적으로 대부분의 경우 꽤 좋아 보입니다. 이 입력 이미지를 예로 들어 보겠습니다.

입력

  • 스케일 : 이미지를 3 : 2 비율로 스케일합니다. 이미지가 정사각형이므로 너비 75 %, 높이 50 %로 이미지 크기를 조정하면됩니다. 입력 예는 200x200이므로이 150x100 이미지로 끝납니다.

숙청

  • 타일 ​​: 크기가 조정 된 이미지의 사본을 2x2 격자에 놓습니다.

그리드

  • 자르기 : 이 2x2 격자의 어느 곳에서나 적절한 크기의 육각형을 잡으십시오. 타일링을 쉽게하기 위해이 육각형은 정확히 규칙적이지 않습니다. 원래 크기 (여기서는 200x200)의 정사각형을 자른 후 모서리를 자릅니다. 자르기 선은 각 왼쪽 / 오른쪽의 중심에서 위 / 아래의 가장자리에서 1/4까지 이어져야합니다.

마녀

그리고 그것은 당신의 출력입니다!

바둑판 식으로 배열했을 때의 모습에 대한 예는 다음과 같습니다 (여기에서 확대).

타일

이것은 코드 골프이므로 바이트 단위의 가장 짧은 코드가 이깁니다. 표준 허점 등이 적용됩니다.


1 믿거 나 말거나 믿어주십시오.
2 이 유용한 사이트의 방법 1입니다 .


13
이 질문은 Hexagony 답변을 구걸 하고 있습니다.
Sanchises

22
@sanchises 행운을 빕니다.
Martin Ender

17
Hex Agony 의 두 번째 부분 이 중요한 곳입니다.
flawr

2
@ mbomb007 아마도 때때로 사용되는 # 00FF00 녹색은 그다지 나쁘지 않습니다. 그래도, 나는 올바른 마음에 아무도 그들의 스프라이트에 정확한 색 원하지 않기 때문에 자홍색을 더 자주 사용하는 것처럼 느낍니다 . 그래서 그것은 보편적입니다. : P
Geobits

3
# 3-나는 멋진 알고리즘이 생성되는 것을보기 위해 참을성있게 기다립니다 ... 그런 다음 부드럽게 그리고 사랑스럽게 내 사용을 위해 그것들을 "빌려줍니다";-)
scunliffe

답변:


10

Matlab, 223215209184163 바이트

크기 조정은 매우 간단합니다. 모서리를 자르기 위해 픽셀 위에 좌표계를 오버레이하고 육각형의 면적을 결정하는 4 개의 선형 불평등을 통해 마스크를 만듭니다.

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

여기에 이미지 설명을 입력하십시오

추신 : 이것은 @ MartinBüttner의 제출 로 codegolf nim 게임으로 바뀌 었습니다 : 동일한 기능을 제공하면서 코드를 짧게 만들어야합니다-마지막 '단축'을 이길 수있는 게임 =)


크기 조정 스케일 계산을로 변경하여 5 바이트를 절약 할 수 있습니다 [k.*[2 3]/4].
비이커

4
배경 영역이 자홍색이 아닌 자홍색이 아니어야합니까?
Blackhole

@Blackhole 알려 주셔서 감사합니다. 지금 고쳤으며 심지어 많은 바이트를 절약했습니다. =)
flawr

12

매쓰, 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어떤 종류의 그림을 가능한 한 "잘"정렬하려고 시도하는 일종의 마술 기능이 있습니다 (무엇이든, 개별 이미지에 무게와 물건을 줄 수도 있음). 어쨌든 동일한 크기와 동일한 (또는없는) 가중치의 4 개의 이미지를 제공하고 2x2 격자로 정렬합니다. 이를 통해 함수 이름뿐만 아니라 행렬의 중첩을 위해 바이트를 저장할 수 있습니다.
  • 육각형은를 통해 단일 다각형으로 렌더링됩니다 Graphics. 내장을 사용하고 RegularPolygon@6있지만 1필요에 따라 가로 세로 비율 을 늘려야합니다. 안타깝게도 Graphics패딩 등을 피하기 위해 몇 가지 고가의 옵션이 필요하며 반대가 아닌 흰색이 검은 색으로 표시됩니다. 결과는로 고정 된 ColorNegate다음 이미지의 원래 채널에로 고정 됩니다 SetAlphaChannel.
  • Graphics육각형 주위에 소량의 패딩을 넣지 만 알파 육각형이 컷 아웃의 전체 크기를 덮기를 원합니다. 그러나 SetAlphaChannel서로 다른 크기의 이미지를 중앙에 놓고 가장 작은 크기로 자르면 서로 다른 크기의 이미지를 결합 할 수 있습니다. 즉, 수동으로 설정하는 대신 PlotRangePadding->0육각 이미지를 약간 확장 할 수 있습니다 ImageSize->1.05e(그리고 어쨌든`ImageSize 옵션이 필요합니다].

5

HTML5 + 자바 스크립트, 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>

http://i.stack.imgur.com/gQAZh.png 다음 URL을 통해 "블록"이미지로 테스트하십시오.


잘 하셨어요! 당신은 추가하여 꽤 많은 바이트를 저장할 수있는 id=A받는 사람 <form>id=B받는 사람 <canvas>한 후, 교체 l[0]Al[1]함께 B, 및 제거 l=document.body.children;. (Firefox 41에서 작동합니다. 다른 브라우저가이를 지원하는지 확실하지 않습니다.) 또한 오른쪽 중괄호 옆에 불필요한 세미콜론 몇 개와 여분의 공백이 있다고 생각합니다.
ETHproductions

더 많은 정보는 : 나는 당신이 추가 할 수 있으리라 생각 id=C받는 <input>후 교체 e.target.children[0]와 함께 C. 0.75같은지 3/4, 1/0.75같은지 4/3, d/4+d/2같은지 d*3/4, 다른 소수의 선행 0은 필요하지 않다. 또한 첫 번째 대체 할 수있는 생각 c.drawImage과 함께 c[p="drawImage"], 다음 이후의 모든 하나 c[p]; 당신도 같은 일을 할 수 c.lineTo있습니다.
ETHproductions

4

파이썬 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;}

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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.