Array transfomieren

Hallo,
Ich verzweifle seit 3 Tagen an der Transformation eines Arrays. Hier ist mein bisheriger Sketch:

int amount_in_x = 6; //variabel
int amount_in_y = 3; //variabel

void setup() {
  Serial.begin(9600);
  Serial.println();
  float counter = 1.0001;
  float measure_array[amount_in_x][amount_in_y];
  float transform_array[amount_in_x][amount_in_y];

  Serial.println("===ORIGINAL ARRAY===");
  for (int x = 0; x < amount_in_x; x++) {
    for (int y = 0; y < amount_in_y; y++) {

      measure_array[x][y] = counter;
      Serial.print(measure_array[x][y], 4);
      Serial.print(" ");
      counter += 0.0001;
    }
    Serial.println();
  }

  //funktioniert (noch) nicht
  Serial.println("===TRANSFORM ARRAY (NOT WORKING)===");
  // MIRROR EVEN ROWS
  for (int x = 0; x < amount_in_x; x++) {
    for (int y = 0; y < amount_in_y; y++) {
      if (x % 2 == 0) { // even)
        transform_array[x][y] = measure_array[x][y];
      } else {
        transform_array[x][y] = measure_array[x][amount_in_y - y - 1];
      }
    }
  }
  //DEBUG
  Serial.println("===MIRROR EVEN ROWS===");
  for (int x = 0; x < amount_in_x; x++) {
    for (int y = 0; y < amount_in_y; y++) {
      Serial.print(transform_array[x][y], 4);
      Serial.print(" ");
    }
    Serial.println();
  }


  // SORT, hier ist der Teil, an dem ich gescheitert bin
  for (int x = 0; x < amount_in_x; x++) {
    for (int y = 0; y < amount_in_y; y++) {
      measure_array[x][y] = transform_array[amount_in_x - x - 1 ][amount_in_y - y - 1 ];
    }
  }

  //DEBUG
  Serial.println("===SORT ROWS===");
  for (int x = 0; x < amount_in_x; x++) {
    for (int y = 0; y < amount_in_y; y++) {
      Serial.print(measure_array[x][y], 4);
      Serial.print(" ");
    }
    Serial.println();
  }


}
void loop() {}

Mein Ziel ist es ein Array zu transformieren, sodass die Werte folgendermaßen ausgegeben werden, wenn ich diese über folgenden Befehl ausgebe:

  Serial.println("===TRANSFORM ARRAY (WORKING)===");
  for (int x = 0; x < amount_in_x; x++) {
    for (int y = 0; y < amount_in_y; y++) {
      Serial.print(measure_array[x][y], 4);
      Serial.print(" ");
    }
    Serial.println();
  }

Bsp.:
ursprünglich:
1.0001 1.0002 1.0003
1.0004 1.0005 1.0006
1.0007 1.0008 1.0009
1.0010 1.0011 1.0012
1.0013 1.0014 1.0015
1.0016 1.0017 1.0018

Ziel:
1.0018 1.0007 1.0006
1.0017 1.0008 1.0005
1.0016 1.0009 1.0004
1.0015 1.0010 1.0003
1.0014 1.0011 1.0002
1.0013 1.0012 1.0001

weiteres Beispiel:
Ursprung:
1.0001 1.0002 1.0003 1.0004
1.0005 1.0006 1.0007 1.0008
1.0009 1.0010 1.0011 1.0012
1.0013 1.0014 1.0015 1.0016
1.0017 1.0018 1.0019 1.0020
Ziel:
1.0016 1.0015 1.0006 1.0005
1.0017 1.0014 1.0007 1.0004
1.0018 1.0013 1.0008 1.0003
1.0019 1.0012 1.0009 1.0002
1.0020 1.0011 1.0010 1.0001

Ich hoffe, dass aus den Beispielen die gewünschte Transformation ersichtlich ist.

Beste Grüße

Ich hoffe, dass aus den Beispielen die gewünschte Transformation ersichtlich ist.

Nöö, für mich nicht.

Hallo,

ich erkenne nur, dass du immer die letzten Werte in die erste Spalte haben möchtest.
Dazu einmal aufwärts oder abwärts sortiert. Zusätzlich greifst du dann noch eher zufällig auf die anderen Werte zu um sie in die neue Zeile zu bringen.

Die erste Spalte aufwärts/abwärts wäre noch vielleicht machbar. Das andere wirkt zufällig. Da fehlt uns noch die eigentliche Zugriffslogik dahinter.

Gibt es ein festes Zugriffsmuster?
Kannst du die Werte schon besser einsortieren ins array damit das auslesen und sortieren leichter wird?

Willst du erstens Zeilen und Spalten vertauschen und zweitens jede gerade Zeile(dann Spalte) rückwärts?

Das rate ich aus deinen Beispielzahlen, sehe es aber nicht in deinem Code.
Ausserdem geht das so nicht mit rechteckigen Arrays. Aus 3x6 würde 6x3, aber du füllst einfach Elemente aus der nächsten Reihe nach ?

Das passt nicht zu zweidimensionalen Arrays.

Mal abgesehen davon, dass ein arduino hierfür eine der unpassendsten Plattformen ist, (und damit dieses Forum :wink: )

100-200-00:
Ich hoffe, dass aus den Beispielen die gewünschte Transformation ersichtlich ist.

Ja, anhand der Beispiele wird klar, dass Du ein Array umsortieren undie Array-Elemente an jeweils andere Stellen verschieben möchtest.

Mir stellt sich dabei aber die Frage: Dient das noch irgendeinem anderen Zweck als der Verschwendung von RAM-Speicher?

Denn am Array selbst ändert sich überhaupt nichts:Aus einem 4x5 Array wird wieder ein 4x5 Array und aus einem 4x6 Array wird wieder ein 4x6 Array.

Das Umsortieren kann man IN EINEM EINZIGEN ARRAY "an Ort und Stelle" machen.

Die Deklaration von zwei Arrays mit doppeltem RAM-Speicherbedarf:

 float measure_array[amount_in_x][amount_in_y];
  float transform_array[amount_in_x][amount_in_y];

ist dabei doch überhaupt nicht notwendig. Man braucht ein Array, in dem sortiert man die Elemente um, und am Ende hat man dasselbe Array mit anders einsortierten Array-Elementen. Die Notwendigkeit, nochmal RAM in Array-Größe unnötig zu verschwenden, sehe ich irgendwie nicht.

Wobei mir die ganze Umsortierung sehr seltsam vorkommt: Wofür braucht man sowas? Beschäftigungstherapie für einen Arduino, der sonst nicht ausgelastet ist?

jurs:
Mir stellt sich dabei aber die Frage: Dient das noch irgendeinem anderen Zweck als der Verschwendung von RAM-Speicher?

Sinn des Ganzen ist folgender:
Ich möchte mit einer Sonde eine Ebene scannen, die in vertikaler und horizontaler Richtung in Messpunkte aufgeteilt ist, also bspw. 3 Punkte horizontal x 6 Punkte vertikal (=18 Punkte insgesamt) aufweist. Hierfür beginne ich unten rechts und bewege mich hoch zum nächsten Punkt usw. Dies mache ich so lange, bis ich meine Anzahl an Punkten in vertikaler Richtung abgefahren habe. Danach gehe ich einen Schritt nach links (horizontal) und wiederhole das Ganze, nur in umgekehrter Richtung (also nach unten in vertikaler Richtung).
Der Schritt nach links wird also so lange gemacht, bis ich alle Punkte in horizontaler Richtung abgefahren habe / mich ganz links befinde.

Da ich mein Messarray aber zeilenweise fülle (von links nach rechts, von oben nach unten), muss ich den Messwerten wieder ihren ursprünglichen Ort zuweisen.

Warum?
Sobald ich die Messwerte für die Ebene habe, möchte ich mir diese über Serial.Print ausgeben lassen, um diese in Excel auswerten zu können. (Copy Paste, Excel erkennt dann anhand des Muster Reihen & Spalten)
Somit soll bspw. der Messwert aus der Ebene links oben später in Zelle A1 sein, usw.

Du mißt also in dieser räumlichen Anordnung
01, 02, 03, 04, 05, 06
12, 11, 10, 09, 08, 07
13, 14, 15, 16, 17, 18

Und möchtst dann die Daten in der Reihenfolge
01, 02, 03, 04, 05, 06, 12, 11, 10, 09, 08, 07, 13, 14, 15, 16, 17, 18 ausgeben.

int array[18];
int index =0;  //geht von 0 bis 17; 18 Werte
int x2=0;

for(int x=0; x<6;x++){
for(int y=0; y<3;y++){
x2=x;
if (y==1) x2=5-x;
index = x2+(y*6);
array[index] = messung();
}}

Grüße Uwe

Was ich nicht verstehe, warum musst du das Array umsortieren?

Kannst du nicht einfach die Werte in umgekehrter Reihenfolge ausgeben?

Serial.println("===TRANSFORM ARRAY (WORKING)===");
for (int x = 0; x < amount_in_x; x++) {
  if (x % 2 == 0) {                           // gerade X-Zeilen
    for (int y = 0; y < amount_in_y; y++) {
      Serial.print(measure_array[x][y], 4);
      Serial.print(" ");
    }
  } else {                                    // ungerade X-Zeilen
    for (int y = amount_in_y; y > 0 ; y--) {    // in umgekehrter Reihenfolge ausgeben
      Serial.print(measure_array[x][y], 4);
      Serial.print(" ");
    }
  }
  Serial.println();
}

edit: oder, wie Uwe beschrieben hat, in umgekehrter Reihenfolge abspeichern?

Hallo,

laut seinen Bsp. fängt er mit den letzten Werten an und hängt dann willkürlich andere Zeilen ran. Mit einfach Reihenfolge ändern ist da nichts. Ich kann immer noch keine Zugrifflogik erkennen. Das beste wäre er malt mal eine Art Schachbrett auf. Malt seine Meßreihenfolge ein und andersfarbig seine gewünschte Ausgabereihenfolge. Die Ausgabereihenfolge muss dann aber konstant sein und nicht wie in den Bsp. verschieden.

Ich hab ihn so verstanden, dass er die Felder im Zickzack liest, aber "der Reihe nach" ausgeben will.

Einlesen:

1234 8765 9ABC

Ausgeben wie die Felder in Wirklichkeit angeordet sind:

1234
5678
9ABC

Der Rest war nur zur Verwirrung.

Hallo 100-200-00,

ist das Dein Ziel das Array in dieser Form auszulesen? Wie es michael_x beschrieben hat oder so

0123 4567 89AB CDEF wird zu

C B 4 3
D A 5 2
E 9 6 1
F 8 7 0

(Erinnert an ein Maze Game … Schlange frisst Zahlen von 0 an und folgt einer Spur … :slight_smile: )

stevie72:
Hallo 100-200-00,

ist das Dein Ziel das Array in dieser Form auszulesen?

Ein Bild auf deinem Desktop?
//c/Users/fu000956/Desktop/test.jpg

Hallo,
ich habe jetzt mal eine kleine Grafik erstellt, hoffe damit wird es klarer:

Genau, sag ich doch.
Das mit dem zusätzlichen "insgesamt umdrehen" ist nur zur extra Verwirrung, und damit stevie72 Sonderbonuspunkte kriegt...
:wink:

DocArduino:
Das andere wirkt zufällig

Du willst übrigens kein Array transformieren, sondern nur eines in einer bestimmten Reihenfolge füllen.
Damit hast du die Hälfte deines Problems gelöst und die andere Hälfte vereinfacht...

@michael_x

Den Highscore teilen wir durch zwei :wink:

Eine Überlegung..
Demnach ist die Folge:

Für 16 Speicherzellen 0 bis F
deren Adressierung

Wobei END das Physikalische Ende ist.

0 = END
1 = END -4
2 = END -8
3 = END -12
4 = END -12 -1
5 = END - 8 -1
6 = END - 4 -1
7 = END -1
8 = END -2
9 = END -4 -2
A = END -8 -2
B = END -12 -2
C = END -12 -3
D = END -8 -3
E = END -4 -3
F = END -3

Kann man noch umstellen in der Schreibweise...

Na, wenn das nicht zufällig wirkt;

4x4 wäre

cb43
da52
e961
f870

Könnte mit deiner Schreibweise übereinstimmen.

Da kann man sich einige einfache Lösungen ausdenken. Ein konstantes Hilfsarray, das für jede Messung sagt, in welche Ziel-Zelle sie gehört, ist sicher eine Möglichkeit.

Interessant wird das ganze erst, wenn der Sketch ohne Neukompilieren und Hochladen verschiedene Array-Abmessungen "können" soll. Sowas hat 100-200-00 leicht angedeutet. Bis dahin : Viel Spass.

:o

Das heist ja er will den Speicher hierfür in seiner Größe dynamisch halten, trotzdem soll am Speicherende der Beginn
sein .. hmmm... seltsam

Du hast Recht michael_x - das wird interessant .. eigentlch fast unmöglich ...
Es sei denn, er reserviert einen dynamischen Speicherbereich mit malloc, den exclusiv nur das programm in dessen grösse, sowie Inhalt verwalteten darf ... d.h. Schreiben / Lesen
aber währe der Speicher dann überhaupt geschützt ?

Der 68000er kennt auch so einen malloc Befehl da musste man aber pinibel auf den Stack achten..
und im supervisor mode ausgeführt werden. Wenn nicht nicht -> absturz

Ich habe jetzt mal den Sketch von uwe versucht zu verstehen & anzuwenden, leider ohne Erfolg.

michael_x:
Interessant wird das ganze erst, wenn der Sketch ohne Neukompilieren und Hochladen verschiedene Array-Abmessungen “können” soll. Sowas hat 100-200-00 leicht angedeutet. Bis dahin : Viel Spass.

In der Tat, so war es geplant :frowning: Ich übergebe die Anzahl an Messpunkten in x und y Richtung und der Arduino schreibt dann die Messwerte an die richtige Stelle des Arrays, sodass ich mit dem Serial.Print()-Befehl mir die Werte in der gewünschten Reihenfolge ausgeben lassen kann…

Ich sitz an dieser Problematik nun fast die ganze Woche und bin einfach zu doof die Lösung zu finden :frowning:
Mein Problem ist vor allem, dass es so viele verschiedene Herangehensweisen gibt, aber jede an einer gewissen Stelle ins Nirvana verläuft…

Für quadratische Messfelder hatte ich bereits eine Lösung, die zum Ziel führt:

Serial.println("===TRANSFORM ARRAY_WORKING===");
  for (int x = 0; x < amount_in_x; x++) {
    for (int y = 0; y < amount_in_y; y++) {
      if (x % 2 == 0) { // gerade)
        transform_array[x][y] = measure_array[x][y];
      } else {
        transform_array[x][y] = measure_array[x][amount_in_y - y - 1];
      }
    }
  }


  for (int y = 0; y < amount_in_y; y++) {
    for (int x = 0; x < amount_in_x; x++) {
      Serial.print(transform_array[amount_in_x - x - 1][amount_in_y - y - 1], 4);
      Serial.print(" ");
    }
    Serial.println();
  }

Sobald man aber nicht quadratische Messfelder eingibt, ist zwar die Reihenfolge korrekt aber die Auflösung in x und y Richtung vertauscht.

Mittlerweile frustriert das schon ziemlich, dass bei mir einfach der “Aha” Effekt ausbleibt…
Einfach zu dumm zum programmieren…

Ich finde immer noch, dass der Ansatz das Array umzusortieren nicht der Optimale Weg ist.

Dir geht es doch vor allem um die Ausgabe der Messwerte in korrekter Reihenfolge.
Dazu ist es aber völlig unerheblich in welcher Reihenfolge die Werte gespeichert sind, man muss nur Wissen welcher Wert wo steht, und in welcher Reihenfolge es ausgegeben werden muss.

Das ist wie bei chaotischer Lagerhaltung: Es ist egal in welchem Regal was liegt, solange der Computer den Ort kennt.

Ich würde den Aufwand nicht in die Datenerfassung oder sortierung stecken, sondern in die Ausgaberoutine.

Du könntest z.B ein eindimensionales Array verwenden, und zwei Werte für Länge und Breite des Feldes.

und dann über die Ausgaberoutine in der Richtigen Reihenfolge ausgeben, oder?