Луч-след блестящей сферы


15

Я скачал POV-ray и отрисовал этот блестящий металлический шар в стиле 90-х:

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

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

Правила:

  • Изображение должно изображать отражающую сферу, парящую над бесконечной шахматной доской. Как сама шахматная доска, так и ее отражение в сфере должны быть показаны на изображении. Должно быть визуально ясно, что это то, что мы видим. Помимо этого, детали геометрии, цвета, свойства материала и т. Д. До вас.

  • В сцене должно быть некоторое освещение: части сферы должны быть темнее, чем другие, и визуально должно быть возможно приблизительно определить, откуда исходит свет. Кроме того, детали модели освещения зависят от вас. (Вы можете придумать свою собственную упрощенную модель освещения, если хотите.) Сфера не должна отбрасывать тень.

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

  • Вывод должен быть не менее 300х300 пикселей. Это может быть отображено на экране или записано в файл, либо в порядке.

  • Ваш код должен быть запущен менее чем за час на разумном современном компьютере. (Это щедро - POV-ray визуализирует вышеуказанную сцену практически мгновенно.)

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

  • Это , поэтому выигрывает запись с положительным результатом и самым коротким кодом (в байтах). Тем не менее, вы также можете сыграть в мета-игру, чтобы набрать наибольшее количество голосов, нарисовав красивую картинку (при этом, конечно, оставляя код коротким).

Эта задача может показаться нелепо сложной, но поскольку геометрия фиксирована, алгоритм рендеринга такой сцены с помощью трассировки лучей довольно прост. На самом деле это просто случай итерации по каждому пикселю в выходном изображении и оценки математического выражения, чтобы увидеть, каким должен быть его цвет, поэтому я надеюсь, что мы увидим несколько хороших ответов.


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

Вы говорите, что цвета до нас. Включает ли это изображения в оттенках серого?
Мартин Эндер

@ MartinBüttner Да, изображения в градациях серого в порядке.
Натаниэль

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

Это уже сделано: fabiensanglard.net/rayTracing_back_of_business_card/index.php Конечно, это можно сделать немного короче, уменьшив его до одной сферы, удалив сглаживание и т. Д.
Shujal

Ответы:


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

Начали с «настоящих» лучевых трассировочных формул (немного подправили для игры в гольф).

Рендеринг занимает около 3 с на моем мертвом старом ПК (0,7 с Pypy).


4
Красивое изображение!
Натаниэль

Вы можете сохранить несколько байт , не делая ZLIB трюк, заменив 0000с e4повсюду.
Натаниэль

@Nathaniel: Doh ... очень большая ошибка для кода гольф :-) Исправлено. Я также удалил трюк с упаковкой zlib, потому что я должен исследовать его законность (последняя версия, например, когда zip работает со стандартным 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.