Forum: PC-Programmierung QT Surface mit random daten?


von Dani (Gast)


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.
1
void SurfaceGraph::fillSqrtSinProxy()
2
{
3
    float stepX = (sampleMax - sampleMin) / float(sampleCountX - 1);
4
    float stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1);
5
6
    QSurfaceDataArray *dataArray = new QSurfaceDataArray;
7
    dataArray->reserve(sampleCountZ);
8
    for (int i = 0 ; i < sampleCountZ ; i++) {
9
        QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX);
10
        // Keep values within range bounds, since just adding step can cause minor drift due
11
        // to the rounding errors.
12
        float z = qMin(sampleMax, (i * stepZ + sampleMin));
13
        int index = 0;
14
        for (int j = 0; j < sampleCountX; j++) {
15
            float x = qMin(sampleMax, (j * stepX + sampleMin));
16
            float R = qSqrt(z * z + x * x) + 0.01f;
17
            float y = (qSin(R) / R + 0.24f) * 1.61f;
18
            (*newRow)[index++].setPosition(QVector3D(x, y, z));
19
        }
20
        *dataArray << newRow;
21
    }
22
23
    m_sqrtSinProxy->resetArray(dataArray);
24
}

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
1
#ifdef RANDOM_SCATTER
2
    for (int i = 0; i < m_itemCount; i++) {
3
        ptrToDataArray->setPosition(randVector());
4
        ptrToDataArray++;
5
    }

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

von Vincent H. (vinci)


Angehängte Dateien:

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:
1
void SurfaceGraph::fillSqrtSinProxy() {
2
  QSurfaceDataArray* dataArray = new QSurfaceDataArray;
3
  dataArray->reserve(sampleCountZ);
4
5
  std::random_device rd;
6
  std::mt19937 gen(rd());
7
  std::uniform_real_distribution<> dis(0.4, 0.8);
8
9
  for (int i = 0; i < sampleCountZ; i++) {
10
    QSurfaceDataRow* newRow = new QSurfaceDataRow(sampleCountX);
11
12
    int index = 0;
13
    for (int j = 0; j < sampleCountX; j++) {
14
    // Z-Achse wird hier durch Zufallswert ersetzt
15
      (*newRow)[index++].setPosition(QVector3D(j * 0.1f, dis(gen), i * 0.1f));
16
    }
17
18
    *dataArray << newRow;
19
  }
20
21
  m_sqrtSinProxy->resetArray(dataArray);
22
}


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

von Dani (Gast)


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.

von Vincent H. (vinci)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.