3D-Array um 90° drehen
-
Bevor ich das Problem schildere, sollte ich lieber genauer erklären was ich meine und machen will, auch wenn mir das schwer fällt und ich es selbst nicht genau weiß.
Es gibt ein 2D-Array als Bild (Höheninformationen). Dieses habe ich auf ein 1D-Array gemapped und komme damit auch ganz gut klar.
Ich habe 2 verschachtelte for-schleifen, außen i als Spaltenzahl was bis zur Breite des Arrays läuft und innen j als Zeilenzahl die bis zur Höhe geht.
Zugriff also mit array[i][j] also spaltenweise, gemapped so:
array[i+j*width].Nun gibt es noch ein zweites ein 3D-Array (im Moment noch statisch angelegt) welches auch ein Bild repräsentieren soll, das aus den Höheninfos noch in der selben verschachtelten for-schleife berechnet werden soll, in der ich auch aus dem 1D/2D-Höhenarray wie oben beschrieben lese.
Es ist dreidimensional, weil ich 4 Farbkomponenten pro Pixel habe.
Die 3. Komponente ist also = 4.Soweit so gut, speichere ich die berechneten Werte in das Array mit
array[i][j][0] = ... array[i][j][1] = ... array[i][j][2] = ... array[i][j][3] = ...
klappt es auch schon _fast_.
Dieses Array wird nämlich dann einer externen Funktion übergeben, auf die ich keinen Einfluss habe. Leider ist das Bild dann um 90° gedreht, die Funktion erwartet also eine um 90° gedrehte Anordnung (ob links oder rechts weiß ich nicht, ist aber auch erstmal egal)Nun geht es darum, die Werte so in das 3D-Array zu speichern, also dass die Indices zum Zugriff auf dieses Array zu bestimmen.
Erst dachte ich an ein einfaches Vertauschen von j und i. (und natürlich hat das 3D-Array dann auch als erste Dimension height statt width elemente und umgekehrt)
Klappt aber nicht, weil das ja ne Spiegelung wäre.
Nun bin ich der Meinung dass
[height-j-1][i] ODER für eine Drehung in die andere Richtung [j][width-i-1] gehen sollte. Ich glaube auch das stimmt. Aber halt nur für 2D-Arrays.
Denn das Bild was ich damit erhalte ist absolut falsch und erinnert an den Moree-Effekt. (eigentlich sollte es sinusförmig hell und dunkel werden)
Liegt sicher daran, dass die Funktion die 4 Farbkomponenten im Stück am Speicher erwartet, genau das aber nicht mehr gewährleistet ist.
Was muss ich also tun?
Übrigens ist auch ein
[4-Anzahl der Farbkomponenten][height][width]
statt
[height][width][4-Anzahl der Farbkomponenten]mit entsprechendem Zugriff nicht die Richtige Lösung.
Bin etwas verwirrt, und befürchte dass ich mich trotz langem Beitrag nicht ganz klar ausgedrückt habe.
Hoffe aber auf schnelle Hilfe weil ich jetzt schon ne knappe Woche daran hänge...
Danke!
splat
-
Hätte ich lieber im C oder C++ - Forum posten sollen?
-
ehrlich gesagt versteh ich garnicht was du machen willst, aber wenns nur um ne drehung einer matrix geht (topicname ;)), greif doch einfach zu zettel und stift oder poste im mathematikforum..
-
Danke erstmal, ich hatte sowas schon befürchtet
Ne, nix mathematisches, das hat einzig etwas mit Speicheranordnung zu tun.
Und darüber weiß ich nicht viel.
Die Frage ist:
**
Wie greife ich richtig auf das Array (3d) zu, um das Bild korrekt
und gedreht um 90° reinzuspeichern?
**
Die nötigen Detailinformationen stehen oben, eventuell fehlen sogar ein paar (wie genau das Bild im Speicher liegen muss), hier müsste eben geraten oder probiert werden (aber eigentlich sollten diese Infos einem aufmerksamen und wissenden (ich also nicht) Leser aus der genannten funktionierenden Lösung hervorgehen können, bei der eben um 90° falsch gedreht ist)
Mal etwas Code.
So funzt es, aber das Bild ist um 90° verdreht:unsigned char lightmap[width][height][4]; for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { //... lightmap[i][j][0] = ...; lightmap[i][j][1] = ...; lightmap[i][j][2] = ...; lightmap[i][j][3] = ...; } }
Also dachte ich es ungefähr so zu lösen:
unsigned char lightmap[4][height][width]; for (int i = 0; i < width; ++i) { for (int j = 0; j < height; ++j) { //... lightmap[0][j-1-height][i] = ...; // oder lightmap[j][i-width-1] um in andere Richtung zu drehen lightmap[1][j-1-height][i] = ...; lightmap[2][j-1-height][i] = ...; lightmap[3][j-1-height][i] = ...; } }
Hierbei kommt aber leider ein falsches Bild heraus.
(Bild besitzt 3 getrennte Streifen)
lightmap[j-1-height][i][0] klappt auch nicht (also Farbkomponente weiterhin als 3. Dim.), das sieht dann nach Moiré-Effekt aus (wie oben geschrieben spielt dabei sicher eine Rolle dass das Bild eigentlich hell-dunkel-hell-dunkel mit weichen Übergängen (sinus) ist).
Eigentlich ist letzteres fast das gleiche Bild wie auch durch eine simple Spiegelung per
lightmap[j][i][0] erreicht würde.
-
hm imho müsste eigentlich lightmap[j][width-i-1][0..3] richtig sein..
-
Danke für deine Bemühungen.
Leider klappt es so nicht. Ich habe mal testweise auf Farben verzichtet und die 3. Dimension gestrichen. Erstaunlicherweise gehts dann immernoch nicht. Und ich dachte, der Fehler liegt dort.
Egal ob [j][i], [height-j-1][i], [j][width-i-1] oder [height-j-1][width-i-1] benutzt wird, es kommt immer genau das gleiche vollkommen falsche Moiré-Bild raus, ganz anders als das Bild von [i][j].Was mich auch grade wundert:
ein [i/2][j] scaled das richtige Bild in die eine Richtung (natürlich halb so breit), ein [i][j/2] scaled aber nicht in die andere Richtung, sondern lässt jeden 2. Pixelstreifen (der selben Ausrichtung wie auch [i*a][j] scaled) verschwinden.
-
hat sich erledigt, der Fehler lag woanders.