การแปลงอย่างราบรื่นจากสแควร์ถึงหกเหลี่ยม


23

สำหรับเกมจำนวนมากที่เล่นบนกริดรูปหกเหลี่ยมคือ Clearly Superior Choice ™ น่าเสียดายที่เว็บไซต์ศิลปะเกมฟรีหลายแห่งมีชุดไพ่เรียงต่อเนื่องสำหรับแผนที่สี่เหลี่ยมเท่านั้น ในโครงการที่ผ่านมาฉันใช้สิ่งเหล่านี้และแปลงเป็นรูปหกเหลี่ยมด้วยตนเอง

อย่างไรก็ตามฉันขี้เกียจในวัยชราของฉัน มันควรจะง่ายต่อการทำให้เป็นกระบวนการอัตโนมัติด้วยสคริปต์ขนาดเล็ก

อย่างไรก็ตามฉันขี้เกียจในวัยชราของฉัน ดังนั้นฉันจ้างให้คุณและปลอมมันเป็นความท้าทายรหัสกอล์ฟ1


อินพุต

อินพุตเป็นรูปภาพสี่เหลี่ยมจัตุรัสในรูปแบบภาพทั่วไปที่สามารถใช้สี RGB 24 บิต คุณอาจใช้ชื่อไฟล์เป็นอินพุตแทนข้อมูลภาพเอง

คุณอาจจะถือว่าภาพเป็นรูปสี่เหลี่ยมจัตุรัสและความยาวด้านนั้นเป็นเท่าของสี่

เอาท์พุต

เอาท์พุทเป็นไทล์ของอินพุต แต่แปลงเป็นรูปหกเหลี่ยม (รูปภาพเองจะเป็นสี่เหลี่ยมจัตุรัสมีพื้นที่โปร่งใส) คุณสามารถบันทึกเป็นไฟล์หรือแสดงไปที่หน้าจอ

รูปแบบภาพทั่วไปจะทำเช่นเดียวกัน หากรูปแบบที่คุณใช้สนับสนุนความโปร่งใสพื้นที่พื้นหลังจะต้องโปร่งใส หากไม่เป็นเช่นนั้นคุณอาจใช้ color # FF00FF (สีแดงอมม่วงอันน่ากลัว) เป็นสแตนอิน

วิธี

แล้วเราจะทำอย่างไร วิธีที่ฉันใช้2ทำให้ภาพแตกในแนวตั้งเล็กน้อย แต่โดยรวมแล้วมันดูค่อนข้างดีสำหรับทุกสิ่ง เราจะทำตัวอย่างกับภาพอินพุตนี้:

อินพุต

  • มาตราส่วน:ปรับอัตราส่วนภาพเป็นอัตราส่วน 3: 2 เนื่องจากรูปภาพของเราจะเป็นสี่เหลี่ยมจัตุรัสหมายความว่าคุณเพียงแค่ปรับให้กว้างถึง 75% และสูง 50% ตัวอย่างอินพุตของเราคือ 200x200 ดังนั้นเราจึงจบด้วยรูปภาพ 150x100 นี้:

แบน

  • ไทล์:วางสำเนาของภาพที่ปรับขนาดของคุณลงในตาราง 2x2:

ตะแกรง

  • ครอบตัด:หยิบรูปหกเหลี่ยมที่มีขนาดเหมาะสมจากที่ใดก็ได้ในตาราง 2x2 นี้ ตอนนี้เพื่อความสะดวกในการเรียงเลขหกเหลี่ยมนี้ไม่ปกติ หลังจากครอบตัดสี่เหลี่ยมขนาดดั้งเดิม (ที่นี่ 200x200) คุณจะครอบตัดมุม เส้นการครอบตัดควรเริ่มจากกึ่งกลางของด้านซ้าย / ขวาไปจนถึงหนึ่งในสี่จากขอบด้านบน / ล่าง:

แม่มด

และนั่นคือผลลัพธ์ของคุณ!

นี่คือตัวอย่างของสิ่งที่อาจดูเหมือนเมื่อปูกระเบื้อง (ซูมออกที่นี่):

กระเบื้อง

นี่คือรหัสกอล์ฟดังนั้นรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ ช่องโหว่มาตรฐานใช้ ฯลฯ และอื่น ๆ


1รู้สึกอิสระที่จะเชื่อสิ่งนี้หรือไม่
2วิธีที่หนึ่งจากเว็บไซต์ที่เป็นประโยชน์นี้


13
คำถามนี้ขอร้องสำหรับคำตอบ Hexagony
Sanchises

22
@sanchises โชคดี
Martin Ender

17
นั่นคือสิ่งที่ส่วนที่สองของ Hex Agonyกลายเป็นสิ่งสำคัญ
ข้อบกพร่อง

2
@ mbomb007 อาจเป็นไปได้แม้ว่า # 00FF00 สีเขียวที่บางครั้งใช้แทนก็ไม่ได้เลวร้ายนัก แต่ถึงกระนั้นฉันรู้สึกว่าพวกเขาใช้สีแดงม่วงบ่อยขึ้นเพราะไม่มีใครในใจที่เหมาะสมของพวกเขาจะต้องการสีที่แน่นอนในสไปรท์ของพวกเขาดังนั้นจึงเป็นสากลสวย: P
Geobits

3
# 3 - ฉันรออย่างอดทนเพื่อดูอัลกอริธึมสุดเจ๋งที่สร้างขึ้น ... จากนั้นค่อย ๆ และ "ยืม" อย่างน่ารักสำหรับการใช้งานของฉัน ;-)
scunliffe

คำตอบ:


10

Matlab, 223 215 209 184 163 ไบต์

การลดขนาดค่อนข้างตรงไปตรงมา สำหรับการครอบตัดมุมฉันซ้อนทับระบบพิกัดเหนือพิกเซลและทำหน้ากากผ่านสี่สมการเชิงเส้นซึ่งกำหนดพื้นที่ของรูปหกเหลี่ยม

​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: สิ่งนี้กลายเป็นเกมcodegolf nim ที่มีการส่งของ @ MartinBüttner: คุณสลับกันทำให้รหัสของคุณสั้นลง (ในขณะที่มีฟังก์ชั่นการทำงานเดียวกัน) - สิ่งหนึ่งที่สามารถทำให้ 'shortening' ชนะ =)


คุณสามารถบันทึก 5 [k.*[2 3]/4]ไบต์โดยการเปลี่ยนการคำนวณการปรับขนาดขนาดที่จะ
บีกเกอร์

4
พื้นที่พื้นหลังไม่ควรเป็นบานเย็นไม่ใช่สีดำใช่ไหม
Blackhole

ขอบคุณสำหรับ @Blackhole ให้ฉันรู้ว่าฉันคงมันตอนนี้แม้บันทึกฉันค่อนข้างพวงของไบต์ = บริการ)
flawr

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ต้องมีตัวเลือกที่มีราคาแพงสองตัวเพื่อหลีกเลี่ยงช่องว่างภายในและเช่นกันและมันยังแสดงผลสีดำบนพื้นสีขาวแทนที่จะเป็นตรงกันข้าม ผลที่ได้คือการแก้ไขด้วยและที่แนบมากับช่องเดิมภาพที่มีแล้วColorNegateSetAlphaChannel
  • Graphicsวาง padding เล็กน้อยรอบ ๆ หกเหลี่ยม แต่เราต้องการให้ alpha hexagon ครอบคลุมขนาดเต็มของ cutout อย่างไรก็ตามSetAlphaChannelสามารถรวมภาพที่มีขนาดแตกต่างกันโดยจัดให้อยู่ตรงกลางของภาพแต่ละภาพและครอบตัดให้มีขนาดเล็กที่สุด ซึ่งหมายความว่าแทนที่จะตั้งค่าด้วยตนเองPlotRangePadding->0เราสามารถขยายภาพหกเหลี่ยมได้เล็กน้อยด้วยImageSize->1.05e(และเราต้องการตัวเลือก 'ขนาดภาพต่อไป')

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

เคล็ดลับเพิ่มเติม: ผมเชื่อว่าคุณสามารถเพิ่มid=Cไป<input>แล้วแทนที่ด้วยe.target.children[0] มีค่าเท่ากับ, เท่ากับ, เท่ากับ, และเลขศูนย์นำหน้าบนทศนิยมอื่น ๆ ไม่จำเป็น ฉันยังเชื่อว่าคุณสามารถแทนที่อันแรกด้วยจากนั้นทุกอันที่ตามมาด้วย; คุณสามารถทำเช่นเดียวกันกับ C0.753/41/0.754/3d/4+d/2d*3/4c.drawImagec[p="drawImage"]c[p]c.lineTo
ETHproductions

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);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.