Ray-jejak bola mengkilap

15

Saya mengunduh POV-ray dan menampilkan gaya 90s metal shiny ini:

masukkan deskripsi gambar di sini

Tugas Anda adalah melakukan hal yang sama, tetapi melakukannya dengan menerapkan mesin rendering sendiri dalam beberapa byte mungkin. Anda tidak harus mereplikasi gambar yang tepat ini - gambar apa pun dari bola reflektif di atas kotak-kotak yang tak terbatas akan dilakukan, asalkan memenuhi kriteria di bawah ini.

Aturan:

  • Gambar harus menggambarkan bola reflektif yang melayang di atas kotak-kotak tak terbatas. Baik kotak-kotak itu sendiri dan pantulannya di bola harus ditunjukkan pada gambar. Harus jelas secara visual bahwa inilah yang kami lihat. Di luar ini, detail geometri, warna, sifat material dll. Terserah Anda.

  • Harus ada beberapa pencahayaan dalam adegan: bagian-bagian dari bola harus lebih gelap daripada bagian-bagian lain, dan secara visual itu mungkin untuk mengetahui secara kasar dari mana cahaya itu berasal. Selain itu, detail model pencahayaan terserah Anda. (Anda dapat menemukan model pencahayaan Anda sendiri yang disederhanakan jika Anda mau.) Bola tidak harus membuat bayangan.

  • Dua kriteria di atas - apakah itu benar-benar terlihat seperti bola mengkilap di atas kotak-kotak yang diterangi oleh sumber cahaya - akan dinilai oleh masyarakat menggunakan voting. Karena itu, jawaban harus memiliki skor positif agar memenuhi syarat untuk menang.

  • Output harus minimal 300x300 piksel. Itu dapat ditampilkan di layar atau ditulis ke file, baik-baik saja.

  • Kode Anda harus berjalan dalam waktu kurang dari satu jam di komputer modern yang masuk akal. (Ini murah hati - POV-ray membuat adegan di atas praktis instan.)

  • Tidak ada fungsi penelusuran sinar bawaan yang dapat digunakan - Anda harus mengimplementasikan renderer sendiri.

  • Ini adalah , sehingga entri penilaian positif dengan kode terpendek (dalam byte) menang. Namun, Anda juga dipersilakan untuk memainkan meta-game untuk mendapatkan suara terbanyak dengan menggambar gambar yang cantik (sambil tetap menjaga kode singkat).

Tantangan ini mungkin tampak sangat sulit, tetapi karena geometri sudah diperbaiki, algoritma untuk rendering adegan seperti itu dengan ray tracing cukup mudah. Ini benar-benar hanya kasus iterasi setiap piksel dalam gambar output dan mengevaluasi ekspresi matematika untuk melihat warna apa yang seharusnya, jadi saya optimis bahwa kita akan melihat beberapa jawaban yang baik.

Nathaniel
sumber
Saya pribadi tidak menyukai persyaratan pencahayaan. Saya pikir itu menambah banyak kompleksitas ekstra, untuk keuntungan yang sangat sedikit. Hanya pendapat saya saja.
stokastic
Anda mengatakan warna terserah kita. Apakah itu termasuk gambar skala abu-abu?
Martin Ender
@ MartinBüttner ya, gambar skala abu-abu baik-baik saja.
Nathaniel
@stokastic harapan saya adalah bahwa itu akan menjadi sumber kreativitas, karena orang-orang datang dengan model pencahayaan yang disederhanakan secara radikal tetapi hanya tentang meyakinkan yang dapat ditentukan dalam sejumlah kecil kode. Saya telah menambahkan catatan dalam pertanyaan bahwa model pencahayaan yang disederhanakan OK.
Nathaniel
Itu sudah dilakukan: fabiensanglard.net/rayTracing_back_of_business_card/index.php Tentu saja ini bisa dibuat sedikit lebih pendek dengan menguranginya menjadi satu bidang, menghilangkan antialiasing dll.
Shujal

Jawaban:

28

Python 2, 484 468 467 byte

masukkan deskripsi gambar di sini

i=int;u=249.3
def Q(A,B):
 a=A*A+B*B+9e4;b=B*u+36e4;I=b*b-a*128e4
 if I>0:
    t=(-b+I**.5)/(5e2*a);F,G,H=A*t,B*t,u*t;J,K,M=F,G+.6,H+2.4;L=a**-.5;k=2*(A*J+B*K+u*M)*L;C,D,E=A*L-k*J,B*L-k*K,u*L-k*M;L=(C*C+D*D+E*E)**-.5;t=(-4e2-G)/D;return(D*D*L*L*u,((i(F+t*C)/200+i(H+t*E)/200)&1)*(u*D*L))[D>0]
 else:return(u*B*B/a,((i(-2e2/B*A)/200+i(-6e4/B)/100)&1)*u*B/a**.5)[B>0]
open("s.pgm","wb").write("P5 800 600 255 "+"".join(chr(i(Q(j%800-4e2,j/800-u)))for j in range(480000)))

Catatan: setelah if I>0:ada baris baru diikuti oleh satu tab char sebelum t=...

Menjalankan program akan membuat gambar 800x600 bernama s.pgm

Dimulai dari formula pelacak sinar "nyata" (sedikit dimodifikasi untuk bermain golf).

Rendering membutuhkan sekitar 3 detik pada PC lama saya yang sudah mati (0,7 detik dengan pypy).

6502
sumber
4
Gambar yang indah!
Nathaniel
Anda dapat menyimpan beberapa byte tanpa melakukan trik zlib dengan mengganti 0000dengan e4seluruh.
Nathaniel
@Nathaniel: Doh ... kesalahan sangat besar untuk kode golf :-) Tetap. Saya juga telah menghapus trik pengemasan zlib karena saya telah menyelidiki legalitasnya (versi terbaru misalnya ketika zip bekerja dengan python standar tetapi tidak bekerja dengan pypy, dan itu sangat aneh).
6502
Trik golf kode lain, Anda dapat mengganti a if b else cdengan (c,a)[b]selama Anda tidak mengandalkan korsleting untuk menghindari mis pembagian dengan nol kesalahan. if A:code;return B\nelse:return CAnda juga dapat menggantinya dengan code;return(C,B)[A].
Claudiu
@Claudiu: Terima kasih atas sarannya. Saya harus mengubah parameter sedikit untuk menghindari pembagian dengan nol. Saya juga menggunakan satu loop di atas gambar dan itu banyak disimpan.
6502