Промінь простежте блискучу сферу


15

Я завантажив POV-ray і створив цю блискучу металеву сферу 90-х років:

введіть тут опис зображення

Ваше завдання - зробити те ж саме, але зробити це, застосувавши механізм візуалізації самостійно в якомога менше байтах. Вам не доведеться повторювати це точне зображення - будь-яке зображення світловідбивної сфери над нескінченною шаховою дошкою буде робити, якщо воно відповідає критеріям, наведеним нижче.

Правила:

  • На зображенні має бути відображена відбивна сфера, що нависає над нескінченною шашкою. Як зображення шашки, так і його відображення у сфері повинні бути показані на зображенні. Повинно бути наочно зрозуміло, що це те, що ми бачимо. Крім цього, вам належать деталі геометрії, кольорів, властивостей матеріалу тощо.

  • На сцені повинно бути деяке освітлення: частини сфери повинні бути темнішими, ніж інші частини, і візуально слід мати можливість приблизно розповідати, звідки йде світло. Крім того, ви залежить від деталей моделі освітлення. (Ви можете придумати власну спрощену модель освітлення, якщо вам подобається.) Куля не повинна кидати тінь.

  • Вищеописані два критерії - чи справді це виглядає як блискуча сфера над шаховою дошкою, освітленою джерелом світла - буде оцінюватися громадою за допомогою голосування. Тому відповідь повинна мати позитивний бал, щоб мати право на перемогу.

  • Вихід повинен бути не менше 300х300 пікселів. Його можна відобразити на екрані або записати у файл, або це добре.

  • Ваш код повинен працювати менш ніж за годину на розумному сучасному комп’ютері. (Це щедро - POV-промінь надає вищезазначену сцену практично миттєво.)

  • Жодна вбудована функція відстеження променів не може використовуватися - ви повинні реалізувати візуалізатор самостійно.

  • Це , тому позиція з позитивним балом із найкоротшим кодом (у байтах) виграє. Однак ви також можете грати в мета-гру, щоб отримати найбільшу кількість голосів, намалювавши гарне зображення (при цьому, звичайно, не дотримуючись код).

Цей виклик може здатися смішним важким, але оскільки геометрія закріплена, алгоритм відображення такої сцени шляхом відстеження променів є досить простим. Це насправді лише випадок ітерації над кожним пікселем у вихідному зображенні та оцінки математичного виразу, щоб побачити, яким він повинен бути колір, тому я оптимістичний, що ми побачимо кілька хороших відповідей.


Мені особисто не подобається вимога до освітлення. Я думаю, що це додає багато зайвих складностей, за дуже малий прибуток. Просто моя думка, хоча.
стокастик

Ви кажете, що кольори залежать від нас. Це включає зображення сірого масштабу?
Мартін Ендер

@ MartinBüttner так, зображення із сірим кольором - це добре.
Натаніель

@stokastic я сподіваюся, що це буде джерелом творчості, оскільки люди придумують докорінно спрощені, але майже переконливі моделі освітлення, які можна вказати в невеликій кількості коду. Я додав до запитання, що спрощені моделі освітлення в порядку.
Натаніел

Це вже зроблено: fabiensanglard.net/rayTracing_back_of_business_card/index.php Звичайно, це можна зробити трохи коротше, зменшивши його до однієї сфери, видаливши
антиалізинг

Відповіді:


28

Python 2, 484 468 467 байт

введіть тут опис зображення

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

Примітка: після if I>0:того, як з'явиться новий рядок, за яким слід одна таблиця вкладки, перш ніж t=...

Запуск програми створить зображення розміром 800x600 під назвою s.pgm

Почав із "справжніх" формул прослідковування променів (трохи підкоригував для гольфу).

На моєму старому ПК (0,7s з pypy) візуалізація займає близько 3 секунд.


4
Гарне зображення!
Натаніел

Ви можете зберегти кілька байтів, не виконуючи трюк zlib, замінивши 0000на на e4весь.
Натаніел

@Nathaniel: До ... дуже велика помилка коду для гольфу :-) Виправлено. Я також видалив трюк упаковки zlib, тому що я повинен досліджувати його законність (остання версія, наприклад, коли zipped працює зі стандартним python, але не працює з pypy, і це дуже дивно).
6502 р.

Інший код гольф трюк, ви можете замінити a if b else cз (c,a)[b]тих пір , поки ви не покладатися на коротке замикання , щоб уникнути , наприклад , розподіл на нуль помилок. Також if A:code;return B\nelse:return Cви можете замінити на code;return(C,B)[A].
Клавдіу

@Claudiu: Дякую за пропозицію. Мені довелося трохи змінити параметри, щоб уникнути поділу на нуль. Я також використав одну петлю над зображенням, і це значно заощадило.
6502
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.