Ray traccia una sfera lucente


15

Ho scaricato POV-ray e ho reso questo lucido sfera di metallo stile anni '90:

inserisci qui la descrizione dell'immagine

Il tuo compito è fare la stessa cosa, ma farlo implementando tu stesso il motore di rendering nel minor numero di byte possibile. Non è necessario replicare questa esatta immagine - qualsiasi immagine di una sfera riflettente sopra una scacchiera infinita lo farà, purché soddisfi i criteri di seguito.

Regole:

  • L'immagine deve rappresentare una sfera riflettente sospesa sopra una scacchiera infinita. Sia la scacchiera stessa che il suo riflesso nella sfera devono essere mostrati nell'immagine. Deve essere visivamente chiaro che questo è ciò che stiamo vedendo. Oltre a ciò, i dettagli della geometria, i colori, le proprietà del materiale ecc.

  • Ci deve essere un po 'di luce nella scena: parti della sfera dovrebbero essere più scure di altre parti e visivamente dovrebbe essere possibile dire approssimativamente da dove proviene la luce. Oltre a ciò, i dettagli del modello di illuminazione dipendono da te. (Se lo desideri, puoi inventare il tuo modello di illuminazione semplificato.) La sfera non deve proiettare un'ombra.

  • I due criteri di cui sopra - indipendentemente dal fatto che sembri davvero una sfera lucente sopra una scacchiera illuminata da una fonte di luce - saranno valutati dalla comunità usando il voto. Pertanto, una risposta deve avere un punteggio positivo per poter vincere.

  • L'output deve essere di almeno 300x300 pixel. Può essere visualizzato sullo schermo o scritto in un file, o va bene.

  • Il codice dovrebbe essere eseguito in meno di un'ora su un computer moderno e ragionevole. (Questo è generoso - POV-ray rende la scena sopra praticamente istantaneamente.)

  • Non è possibile utilizzare alcuna funzionalità di ray tracing integrata: è necessario implementare il renderer da soli.

  • Si tratta di , quindi vince la voce con punteggio positivo con il codice più breve (in byte). Tuttavia, sei anche invitato a giocare al meta-gioco per ottenere il maggior numero di voti disegnando una bella immagine (mantenendo ovviamente il codice breve).

Questa sfida potrebbe sembrare ridicolmente difficile, ma dal momento che la geometria è fissa, l'algoritmo per il rendering di una tale scena mediante ray tracing è piuttosto semplice. È davvero solo un caso di iterare su ogni pixel nell'immagine di output e valutare un'espressione matematica per vedere di che colore dovrebbe essere, quindi sono ottimista sul fatto che vedremo delle buone risposte.


Personalmente non mi piace il requisito di illuminazione. Penso che aggiunga molta ulteriore complessità, per un guadagno molto piccolo. Solo la mia opinione, però.
stokastic

Dici che i colori dipendono da noi. Questo include immagini in scala di grigi?
Martin Ender,

@ MartinBüttner sì, le immagini in scala di grigi vanno bene.
Nathaniel,

@stokastic la mia speranza è che sia una fonte di creatività, dato che le persone escono con modelli di illuminazione radicalmente semplificati ma convincenti che possono essere specificati in una piccola quantità di codice. Ho aggiunto una nota alla domanda che i modelli di illuminazione semplificati sono OK.
Nathaniel,

È già stato fatto: fabiensanglard.net/rayTracing_back_of_business_card/index.php Naturalmente questo può essere reso un po 'più breve riducendolo a una sfera, rimuovendo l'antialiasing ecc.
Shujal

Risposte:


28

Python 2, 484 468 467 byte

inserisci qui la descrizione dell'immagine

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

Nota: dopo che if I>0:c'è una nuova riga seguita da un singolo carattere tab prima di t=...

L'esecuzione del programma creerà un'immagine 800x600 denominata s.pgm

Iniziato da una "vera" formula ray tracciante (ottimizzata un po 'per il golf).

Il rendering richiede circa 3 secondi sul mio vecchio PC morto (0,7 secondi con pypy).


4
Bella immagine!
Nathaniel,

Puoi salvare alcuni byte senza fare il trucco zlib sostituendolo 0000con e4ovunque.
Nathaniel,

@ Nathaniel: Doh ... grosso errore per un codice golf :-) Risolto. Ho anche rimosso il trucco dell'imballaggio zlib perché devo indagare sulla sua legalità (l'ultima versione, ad esempio quando zippato funziona con Python standard ma non funziona con Pypy, ed è molto strano).
6502

Un altro trucco da golf di codice, che puoi sostituire a if b else ccon il (c,a)[b]tempo in cui non fai affidamento sul corto circuito per evitare, ad esempio, la divisione per zero errori. Inoltre if A:code;return B\nelse:return Cè possibile sostituire con code;return(C,B)[A].
Claudiu,

@Claudiu: Grazie per il suggerimento. Ho dovuto modificare un po 'i parametri per evitare una divisione per zero. Ho anche usato un singolo loop sull'immagine e questo mi ha salvato molto.
6502
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.