Verfolgen Sie eine glänzende Kugel

15

Ich habe POV-ray heruntergeladen und diesen glänzenden Metallkugel-90er-Stil gerendert:

Bildbeschreibung hier eingeben

Ihre Aufgabe ist es, dasselbe zu tun, indem Sie die Rendering-Engine selbst in so wenigen Bytes wie möglich implementieren. Sie müssen dieses genaue Bild nicht replizieren - jedes Bild einer reflektierenden Kugel über einem unendlichen Schachbrett reicht aus, solange es die folgenden Kriterien erfüllt.

Regeln:

  • Das Bild muss eine reflektierende Kugel zeigen, die über einem unendlichen Schachbrett schwebt. Sowohl das Schachbrett selbst als auch seine Reflexion in der Kugel müssen im Bild gezeigt werden. Es muss visuell klar sein, dass dies das ist, was wir sehen. Darüber hinaus liegen die Angaben zu Geometrie, Farben, Materialeigenschaften usw. bei Ihnen.

  • Es muss etwas Licht in der Szene sein: Teile der Kugel sollten dunkler sein als andere Teile, und visuell sollte es möglich sein, ungefähr zu sagen, woher das Licht kommt. Darüber hinaus liegen die Details des Beleuchtungsmodells bei Ihnen. (Sie können Ihr eigenes vereinfachtes Beleuchtungsmodell erfinden, wenn Sie möchten.) Die Kugel muss keinen Schatten werfen.

  • Die beiden oben genannten Kriterien - ob es wirklich wie eine glänzende Kugel über einem Schachbrett aussieht, das von einer Lichtquelle beleuchtet wird - werden von der Community anhand von Abstimmungen beurteilt. Daher muss eine Antwort eine positive Punktzahl haben, um gewinnberechtigt zu sein.

  • Die Ausgabe muss mindestens 300x300 Pixel betragen. Es kann auf dem Bildschirm angezeigt oder in eine Datei geschrieben werden.

  • Ihr Code sollte auf einem vernünftigen modernen Computer in weniger als einer Stunde ausgeführt werden. (Dies ist großzügig - POV-ray rendert die obige Szene praktisch sofort.)

  • Es darf keine integrierte Raytracing-Funktion verwendet werden - Sie müssen den Renderer selbst implementieren.

  • Dies ist , daher gewinnt der positiv bewertete Eintrag mit dem kürzesten Code (in Bytes). Sie können jedoch auch gerne das Metaspiel spielen, bei dem Sie die meisten Stimmen erhalten, indem Sie ein hübsches Bild zeichnen (wobei Sie den Code natürlich kurz halten).

Diese Herausforderung mag lächerlich schwierig erscheinen, aber da die Geometrie feststeht, ist der Algorithmus zum Rendern einer solchen Szene durch Raytracing ziemlich einfach. Es geht wirklich nur darum, jedes Pixel im Ausgabebild zu durchlaufen und einen mathematischen Ausdruck auszuwerten, um festzustellen, welche Farbe es haben sollte. Ich bin also optimistisch, dass wir einige gute Antworten sehen werden.

Nathaniel
quelle
Ich persönlich mag den Beleuchtungsbedarf nicht. Ich denke, es erhöht die Komplexität erheblich, und das bei sehr geringem Gewinn. Nur meine Meinung.
Stokastic
Sie sagen, Farben liegen bei uns. Enthält das Graustufenbilder?
Martin Ender
@ MartinBüttner ja, Graustufenbilder sind in Ordnung.
Nathaniel
@stokastic Ich hoffe, dass dies eine Quelle der Kreativität sein wird, da die Leute radikal vereinfachte, aber nur überzeugende Beleuchtungsmodelle entwickeln, die in einer kleinen Menge Code angegeben werden können. Ich habe einen Hinweis in die Frage eingefügt, dass vereinfachte Beleuchtungsmodelle in Ordnung sind.
Nathaniel
Es wurde bereits getan: fabiensanglard.net/rayTracing_back_of_business_card/index.php Natürlich kann dies etwas verkürzt werden, indem es auf eine Kugel reduziert wird, Antialiasing usw. entfernt wird.
Shujal

Antworten:

28

Python 2, 484 468 467 Bytes

Bildbeschreibung hier eingeben

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

Hinweis: Nach if I>0:einem Zeilenumbruch folgt ein einzelnes Tabulatorzeichen vor t=...

Wenn Sie das Programm ausführen, wird ein 800x600-Image mit dem Namen "s.pgm" erstellt

Ausgehend von einer "echten" Raytracer-Formel (zum Golfen etwas überarbeitet).

Auf meinem toten alten PC dauert das Rendern ca. 3s (0,7s mit pypy).

6502
quelle
4
Schönes Bild!
Nathaniel
Sie können durch das Ersetzen ohne dabei den zlib Trick ein paar Bytes speichern 0000mit e4ganz.
Nathaniel
@ Nathaniel: Doh ... sehr großer Fehler bei einem Codegolf :-) behoben. Ich habe auch den Zlib-Pack-Trick entfernt, weil ich seine Rechtmäßigkeit untersuchen muss (die neueste Version funktioniert beispielsweise mit Standard-Python, funktioniert aber nicht mit Pypy, und das ist sehr seltsam).
6502
Ein weiterer Code Golf Trick, können Sie ersetzen a if b else cmit (c,a)[b]so lange , wie Sie verlassen sich auf nicht Kurzschließen zB Division durch Null - Fehler zu vermeiden. Auch können if A:code;return B\nelse:return CSie mit ersetzen code;return(C,B)[A].
Claudiu
@Claudiu: Danke für den Vorschlag. Ich musste die Parameter etwas ändern, um eine Division durch Null zu vermeiden. Ich habe auch eine einzelne Schleife über dem Bild verwendet und das hat viel gespart.
6502