Einführung
Ein Hyperwürfel / Tesserakt ist das vierdimensionale Äquivalent eines normalen Würfels. Es wird hergestellt, indem ein Würfelnetz genommen, auf die 3. Dimension erweitert und dann - unter Verwendung der 4. Dimension - zu einem Hyperwürfel gefaltet wird. Es ist im Grunde ein Würfel, bei dem jede Seite ein Würfel ist.
Um einen Hypercube zu erstellen, benötigen Sie 16 4d-Vektoren (einen Vektor mit einer x
, einer y
, einer z
und einer w
Komponente). Diese Vektoren sind die folgenden:
A(0, 0, 0, 0); B(1, 0, 0, 0); C(1, 0, 1, 0); D(0, 0, 1, 0); E(0, 1, 0, 0); F(1, 1, 0, 0); G(1, 1, 1, 0); H(0, 1, 1, 0);
I(0, 0, 0, 1); J(1, 0, 0, 1); K(1, 0, 1, 1); L(0, 0, 1, 1); M(0, 1, 0, 1); N(1, 1, 0, 1); O(1, 1, 1, 1); P(0, 1, 1, 1);
Der Hyperwürfel hat 24 Gesichter. Die folgende Liste enthält alle (jede Gruppe markiert ein Quad):
ABFE, CDHG, BCGF, DAEH, DCBA, FEHG
IJNM, KLPO, JKON, LIMP, LKJI, PMNO
ABJI, DCKL, BCKJ, DAIL, FEMN, GHPO, FGON, EHPM, EAIM, BFNJ, CGOK, HDLP
Mit all diesen Informationen haben Sie technisch gesehen einen Hypercube im Code. Um dies zu drehen, benötigen Sie 6 verschiedene Matrizen für jede Rotationsebene, eine für die Ebenen YZ, XZ, XY, XW, YW und ZW. Nachdem Sie jede Matrix haben, müssen Sie die Eckpunkte des Würfels mit ihnen multiplizieren.
Die folgenden Bilder zeigen die Struktur jeder Matrix:
Für die Rotation auf der YZ-Ebene:
Für die Drehung auf der XZ-Ebene:
Für die Drehung auf der XY-Ebene:
Für die Drehung auf der XW-Ebene:
Für die Drehung auf der YW-Ebene:
Für die Rotation auf der ZW-Ebene:
Die Rotationen werden in dieser Reihenfolge angewendet.
Nach all dem haben Sie einen gedrehten Hyperwürfel. Jetzt musst du es zeichnen. Sie sollten eine orthogonale Projektion in Kombination mit einer perspektivischen Projektion verwenden, an die gesendet werden (x, y, z, w)
soll (2x/(2+z), 2y/(2+z))
.
Eingang
Ihre Eingabe besteht aus 6 ganzen Zahlen zwischen 0 (einschließlich) und 360 (ausschließlich). Diese repräsentieren die Rotationen in Grad auf den verschiedenen Rotationsebenen des Hyperwürfels.
Ausgabe
Ihre Ausgabe sollte ein einzelnes Bild sein, das den Hypercube enthält. Die Anzeige kann ein gerastertes Bild, ein Vektorbild oder eine ASCII-Grafik sein. Das Ausgabebild sollte mindestens 100 * 100 Pixel groß sein und der Würfel muss mindestens 50% des Bildschirms einnehmen. Jedes Standardformat für die Bildausgabe ist zulässig.
Testfälle
0 0 0 0 0 0
0 0 0 0 0 30
30 0 0 0 0 30
0 0 0 30 30 30
45 45 45 0 0 0
45 45 45 45 45 45
Öffnen Sie die Bilder in einem neuen Tab, um sie in voller Größe anzuzeigen.
Regeln
- Es gelten die Standardregeln
- Standardlücken sind verboten
- Kürzester Code in Bytes gewinnt
quelle
Antworten:
Oktave,
474433429 BytesGedreht:
Die Rotationsmatrizen verbrauchen immer noch eine Menge Bytes, aber der Eulersche Zyklus funktionierte recht gut und reduzierte die Anzahl der besuchten Vertices von
96 auf120 auf 33.Vertices werden erzeugt, indem die 4-Bit-Binärdarstellung von
[0:15]
msb als x-Koordinate und lsb als w-Koordinate betrachtet wird.Bearbeiten: Das Vormultiplizieren aller Rotationsmatrizen war ein Albtraum, weshalb ich es anfangs nicht verwendet habe, sondern sie paarweise vormultipliziert habe. Das sparte 41 Byte.
Suchen Sie nun die optimale Kombination. :) DasMultiplizieren der Matrizen mit drei war schlimmer als gar keine Vormultiplikation, daher bin ich mit dem paarweisen Ansatz zufrieden.Ausgabe:
quelle
Nachsatz
1075732683640631601590545542526514478470Verwendet mat.ps und G .
Edit: -343 Angewandte binäre Codierungserzeugung von Vektoren und Euler-Schaltung
gestohlenvon anderen Antworten entlehnt. Und angewandte binäre Token-Strings aus der G-Bibliothek.Edit: -49 Neu definiert
sin
cos
undneg
zu kürzeren Namen.Edit: -43 Definierte Kurznamen für Sequenzen
0 0
0 1
1 0
.Bearbeiten: -9
al
(d. H.aload
) Ist kürzer als(")@
. Faktor 3 Anrufe nachidi
(d. H.idiv
) Auf Kosten eines Nichtstuns1 idiv
.Edit: -30 Angewandter impliziter Definitionsblock aus G.
Edit: -10 Noch ein paar dreifach verwendete Sequenzen.
Bearbeiten: -45 Entferne Variablen
i
j
k
l
m
n
für die Winkel und definiere immer den aktuellen Winkel alst
und Funktionen von Winkeln benutze den Wert des (globalen)t
Variable. Verschieben Sie die Ausführung der Codebeschreibung der Rotationsmatrix, bis ihrt
Wert fertig ist.Bearbeiten: -3 Entfernen Sie
<16>$
dh.closepath
. Und ein Leerzeichen.Edit: -16 Array-Klammern aus Einheitsvektoren in den Rotationsmatrizen (
J
K
L
undM
) herausrechnen . Bewerben Sie sich erneutmo
fürmod
undsu
fürsub
.Bearbeiten: -12 Inline die Projekt-und-Zeichnen- Funktion und entfernen (jetzt leer) umschließendes Wörterbuch.
Edit: -36 Codiert die Schaltung (dh die Gesichter ) in einer Zeichenfolge.
Bearbeiten: -8 Definition des Vertices-Arrays entfernen
V
. Stattdessen auf Stapel lassen unddup
Arbeitskopien nach Bedarf (einmal, zuerst und wieder am Ende der Schleife). Außerdem wurden einige Operatoren von binären Token-Zeichenfolgen zurück in abgekürzte Namen übersetzt, bei denen die BTS keine Einsparungen ergab, so(I)$
ist es jetztfora
(d. H.forall
).if du
könnte sein(T8)$
, ist aberif du
eindeutig eine bessere Wahl (es ist Golf , keine Verschleierung per se). Führen Sie auch dasscale
Vorher durchtranslate
, damit übersetzte Koordinaten3
und4
anstelle von300
und sein können400
.Die
3
4
und100
in der ersten Zeile des zweiten Blocks sind Parameter, die den Mittelpunkt x, den Mittelpunkt y bzw. den Maßstab der Zeichnung auf der Seite darstellen (die Mittelpunktkoordinaten werden um skaliertscale
). (300.400) ist ungefähr das Zentrum des US-amerikanischen Briefpapiers (612.792) in PS-Einheiten.Wenn Sie Postscript grob befolgen können, sind die wichtigen bizarren Dinge der implizite Prozedurblock und die codierten Operatorzeichenfolgen. Wie aus den Kommentaren in der Arbeitsdatei hervorgeht, ist jede Zeile des ersten Blocks implizit mit A, B, C usw. benannt.
F E D
würde produzieren1 0 0 1 0 0
. Für die codierten Operatorzeichenfolgen ist alles, was ein Argument für$
#
oder@
eine Folge von Operatoraufrufen ist, mit den Bytes Operatoren aus der Systemnamentabelle, PLRM 3ed Anhang F, auszuwählen. Diese und weitere Funktionen sind für PostScript mit der G-Bibliothek verfügbar ( enthält jetzt auch die mat.ps Funktionen).Arbeitsdatei:
Ungolfed und leicht kommentiert:
Einige meiner Ausgaben spiegeln die Beispiele der Frage wider.
Denn
gs -- hc.ps 0 0 0 0 0 0
ich bekomme:gs -- hc.ps 0 0 0 0 0 30
gs -- hc.ps 30 0 0 0 0 30
gs -- hc.ps 0 0 0 30 30 30
gs -- hc.ps 45 45 45 0 0 0
gs -- hc.ps 45 45 45 45 45 45
Bonusanimation habe ich gerade mit diesem Programm gemacht. Dieses Bild entspricht der Rotationssequenz 0 30 60 0 i i , wobei i von 0 bis 360 mal 2 reicht.
quelle
C # + Unity,
1060845835 BytesC # ≈ Java
Es wird davon ausgegangen, dass diese Funktion in einem Skript enthalten ist, auf dem platziert wurde
MainCamera
.Bearbeiten:
Vielen Dank an @TuukkaX für die Vorschläge zum Speichern von 19 Bytes Gespeicherte ~ 200 Bytes mit dem Euler-Zyklus.
Golf gespielt:
Zeilenumbruch + Einrückung + Vollschale:
Ich konnte weder eine einfache Formel zum Konstruieren der Rotationsmatrizen noch der zu zeichnenden "Flächen" finden, so dass der Hardcode viele Bytes kostete.Ich habe den Eulerschen Zyklus von @beaker ausgeliehen. Außerdem sind die integrierten Unity-Funktionen äußerst ausführlich.Sie können alle Testfälle online überprüfen .
quelle
0.5f
kann auf.5f
und0.01f
auf reduziert werden.01f
. Ich denke auch, dass die Integer-Arrays mit einem Komma getrennt werden können, anstattint[]
mehrere Male zu sagen .int[,]
. Trotzdem danke.Vector4(0.5f,0.5f,0.5f,0.5f)
die reduziert werden könnteVector4(.5f,.5f,.5f,.5f)
.Javascript ES6, 584 Bytes
"Ungolfed":
Sehen Sie es in Aktion (modifiziert, um sich kontinuierlich zu drehen):
Die Funktion gibt ein HTML5-Zeichenbereichsobjekt zurück. Sie müssen es beispielsweise der Seite hinzufügen
document.body.appendChild(f(0,0,0,0,0,0))
.Derzeit werden die Rotationen nicht in der richtigen Reihenfolge angewendet. Ich arbeite an der Neuordnung, aber so wie sie ist, dreht sie einen Hypercube korrekt.
quelle
Mathematica,
453415 Byte *Verkürzt durch Verwendung der Euler-Tour und Bereinigung in einer einzigen Anweisung, ohne Funktionen in Variablen zu definieren. Dadurch wird der Code aus irgendeinem Grund langsamer. Ich vermute, Mathematica wertet die Funktionen jetzt mehrmals neu aus, da sie nicht in einer Variablen gespeichert sind.
* Ich zähle
°
und==
als einzelne Bytes, da sie in Mathematica als einzelne Zeichen dargestellt werden. Ich halte das für fair, da viele Sprachen seltsame Zeichenkodierungen verwenden.Ungolfed mit Kommentaren. Die Eingabe ist oben als fest codiert
a={30,0,0,0,0,30};
. Ich habe das nicht auf meine Punktzahl angerechnet.0 0 0 0 0 30
0 0 0 30 30 30
405 10 -14 -8 -9 205
quelle