Gambar Garis Lurus

15

Gambarlah gambar seni ASCII sederhana yang berisi garis lurus. Ini mirip dengan ini dan ini tetapi dengan spesifikasi yang berbeda.

Memasukkan

Anda dapat mengubah format input ini agar sesuai dengan kode Anda.

  • bilangan bulat width
  • bilangan bulat height
  • bilangan bulat x0
  • bilangan bulat y0
  • bilangan bulat x1
  • bilangan bulat y1

Keluaran

Gambar seni ASCII terisi dari lebar dan tinggi yang ditentukan yang mengandung garis dari piksel (x0, y0)ke piksel (x1, y1).

Segala bentuk standar output teks dapat diterima, tetapi jangan gunakan fungsi menggambar garis bawaan.

Detail

Garis harus digambar dengan menggunakan satu karakter yang dapat dicetak (seperti #), sementara latar belakang diisi dengan karakter yang berbeda (seperti .). Anda harus mencetak karakter tambahan yang diperlukan agar ukuran gambar benar.

Koordinat piksel dapat diindeks 0 atau diindeks 1 dan dapat dimulai dari sudut gambar mana saja. Garis harus digambar dengan membayangkan garis sub-piksel 0-lebar yang menghubungkan pusat piksel awal dan akhir. Setiap piksel yang dimasukkan garis harus diisi.

Kemenangan

Aturan golf-aturan biasa. Kode terpendek menang.

Contohnya

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:
#...
#...
#...
....
Curtis Bechtel
sumber
4
Saya akan mengatakan "Selamat datang di PPCG" tetapi Anda sudah terdaftar di sini selama saya. :-) Tantangan pertama yang bagus!
AdmBorkBork
Bisakah kita menampilkan titik-titik aktual dan bukan spasi? atau karakter lain selain spasi? (dengan asumsi masih termasuk
jejak
Tentu! Saya akan mengeditnya
Curtis Bechtel
1
@AlbertRenshaw Sebenarnya, ketika saya melihat Curve di Wikipedia itu menyatakan: " Dalam matematika, kurva (juga disebut garis lengkung dalam teks yang lebih tua), secara umum, adalah objek yang mirip dengan garis tetapi itu tidak perlu lurus. "; )
Kevin Cruijssen
1
@KevinCruijssen Menyiratkan bahwa garis harus lurus , bukan? ;)
Albert Renshaw

Jawaban:

2

Mathematica, 166 137 byte

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

Versi yang lebih mudah dibaca:

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

Ini mendefinisikan fungsi yang disebut f. Saya menginterpretasikan spesifikasi input dan output secara bebas. Fungsi ini fmengambil input dalam format f[{x0, y0}, {x1, y1}, height, width], dan kisi diindeks 1, mulai dari kiri atas. Outputnya seperti

Output sampel

dengan garis ditampilkan sebagai 1s dan latar belakang sebagai 0s (ditampilkan di sini untuk f[{2, 6}, {4, 2}, 5, 7]). Tugas mengubah matriks Mathematica 1s dan 0s menjadi string #s dan .s telah di-golf dalam banyak tantangan lain sebelumnya, jadi saya hanya bisa menggunakan metode standar, tapi saya tidak berpikir itu menambahkan sesuatu yang menarik.

Penjelasan:

Gagasan umum adalah jika garis melewati beberapa piksel, maka setidaknya satu dari empat sudut piksel berada di atas garis, dan setidaknya satu di bawah. Kami memeriksa apakah sudut berada di atas atau di bawah garis dengan memeriksa sudut antara vektor ( {x0,y0}ke sudut) dan ( {x0,y0}ke {x1,y1}): jika sudut ini positif, sudut di atas, dan jika sudut negatif, sudut di bawah.

Jika kita memiliki dua vektor {a1,b1} dan {a2,b2}, kita dapat memeriksa apakah sudut di antara mereka positif atau negatif dengan menemukan tanda penentu matriks {{a1,b1},{a2,b2}}. (Metode lama saya melakukan ini menggunakan aritmatika bilangan kompleks, yang terlalu ... well, kompleks.)

Cara ini bekerja dalam kode adalah sebagai berikut:

  • {p-l+#,p-q}&/@Tuples[.5{1,-1},2]mendapatkan empat vektor dari {x0,y0}dan empat sudut piksel (dengan l:={i,j}, koordinat piksel, yang ditentukan sebelumnya), dan juga vektor antara {x0,y0}dan {x1,y1}.
  • s@Det@...menemukan tanda-tanda sudut antara garis dan empat sudut (menggunakan s=Sign). Ini akan sama dengan -1, 0 atau 1.
  • Abs@Mean[...]<.6memeriksa bahwa beberapa sudut positif dan sebagian negatif. 4-tupel tanda yang memiliki properti ini semuanya memiliki sarana antara -0,5 dan 0,5 (inklusif), jadi kami membandingkan dengan 0,6 untuk menyimpan byte dengan menggunakan <alih-alih <=.

Masih ada masalah: kode ini mengasumsikan bahwa garis memanjang selamanya di kedua arah. Karena itu kita perlu memotong garis dengan mengalikannya dengan 1-Max[s[p-l]s[q-l],0](ditemukan dengan coba-coba), yang berada 1di dalam persegi panjang yang ditentukan oleh titik akhir garis, dan di 0luarnya.

Memotong garis dengan persegi panjang

Sisa kode membuat kisi-kisi piksel ini.

(Sebagai bonus, inilah upaya sebelumnya dengan metode yang sama sekali berbeda, untuk 181 byte :)

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}]&
Bukan pohon
sumber
1
Sekarang sudah selesai, saatnya makan siang! (Pukul 6:30 sore ...)
Bukan sebatang pohon
1

CJam, 122 byte

{),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*

Cobalah online

Ini pada dasarnya menggabungkan dua jawaban yang sebelumnya saya tulis untuk tantangan lain (terutama perhitungan dari fungsi kedua l).
(0, 0) secara alami adalah sudut kiri atas, bukan kiri bawah seperti contoh dalam pernyataan.

Gambaran:

{),V>{[I\]E.*A.+}/}:F;mendefinisikan fungsi F yang membantu menghasilkan semua piksel (pasangan koordinat) untuk koordinat x yang diberikan
l~]2/~@:S~'.*f*\@:A.-_:g:E;:z:Dmembaca dan memproses input, dan membuat matriks titik-titik yang
0=:B{D~I2*)*+:U(2/B/FU2/B/:V;}fIdiulang pada semua koordinat x kecuali yang terakhir, dan menghasilkan semua piksel yang sesuai
D~\:I;Fmelakukan hal yang sama untuk koordinat x terakhir
{_Wf>\S.<+:*},hanya menyimpan piksel yang seharusnya muncul di dalam gambar
{~_3$=@0tt}/menempatkan 0 dalam matriks untuk setiap piksel
N*bergabung dengan matriks dengan karakter baris baru untuk ditampilkan

aditsu
sumber