Gitter erzeugen



  • Hallo Leute

    ich brauche mal wieder eure Hilfe, da mir gerade mal wieder jemand auf dem Schlauch sitzt.

    Ich möchte ein Gitter erzeugen in das ich Datenpukte eintragen möchte. Der Gitterabstand soll 0,2 in X- und Y-Richtung betragen. Der Datenpunkt soll mit meinen Gitterpunkten verglichen werden und am richtigen Gitterpunkt eingetragen werden. Wie mache ich sowas?



  • sry, aber ich glaube, hier verstehen die leute nicht wirklich was du willst... willst du irgendetwas grafisch darstellen, oder geht es dir um irgendeinen pervers komplizierten container, der objekte schnell nach ihrer position im raum abspeichern und sehr schnell wieder finden kann? 😕 (irgendsoein BSP-dingens für kollisionserkennung oder irgendwas in die richtung??)



  • Sorry wenn das etwas kompliziert klang. Ich möchte eigentlich in eine Matrix, in der der x- und y-abstand 0.1 sein soll, werte eintragen. Diese möchte ich nachher graphisch darstellen. Die Werte bekomme ich aus einem Scanner, der mir x- und z-werte liefert.

    Ich dachte also an irgendwie sowas:

    float xScannerwert; 
    int yabstand;
    float zscannerwert;
    
    float gitter[256][256];
    
    for(int i = 0; i < 256; i++)
    {
        gitter[(int)xScannerwert][yAbstand] = zscannerwert;
    }
    

    Was ich mich nur frage ist, wie ich den Gitterabstand auf 0.1 bekomme. Ich laufe doch meine Matrix ganzzahlig durch. Wo ist denn da mein Denkfehler?

    Ausserdem sind meine xScannerwerte eigentlich negativ. Negative Indexwerte gibt es ja aber nicht in einem array.

    Also entweder das ist jetzt alles verwirrend was ich geschrieben habe, oder es sitzt mir tatsächlich jemand auf dem Schlauch.



  • hmm, ich glaub du hast eher ein Mathematisches Problem 😉

    also du hast 256 Werte in x und 256 Werte in y - Richtung, soweit mal korrekt?
    Und diese Werte möchtest du mit einer Auflösung von 0,1 abspeichern, stimmt das?

    Wenn JA, dann überleg mal, wenn deine Auflösung 1 wäre, dann würde ein 256*256 Array reichen! Deine Aufösung ist aber 10x besser also 0,1 ,folglich musst du ein Array mit 2560*2560 Elemente verwenden.

    Alles klar?



  • Was Du hier brauchst ist eine lineare Abbildung von der Scanner-Position (x,y) alias (xScannerwert,yAbstand) zu einem Indexpaar ix,iy innerhalb des Gitters bzw. der Matrix.

    Ich nehme mal an, dass keine Rotation vorgesehen ist, dann ist die allgemeine Form

    ix = nx * x + px
    iy = oy * y + py
    

    nx und oy sind die Skalierfaktoren. In Deinem Fall sind sie vom Betrag her 10. 10 weil eine Einheit auf dem Scanner genau 10 Einheiten im Gitter sind.
    px und py ist der Ursprung der Scanner-Koordinaten bezogen auf das Gitter. Oder anders ausgedrückt sie geben das Index-Paar im Gitter an, welches bei der Scannerposition (0,0) liegt.
    Für die negativen X-Koordinaten hast Du nun zwei Möglichkeiten. Entweder ist nx = -10 oder nx ist +10 und px ist so groß, dass ix nicht unter 0 fällt. Zum Beispiel px = 25,6. Die Möglichkeiten unterscheidensich dadurch, dass das Bild einmal gespiegelt ist und einmal nicht.
    Zum Schluß must Du noch runden, um auf ganzzahlige Koordinaten zu kommen.
    Der Code sieht dann etwa so aus:

    float xScannerwert;
        float yAbstand;
        float zscannerwert;
    
        float gitter[256][256];
    
        // -- nur ein Beispiel
        float nx = -10; // oder 10
        float oy = 10;
        float px = 0;  // oder 25.6
        float py = 0;
    
        for(int i = 0; i < 256; i++)
        {
            int ix = floor( nx * xScannerwert + px + 0.5 );
            int iy = floor( oy * yAbstand + py + 0.5 );
            if( ix >= 0 && ix <256 && iy >= 0 && iy < 256 ) // Bereich prüfen
                gitter[ix][iy] = zscannerwert;
        }
    

    für das floor benötigt man noch #include <cmath> und das '+ 0.5' kann man natürlich auch gleich zu px, bzw. py hinzufügen.

    Falls Du mit den nx,oy,px und py nicht klar kommst, so sage uns einfach an welchen Scanner-Positionen die vier Ecken der Matrix liegen sollen. Also welche Werte xScannerwert,yAbstand gehören zu den Gitterpunkten [0][0], [255][0], [255][255] und [0][255]?

    Gruß
    Werner



  • Hallo Werner

    vielen Dank für deine ausführliche Antwort. Deine Lösung geht auf jeden Fall schonmal in die Richtung die ich brauche. Meine Eckdaten für die Matrix sind:
    MinScannerX = -380;
    MaxScannerX = -360;
    MinY = 0;
    MaxY = 255;

    So ungefähr sind die Daten. Die sind deshalb so seltsam, da sie auf eine Roboterposition mit draufgerechnet werden. Und ich die Scannerdaten in Abhängigkeit des Roboters brauche.

    Danke auf jeden Fall schonmal!!



  • Meine Eckdaten für die Matrix sind:
    MinScannerX = -380;
    MaxScannerX = -360;
    MinY = 0;
    MaxY = 255;

    ach bitte 😃 , was soll Werner Salomon denn mit diesen ziffern? der wird jetzt wohl kaum durch die gegend rennen und nach einem taschenrechner suchen^^ 😉 die ein paar multiplikationen kriegst du schon irgendwie hin, werner hat schliesslich schon alles hingeschrieben, was man für die lösung braucht, man muss nur andere werte einsetzen 👍



  • samo schrieb:

    Meine Eckdaten für die Matrix sind:
    MinScannerX = -380;
    MaxScannerX = -360;
    MinY = 0;
    MaxY = 255;

    Ok dann sind die Werte für oy und py einfach. oy = 1 und py = 0; d.h. iy = yAbstand. Das steht aber im Widerspruch zu Deiner ersten Angabe

    samo schrieb:

    Ich möchte eigentlich in eine Matrix, in der der x- und y-abstand 0.1 sein soll, werte eintragen.

    Egal .. und der Rest ist

    float nx = 12.75;
        // float oy = 1;
        float px = 4845;
        // float py = 0;
    
        for(int i = 0; i < 256; i++)
        {
            int ix = floor( nx * xScannerwert + px + 0.5 );
            int iy = yAbstand;
            if( ix >= 0 && ix <256 && iy >= 0 && iy < 256 ) // Bereich prüfen
                gitter[ix][iy] = zscannerwert;
        }
    

    .. und Andrey erklärt Dir warum das richtig ist 🕶 . Ich muss jetzt weg.

    Gruß
    Werner



  • .. und Andrey erklärt Dir warum das richtig ist 🕶 . Ich muss jetzt weg.

    kP... der OP hat mich irgendwie voll verwirrt, ich kann im moment das, was er wollte, nicht mit deinem code in zusammenhang bringen, Werner, also poste ich hier einfach meine version, der OP soll dann auswählen,was ihm besser gefällt^^ 😃

    //wertebereich von dem scanner (eingabe im "konstruktor?")
    float scanner_x_min=-380;
    float scanner_x_max=-360;
    float scanner_y_min=0;
    float scanner_y_max=255;
    
    //auflösung=0.1
    float resolution =0.1;
    int gridWidth=static_cast<int>((scanner_x_max-scanner_x_min)/resolution)+1;
    int gridHeight=static_cast<int>((scanner_y_max-scanner_y_min)/resolution)+1;
    
    int** pGrid; //gitter (membervariable der klasse ?)
    //speicherplatz reservieren
    pGrid=new int*[gridWidth];
    for(int i=0; i<gridWidth; i++){
     pGrid[i]=new int[gridHeight];
    }
    
    //umrechnung von scanner-werten in die array-koordinaten
    int& at(float scanner_x, float scanner_y){
     int array_x=static_cast<int>((scanner_x-scanner_x_min)/resolution);
     int array_y=static_cast<int>((scanner_y-scanner_y_min)/resolution);
     if(array_x>=0 && array_x<gridWidth && array_y>=0 && array_y<gridHeight){
       return pGrid[array_x][array_y];
     }else{
       //hoppla, da ist was schief gelaufen
       return (**pGrid);
     }
    }
    

    diese code schnipsel funktionieren in der form direkt natürlich nicht, den ersten block musst du irgendwie in deinen konstruktor, oder wo auch immer, einbinden, die at funktion muss dann auch zugriff auf die ganzen variablen haben. das alles war eher als erläuterung des "mathematischen hintergrundes" gedacht^^ aber das kriegst du schon irgendwie in dein programm integriert...



  • Hallo Andrey,

    das ist natürlich auch eine Lösung. Die Diskrepanz liegt darin dass samo widersprüchliche Angaben macht. Wenn man die drei Größen Bildbereich (Min/MaxScannerX) Gitterbereich (0,255) und Auflösung anschaut, so sind immer nur zwei frei wählbar, die dritte folgt dann unmittelbar aus den beiden anderen. Bei Dir war es der Bildbereich und die Auflösung und ich habe angenommen Bildbereich und Gitterbereich ist fest.

    Hallo samo,

    wie isses denn nun? was ist wirklich gegeben und was ergibt sich daraus. Und wie läuft das Erfassen der Scannerswerte eigentlich ab. Wenn Du 256 Scannerwerte erhälst, so brauchst Du sie doch nur auf die Indizes 0 bis 255 zu verteilen. Erhältst Du weniger, so gibt es Lücken; sind mehr da, so werden Gitterpunkte doppelt beschrieben (der letzte gewinnt). Sag' uns doch mal genau wie die Scannerwerte 'zscannerwert' in das System hineinkommen.

    Gruß
    Werner



  • Hallo

    sorry dass ich mich solange nicht gemeldet habe, war abwesend. Das Problem ist gelöst dank eurer Hilfe (DANKE!), aber ich möchte dennoch die letzte Frage von Werner noch beantworten:

    Und wie läuft das Erfassen der Scannerswerte eigentlich ab. Wenn Du 256 Scannerwerte erhälst, so brauchst Du sie doch nur auf die Indizes 0 bis 255 zu verteilen. Erhältst Du weniger, so gibt es Lücken; sind mehr da, so werden Gitterpunkte doppelt beschrieben (der letzte gewinnt)

    Genauso werden die Daten auch generiert und eigentlich ist es auch kein Problem, die Daten auf die Indizes 0 bis 255 zu verteilen. Meine Überlegung war allerdings, dass ich eigentlich nicht möchte, dass die Daten überschrieben werden und wollte somit eine kleinere Auflösung meines Gitters, damit mir nicht zuviele Punkte meines Scanners verloren gehen. Allerdings war das Ergebnis nicht wie gewünscht und ich bin im Endeffekt dann doch wieder zurück zum Ursprung, Daten nehmen wie sie kommen und in das Gitter eintragen ohne kleinere Auflösung des Gitters.

    Danke jedenfalls nochmal für die tolle Unterstützung! 👍


Anmelden zum Antworten