วาดเส้นตรง


15

วาดภาพศิลปะ ASCII อย่างง่าย ๆ ที่มีเส้นตรง มันคล้ายกับสิ่งนี้และสิ่งนี้แต่มีข้อกำหนดที่แตกต่างกัน

อินพุต

คุณสามารถแก้ไขรูปแบบการป้อนข้อมูลนี้เพื่อให้เหมาะกับรหัสของคุณ

  • จำนวนเต็ม width
  • จำนวนเต็ม height
  • จำนวนเต็ม x0
  • จำนวนเต็ม y0
  • จำนวนเต็ม x1
  • จำนวนเต็ม y1

เอาท์พุต

ที่เต็มไปภาพศิลปะ ASCII ของความกว้างและความสูงที่กำหนดมีบรรทัดต่อจากพิกเซลพิกเซล(x0, y0)(x1, y1)

รูปแบบข้อความมาตรฐานใด ๆ ที่เป็นที่ยอมรับ แต่ไม่ได้ใช้ฟังก์ชั่นการวาดเส้นในตัว

รายละเอียด

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

พิกัดพิกเซลสามารถทำดัชนีได้ 0 หรือดัชนี 1 ดัชนีและสามารถเริ่มในมุมใดก็ได้ของภาพ ควรลากเส้นโดยการจินตนาการว่ามีเส้นย่อยพิกเซลความกว้าง 0 นิ้วเชื่อมต่อกึ่งกลางของจุดเริ่มต้นและจุดสิ้นสุดพิกเซล ทุกพิกเซลที่สายเข้าควรกรอก

การชนะ

กฎของรหัสกอล์ฟ รหัสที่สั้นที่สุดชนะ

ตัวอย่าง

IN: width, height, x0, y0, x1, y1

IN: 7, 6, 0, 0, 6, 5
OUT:
.....##
....##.
...##..
..##...
.##....
##.....

IN: 3, 3, 1, 1, 1, 1
OUT:
...
.#.
...

IN: 3, 3, 0, 2, 2, 0
OUT:
#..
.#.
..#

IN: 6, 3, 0, 0, 5, 2
OUT:
....##
.####.
##....

IN: 4, 4, -1, -1, 0, 3
OUT:
#...
#...
#...
....

4
ฉันจะพูดว่า "ยินดีต้อนรับสู่ PPCG" แต่คุณได้ลงทะเบียนที่นี่เกือบตราบเท่าที่ฉัน :-) ความท้าทายแรกที่ดี!
AdmBorkBork

เราสามารถส่งออกจุดจริงแทนที่จะเป็นช่องว่างได้หรือไม่? หรือตัวละครอื่น ๆ ยกเว้นช่องว่าง? (สมมติว่ายังรวมถึงส่วนท้าย <character> s)
Rɪᴋᴇʀ

แน่นอน! ฉันจะแก้ไข
เคอร์ติสเบคเทล

1
@AlbertRenshaw ที่จริงแล้วเมื่อฉันดูCurve บน Wikipediaมันกล่าวว่า: " ในทางคณิตศาสตร์เส้นโค้ง (หรือที่เรียกว่า เส้นโค้ง ในตำราเก่า) คือโดยทั่วไปแล้วพูดวัตถุคล้ายกับ เส้น แต่ไม่จำเป็นต้องตรง "; )
Kevin Cruijssen

1
@KevinCruijssen หมายความว่าบรรทัด ต้องตรงใช่ไหม? ;)
Albert Renshaw

คำตอบ:


2

Mathematica, 166 137 ไบต์

l:={i,j};s=Sign;f[p_,q_,h_,w_]:=Grid@Table[(1-Max[s[p-l]s[q-l],0])Boole[Abs@Mean[s@Det@{p-l+#,p-q}&/@Tuples[.5{1,-1},2]]<.6],{i,h},{j,w}]

รุ่นที่อ่านเพิ่มเติมได้:

l := {i, j}; s = Sign; 
f[p_, q_, h_, w_] := 
 Grid@Table[(1 - Max[s[p - l] s[q - l], 0]) Boole[
     Abs@Mean[
        s@Det@{p - l + #, p - q} & /@ 
         Tuples[.5 {1, -1}, 2]] < .6], {i, h}, {j, w}]

fนี้กำหนดฟังก์ชั่นที่เรียกว่า ฉันตีความข้อกำหนดอินพุตและเอาต์พุตอย่างเป็นอิสระ ฟังก์ชั่นfรับอินพุตในรูปแบบf[{x0, y0}, {x1, y1}, height, width]และกริดเป็น 1 ดัชนีเริ่มต้นที่ด้านซ้ายบน ผลลัพธ์มีลักษณะดังนี้

ตัวอย่างผลลัพธ์

ด้วยบรรทัดที่แสดงเป็น1s และพื้นหลังเป็น0s (แสดงที่นี่เพื่อf[{2, 6}, {4, 2}, 5, 7]) ภารกิจของการเปลี่ยนเมทริกซ์ Mathematica ของ1s และ0s เป็นสตริงของ#s และ.s ได้รับการตีกอล์ฟในความท้าทายอื่น ๆ อีกมากมายมาก่อนดังนั้นฉันสามารถใช้วิธีมาตรฐาน แต่ฉันไม่คิดว่าจะเพิ่มสิ่งที่น่าสนใจ

คำอธิบาย:

แนวคิดทั่วไปคือถ้าเส้นผ่านพิกเซลบางอย่างแล้วอย่างน้อยหนึ่งในสี่มุมของพิกเซลอยู่เหนือเส้นและอย่างน้อยหนึ่งอยู่ด้านล่าง เราตรวจสอบว่ามุมหนึ่งอยู่เหนือหรือใต้เส้นโดยตรวจสอบมุมระหว่างเวกเตอร์ ( {x0,y0}กับมุม) และ ( {x0,y0}ถึง{x1,y1}): ถ้ามุมนี้เป็นบวกมุมจะอยู่เหนือและถ้ามุมนั้นเป็นลบมุมจะอยู่ด้านล่าง

ถ้าเรามีสองเวกเตอร์{a1,b1}และเราสามารถตรวจสอบว่ามุมระหว่างพวกเขาเป็นบวกหรือลบโดยการหาสัญญาณของปัจจัยของเมทริกซ์ที่{a2,b2} {{a1,b1},{a2,b2}}(วิธีการเก่าของฉันในการทำสิ่งนี้ใช้เลขคณิตของจำนวนเชิงซ้อนซึ่งเป็นวิธีที่เกินไป…ดีซับซ้อน)

วิธีการทำงานในรหัสมีดังนี้:

  • {p-l+#,p-q}&/@Tuples[.5{1,-1},2]ได้รับสี่พาหะจาก{x0,y0}และมุมทั้งสี่ของพิกเซล (กับl:={i,j}พิกัดของพิกเซลที่กำหนดไว้ก่อนหน้านี้) และยังเวกเตอร์ระหว่างและ{x0,y0}{x1,y1}
  • s@Det@...ค้นหาสัญญาณของมุมระหว่างเส้นและมุมทั้งสี่ (โดยใช้s=Sign) สิ่งเหล่านี้จะเท่ากับ -1, 0 หรือ 1
  • Abs@Mean[...]<.6ตรวจสอบว่ามุมบางมุมเป็นบวกและลบ 4 อันดับของสัญญาณที่มีคุณสมบัติทั้งหมดนี้มีวิธีการระหว่าง -0.5 และ 0.5 (รวม) เพื่อให้เราเปรียบเทียบกับ 0.6 เพื่อประหยัดไบต์โดยใช้แทน<<=

ยังคงมีปัญหา: รหัสนี้อนุมานว่าบรรทัดที่ขยายไปตลอดกาลในทั้งสองทิศทาง เราจำเป็นต้องครอบตัดบรรทัดโดยการคูณด้วย1-Max[s[p-l]s[q-l],0](พบโดยการลองผิดลองถูก) ซึ่งอยู่1ภายในสี่เหลี่ยมที่กำหนดโดยจุดสิ้นสุดของเส้นและ0นอก

การครอบตัดบรรทัดด้วยสี่เหลี่ยม

ส่วนที่เหลือของรหัสทำให้ตารางของพิกเซลเหล่านี้

(เป็นโบนัสนี่เป็นความพยายามก่อนหน้านี้ด้วยวิธีที่แตกต่างอย่างสิ้นเชิงสำหรับ 181 ไบต์ :)

Quiet@Grid@Table[(1-Max[Sign[{i,j}-#3]Sign[{i,j}-#4],0])Boole[#3==#4=={i,j}||2Abs@Tr[Cross@@Thread@{{i,j},#3,#4}]/Norm[d=#3-#4]<2^.5Cos@Abs[Pi/4-Mod[ArcTan@@d,Pi/2]]],{i,#},{j,#2}]&

1
เมื่อเสร็จแล้วก็ถึงเวลาอาหารกลางวัน! (เวลา 18:30 น. …)
ไม่ใช่ต้นไม้

1

CJam, 122 ไบต์

{),V>{[I\]E.*A.+}/}:F;l~]2/~@:S~'.*f*\@:A.-_:g:E;:z:D[0=:B{D~I2*)*+:U(2/B/FU2/B/:V;}fID~\:I;F]{_Wf>\S.<+:*},{~_3$=@0tt}/N*

ลองออนไลน์

นี้โดยทั่วไปรวมสอง คำตอบที่ผมเคยเขียนความท้าทายอื่น ๆ (ส่วนใหญ่คำนวณจาก 2 หนึ่ง - ฟังก์ชั่นl)
(0, 0) เป็นมุมบนซ้ายตามธรรมชาติไม่ใช่มุมล่างซ้ายเหมือนตัวอย่างในข้อความสั่ง

ข้อมูลทั่วไป:

{),V>{[I\]E.*A.+}/}:F;กำหนดฟังก์ชั่น F ซึ่งช่วยสร้างพิกเซลทั้งหมด (พิกัดคู่) สำหรับพิกัด x ที่กำหนดให้
l~]2/~@:S~'.*f*\@:A.-_:g:E;:z:Dอ่านและประมวลผลอินพุตและสร้างเมทริกซ์ของจุดที่
0=:B{D~I2*)*+:U(2/B/FU2/B/:V;}fIวนซ้ำในพิกัด x ทั้งหมดยกเว้นอันสุดท้ายและสร้างพิกเซลที่สอดคล้องกันทั้งหมด
D~\:I;Fจะเหมือนกันสำหรับ พิกัด x สุดท้าย
{_Wf>\S.<+:*},เก็บเฉพาะพิกเซลที่ควรปรากฏภายในภาพ
{~_3$=@0tt}/ใส่ 0 ในเมทริกซ์สำหรับแต่ละพิกเซล
N*รวมเมทริกซ์ด้วยอักขระบรรทัดใหม่เพื่อแสดง

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