Jeder kennt das Problem: dreidimensionale Arrays (
(muss jetzt nichts heißen, da das Problem sicher mehr als nur mich betroffen haben und sich entsprechend einige damit befassten)
Aber ich habe es trotzdem geschafft!
Das Array ist zwar noch nicht IEnumerable-kompatibel, aber das wird, hoffentlich, noch kommen.
Derzeit ist es noch eine ganz normale Klasse, mit der ihr schön arbeiten könnt.
Die Klasse habe ich ursprünglich in C# geschrieben, wird hier somit "nur" übersetzt werden, wodurch u.U. Fehler auftreten können.
Einige Elemente habe ich so gekennzeichnet, dass ihr die gerne löschen könnt, da diese für das Array ansich nicht wichtig sind. Dies soll zudem eine Alternative zum
Wobei dies Elemente mit
Nun, was benötigen wir ersteinmal für so ein Anliegen? Natürlich das Array selbst.
Da ich sagte, dass dies ein serialisierbares Array wird, könnt ihr euch natürlich vorstellen, dass dies ein eindimensionales Array sein wird, also definieren wir das als:
Jetzt ist natürlich die Frage: woher den Index eines Elements nehmen?
Stellen wir uns ein eindimensionales Array mit der Länge 5 vor. Dann sind die Indexe so:
Also ist der Index = X, wenn X das angesprochene Element ist
bei einem zwei dimensionalen Array sähe das so aus:
Hier gilt dann:
da 3 * 1 + 2 = 5.
Für das drei dimensionale Array möchte ich die Beziehungen nicht angeben, da dies doch zu lang wäre.
Dort gilt:
Warum X als erstes angegen wird: die Indexe sollen mit Z um eins steigen, mit Y um die Länge und mit X um Länge².
Also haben wir auch schon die nächste Funktion für die Klasse:
Hier ist nur noch ein Problem: was ist
Wie vorher schon angesprochen, gibt es eine Konstante
Daher muss eine Eigenschaft
Jetzt kann das
Da wir jetzt die zwei nötigen Dinge für die Initialisierung haben, sollten wir uns an den Konstruktor machen.
Hier müssen das Array und die Dimensionen definiert werden:
Theoretisch ist die Klasse damit fertig, nur leider gibt es dort ein Problem: was ist mit dem Zugriff auf das Array?
Dafür gibt es die
Dort kann der Array-Zugriff einfach gestaltet werden und ebenfalls zurückgegeben werden.
Damit ist die Klasse für die grobe Nutzung fertig!
Wenn ihr noch erweiterte Funktionalität haben wollt, könnt ihr noch weiterlesen, ansonsten könnt ihr das nun so nutzen. Ich werde beides in VB und C# mit der erweiterten Funktionalität anhängen, sodass ihr den Code so übernehmen könnt.
Da wir nur wissen, welcher Index zu welcher Position gehört und nicht wissen, welche Position zu welchem Index gehört, müssen wir uns einiger Mathematik bedienen. Das ist auch der eigentliche Sinn hinter der erweiterten Funktionalität, die ich bisher implementiert habe.
Wir definieren ersteinmal zwei Variable
Machen wir uns erst einmal eine Eigenschaft um eine Zahl zu bekommen.
Es wird also die komplette Zahl von Anfang an um ein Bit verschoben, sodass die größte Zahl, die wir bekommen,
Diese Property beschreibt das Bit-Muster, mit dem wir am Ende den Index in eine Koordinate umrechnen.
Die nächste Property wird die Anzahl der zu verschiebenden Bits darstellen.
Hier wird aus dem Flag berechnet, wie viele Schritte getan werden müssen, um von der einen Koordinate zur nächsten zu gelangen. Hier ist allerdings ein Fehler enthalten, sodass nur Zahlen der Basis 2
Sollte jemand wissen, wie dies korrigiert werden kann, bitte melden!
Nach dem die zwei Properties eingerichtet wurden, müssen die Werte korrekt eingesetzt werden:
VB
Es werden die Koordinaten also zur richtigen Position gerückt und anschließend mit dem Vergleichsmuster verglichen. Am Ende kommt dann die korrekte Koordinate heraus.
Ihr solltet allerdings nur Dimensionen mit der Basis 2 nutzen, da sonst Probleme beim Resolven entstehen (es werden falsche Koordinaten zurückgegeben).
Ich übernehme keine Garantie, dass der VB-Code korrekt ist, da ich diesen nur durch einen Konverter gejagt habe.
T(, ,)
bzw. T[, ,]
) sind nicht serialisierbar. Das Problem habe ich seit heute gelöst!(muss jetzt nichts heißen, da das Problem sicher mehr als nur mich betroffen haben und sich entsprechend einige damit befassten)
Aber ich habe es trotzdem geschafft!
Das Array ist zwar noch nicht IEnumerable-kompatibel, aber das wird, hoffentlich, noch kommen.
Derzeit ist es noch eine ganz normale Klasse, mit der ihr schön arbeiten könnt.
Die Klasse habe ich ursprünglich in C# geschrieben, wird hier somit "nur" übersetzt werden, wodurch u.U. Fehler auftreten können.
Einige Elemente habe ich so gekennzeichnet, dass ihr die gerne löschen könnt, da diese für das Array ansich nicht wichtig sind. Dies soll zudem eine Alternative zum
Dictionary(Of Vector3, T)
bzw. Dictionary(Of Point3, T)
sein.Wobei dies Elemente mit
XYZ
-Koordinaten sind.Nun, was benötigen wir ersteinmal für so ein Anliegen? Natürlich das Array selbst.
Da ich sagte, dass dies ein serialisierbares Array wird, könnt ihr euch natürlich vorstellen, dass dies ein eindimensionales Array sein wird, also definieren wir das als:
Jetzt ist natürlich die Frage: woher den Index eines Elements nehmen?
Stellen wir uns ein eindimensionales Array mit der Länge 5 vor. Dann sind die Indexe so:
Also ist der Index = X, wenn X das angesprochene Element ist
bei einem zwei dimensionalen Array sähe das so aus:
Hier gilt dann:
Index = Länge * X + Y
da 3 * 1 + 2 = 5.
Für das drei dimensionale Array möchte ich die Beziehungen nicht angeben, da dies doch zu lang wäre.
Dort gilt:
Index = ((X * Länge) + Y) * Länge + Z
.Warum X als erstes angegen wird: die Indexe sollen mit Z um eins steigen, mit Y um die Länge und mit X um Länge².
Also haben wir auch schon die nächste Funktion für die Klasse:
Index(x, y, z)
.Hier ist nur noch ein Problem: was ist
k
?Wie vorher schon angesprochen, gibt es eine Konstante
Länge
, die angegeben werden muss.Daher muss eine Eigenschaft
Dimensions
erzeugt werden, die dann die Eigenschaften enthält.Jetzt kann das
k
auch durch Dimensions
ersetzt werden.Da wir jetzt die zwei nötigen Dinge für die Initialisierung haben, sollten wir uns an den Konstruktor machen.
Hier müssen das Array und die Dimensionen definiert werden:
Theoretisch ist die Klasse damit fertig, nur leider gibt es dort ein Problem: was ist mit dem Zugriff auf das Array?
Dafür gibt es die
Default Property
bzw. this
.Dort kann der Array-Zugriff einfach gestaltet werden und ebenfalls zurückgegeben werden.
Damit ist die Klasse für die grobe Nutzung fertig!
Wenn ihr noch erweiterte Funktionalität haben wollt, könnt ihr noch weiterlesen, ansonsten könnt ihr das nun so nutzen. Ich werde beides in VB und C# mit der erweiterten Funktionalität anhängen, sodass ihr den Code so übernehmen könnt.
Da wir nur wissen, welcher Index zu welcher Position gehört und nicht wissen, welche Position zu welchem Index gehört, müssen wir uns einiger Mathematik bedienen. Das ist auch der eigentliche Sinn hinter der erweiterten Funktionalität, die ich bisher implementiert habe.
Wir definieren ersteinmal zwei Variable
flag = -1
und move = -1
, diese werden später wichtig sein. Diese sollten auf Private
sein, damit nicht jeder auf diese zugriff hat.Machen wir uns erst einmal eine Eigenschaft um eine Zahl zu bekommen.
Es wird also die komplette Zahl von Anfang an um ein Bit verschoben, sodass die größte Zahl, die wir bekommen,
Dimensions - 1
ist.Diese Property beschreibt das Bit-Muster, mit dem wir am Ende den Index in eine Koordinate umrechnen.
Die nächste Property wird die Anzahl der zu verschiebenden Bits darstellen.
Hier wird aus dem Flag berechnet, wie viele Schritte getan werden müssen, um von der einen Koordinate zur nächsten zu gelangen. Hier ist allerdings ein Fehler enthalten, sodass nur Zahlen der Basis 2
2^n
korrekt behandelt werden.Sollte jemand wissen, wie dies korrigiert werden kann, bitte melden!
Nach dem die zwei Properties eingerichtet wurden, müssen die Werte korrekt eingesetzt werden:
VB.NET-Quellcode
- Public Function Resolve(index As Integer) As Point3
- Dim logicFlag As Integer = Flag
- Dim bitMove As Integer = Move
- Dim x As Integer = (index >> (bitMove * 2)) And logicFlag
- Dim y As Integer = (index >> bitMove) And logicFlag
- Dim z As Integer = index And logicFlag
- Return New Point3(x, y, z)
- End Function
Es werden die Koordinaten also zur richtigen Position gerückt und anschließend mit dem Vergleichsmuster verglichen. Am Ende kommt dann die korrekte Koordinate heraus.
Ihr solltet allerdings nur Dimensionen mit der Basis 2 nutzen, da sonst Probleme beim Resolven entstehen (es werden falsche Koordinaten zurückgegeben).
Ich übernehme keine Garantie, dass der VB-Code korrekt ist, da ich diesen nur durch einen Konverter gejagt habe.