mikrocontroller.net

Forum: PC-Programmierung QT Surface mit random daten?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Dani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich versuche mich gerade in das das surface-example von QT einzuarbeiten 
(https://doc.qt.io/qt-5/qtdatavisualization-surface-example.html) und 
mit anderen Daten auszustatten was nicht so wirklich gelingt daher eine 
kurze Verständnisfrage.

Lässt sich ein surface überhaupt mit "random" Daten bestücken? Beim 
Scatter Example geht dies ohne Probleme, dort sind es auch "nur" 
einzelne Datenpunkte im 3D Raum.
Beim surface hingegen sind die Punkte durch eine Oberfläche also wie ein 
Stoff über Datenpunkte verbunden. Jetzt frage ich mich irgendwie muss 
wohl der jeweilige Nachbar bekannt sein damit für die Darstellung klar 
ist welcher Punkt zu welchem mit dem Stoff überzogen wird. Dort wird 
flogendes wohl zum Daten füttern verwendet: 
https://doc.qt.io/qt-5/qsurfacedataproxy.html

Im Code sieht es so aus, als würden mehrere Datenpunkte in Reihe/"Row" 
erzeugt werden und dann erst in die dritte Dimension.
void SurfaceGraph::fillSqrtSinProxy()
{
    float stepX = (sampleMax - sampleMin) / float(sampleCountX - 1);
    float stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1);

    QSurfaceDataArray *dataArray = new QSurfaceDataArray;
    dataArray->reserve(sampleCountZ);
    for (int i = 0 ; i < sampleCountZ ; i++) {
        QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX);
        // Keep values within range bounds, since just adding step can cause minor drift due
        // to the rounding errors.
        float z = qMin(sampleMax, (i * stepZ + sampleMin));
        int index = 0;
        for (int j = 0; j < sampleCountX; j++) {
            float x = qMin(sampleMax, (j * stepX + sampleMin));
            float R = qSqrt(z * z + x * x) + 0.01f;
            float y = (qSin(R) / R + 0.24f) * 1.61f;
            (*newRow)[index++].setPosition(QVector3D(x, y, z));
        }
        *dataArray << newRow;
    }

    m_sqrtSinProxy->resetArray(dataArray);
}

Die Daten sind im Beispiel gleichmäßig verteilt, was aber bei anderen 
Daten nicht unbedingt so ist.
ZB beim scatter example gibt es eine Möglichkeit random Werte anzeigen 
zu lassen:
https://doc.qt.io/qt-5.12/qtdatavisualization-scatter-scatterdatamodifier-cpp.html
#ifdef RANDOM_SCATTER
    for (int i = 0; i < m_itemCount; i++) {
        ptrToDataArray->setPosition(randVector());
        ptrToDataArray++;
    }

Würde sich random Werte auch auf das Surface-Example anwenden lassen?, 
also kann auch eine beliebige Streuung im 3D Raum als Surface angezeigt 
werden? und wie würde das funktionieren? Wäre genial wenn dies irgendwie 
klappen würde. Danke schon mal für jeden Input, LG

Autor: Vincent H. (vinci)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Prinzipiell funktioniert das schon, die Frage ist nur wie sinnvoll das 
ganze ist? Solange die Zufallswerte in einem bestimmten Bereich liegen 
und nur etwa 1x Achse betroffen ist mag das brauchbare Grafiken 
erzeugen, aber doch sicher nicht wenn die Daten komplett zufällig 
erzeugt werden?

Ich hab mal ein Bild angehängt wo für einen Surface-Plot die Z-Werte 
zufällig zw. 0.4 und 0.8 erzeugt werden.

Die von dir bereits gepostete Funktion hab ich etwas abgeändert:
void SurfaceGraph::fillSqrtSinProxy() {
  QSurfaceDataArray* dataArray = new QSurfaceDataArray;
  dataArray->reserve(sampleCountZ);

  std::random_device rd;
  std::mt19937 gen(rd());
  std::uniform_real_distribution<> dis(0.4, 0.8);

  for (int i = 0; i < sampleCountZ; i++) {
    QSurfaceDataRow* newRow = new QSurfaceDataRow(sampleCountX);

    int index = 0;
    for (int j = 0; j < sampleCountX; j++) {
    // Z-Achse wird hier durch Zufallswert ersetzt
      (*newRow)[index++].setPosition(QVector3D(j * 0.1f, dis(gen), i * 0.1f));
    }

    *dataArray << newRow;
  }

  m_sqrtSinProxy->resetArray(dataArray);
}


Außerdem hab ich folgende Konstanten abgeändert damit ich mich nicht mit 
irgendeiner Skalierung plagen muss:
const float sampleMin = 0.0f;
const float sampleMax = 1.0f;

Autor: Dani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke das sieht gut aus. Wenn ich es richtig verstehe ist sind die Rows 
die Basis um die Verbindungen zwischen Row zu Row zu spannen ohne das es 
chaotisch wird.
So generierte Datenpunkte unterliegen meist automatisch einer Struktur 
durch zb Schleifen etc dann klappt das gut mit dem "Row zu Row".

Was natürlich noch interessant ist wie man Beispielsweise einen 3D 
Vector dort anzeigt welcher nicht von Beginn an dieser "Row zu 
Row"-Struktur entspricht. Wenn zB ein genetischer Optimierer die zB 
Himmelblaufunktion zum kleinsten Wert hin optimiert und der Verlauf die 
Datenpunkte im Raum darstellt, wäre dieser 3D vector erstmal unsortiert 
und die Datenpunktdichte im Raum unterschiedlich stark. Die Frage wäre 
wie würde man solche bestehenden 3D Datenpunkte so managen, dass das 
QSurfaceDataArray so befüllt wird, dass es zwischen benachbarten Punkten 
Verbindungen spannen kann.

Autor: Vincent H. (vinci)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das scheint leider nicht so simpel zu sein. Den Moment wo man in 
irgendeiner Reihe einen Punkt anlegt wird der Ursprung als erster 
Verbindungspunkt herangezogen. Da bin ich leider überfragt.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.