Mathematische Gleichungen

Visualisierung mathematischer Gleichungen.

Mathematische Gleichungen zeigt, wie mathematische Gleichungen in QML mit allen verfügbaren Diagrammtypen visualisiert werden können. Es wird auch gezeigt, wie man die QtQuick3D Szene in ein Diagramm integriert und wie man das Aussehen des Diagramms mit ExtendedSceneEnvironment anpasst.

Weitere Informationen zu den grundlegenden Funktionen von QML-Anwendungen finden Sie unter Einfaches Streudiagramm.

Ausführen des Beispiels

Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel unter Examples aus. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.

Einrichten

Die Daten für alle Diagrammtypen können in einem gemeinsamen ListModel gespeichert werden:

ListModel {
    id: dataModel
}

Das Modell wird für jeden Diagrammtyp in der Diagrammreihe eingestellt:

Surface3DSeries {
    id: surfaceSeries
    itemLabelFormat: "(@xLabel, @zLabel): @yLabel"

    ItemModelSurfaceDataProxy {
        itemModel: dataModel
        columnRole: "xPos"
        yPosRole: "yPos"
        rowRole: "zPos"
    }
}
...
Bar3DSeries {
    id: barSeries
    itemLabelFormat: "@colLabel, @rowLabel: @valueLabel"

    ItemModelBarDataProxy {
        itemModel: dataModel
        columnRole: "xPos"
        valueRole: "yPos"
        rowRole: "zPos"
    }
}
...
Scatter3DSeries {
    id: scatterSeries
    itemLabelFormat: "(@xLabel, @zLabel): @yLabel"
    mesh: Abstract3DSeries.Mesh.Point

    ItemModelScatterDataProxy {
        itemModel: dataModel
        xPosRole: "xPos"
        yPosRole: "yPos"
        zPosRole: "zPos"
    }
}

Durch die Einstellung der Rollen können die Daten im Modell automatisch auf die entsprechenden Achsen abgebildet werden.

Parsing der Gleichung

Die Gleichung kann unter Verwendung der folgenden Operatoren und mathematischen Funktionen sowie der für die Verwendung dieser Funktionen erforderlichen Zeichen in das Textfeld eingegeben werden:

OperatorenFunktionenZeichen
+ - * / % ^sin cos tan log exp sqrt( ) ,

Als Parameter werden x und y unterstützt, da die zu behandelnden Daten zwei Achsen und den Wert haben. Die Gleichung kann Leerzeichen um die Operatoren enthalten, so dass beide der folgenden Stile in Ordnung sind:

  • x^2+y^2
  • x ^ 2 + y ^ 2

Die Gleichung wird mit einem JavaScript-Gleichungsparser und -Rechner geparst, der in QML importiert wird:

import "calculator.js" as Calc

Der Rechner wurde von tanguy_k in TypeScript auf Stack Overflow gepostet und wurde in JavaScript konvertiert, um von QML aus verwendet werden zu können.

Die Gleichungsparameter werden jedes Mal ausgefüllt, wenn sich die Gleichung ändert oder die Spalten- oder Zeilenzahl aktualisiert wird.

Schleifenbildung der Zeilen und Spalten:

for (i = xValues.first.value; i <= xValues.second.value; ++i) {
    for (j = zValues.first.value; j <= zValues.second.value; ++j)
        addDataPoint(i, j)
}

Ausfüllen der Werte für x und y:

function addDataPoint(i, j) {
    var filledEquation = equation.text.replace("x", i)
    filledEquation = filledEquation.replace("y", j)
    ...

Die Gleichung wird dann an den JavaScript-Rechner übergeben, um das Ergebnis zu erhalten, das dann dem Datenmodell hinzugefügt wird, indem es in die definierten Rollen eingefügt wird:

try {
    var result = Calc.calculate(filledEquation)
    dataModel.append({"xPos": i, "yPos": result, "zPos": j})
}

Falls ein Fehler oder ein unbekannter Operator oder eine unbekannte mathematische Funktion in der Gleichung auftritt, wird der vom Rechner ausgelöste Fehler abgefangen und ein Fehlerdialog angezeigt:

MessageDialog {
    id : messageDialog
    title: qsTr("Error")
    text: qsTr("Undefined behavior")
    ...

Anzeige der Fehlermeldung des Taschenrechners:

catch(msg) {
    messageDialog.informativeText = msg.toString()
    messageDialog.open()
}

Graphen

Für alle drei Diagrammtypen wird das gleiche Datenmodell verwendet. Es gibt jedoch einige Unterschiede bei der Erstellung der Diagramme.

Oberfläche

Das Oberflächendiagramm wird verwendet, um die Daten ohne spezifische Änderungen anzuzeigen. Es stellt die Gleichung in jeder Zeile und Spalte mit dem Berechnungsergebnis dar.

Die einzigen Änderungen, die vorgenommen werden, sind die Einstellung der Anzahl der Achsensegmente:

axisX.segmentCount: 10
axisZ.segmentCount: 10
axisY.segmentCount: 10

Für das Thema wird ein Bereichsgradient festgelegt, um die hohen und niedrigen Werte hervorzuheben:

theme : GraphsTheme {
    id: surfaceTheme
    colorStyle: GraphsTheme.ColorStyle.RangeGradient
    baseGradients: [ gradient1 ]
    plotAreaBackgroundVisible: false
}

Der Farbverlauf selbst wird an anderer Stelle definiert, damit er von anderen Themen verwendet werden kann.

Balken

Für Balken wird ebenfalls ein Farbverlauf verwendet. Der Farbverlauf ist leicht transparent, damit die Werte leichter zu erkennen sind, ohne das Diagramm zu sehr zu drehen. Ein Schieberegler wurde hinzugefügt, um den Grad der Transparenz zu steuern.

Streuung

Für die Streuung wurde das Thema in Vorbereitung auf die QtQuick3D-Integrationen etwas mehr angepasst.

Zunächst wird ein anderer Farbverlauf als bei den beiden anderen verwendet. Dann wird ein dunkles Farbschema erzwungen, im Gegensatz zu den anderen beiden, die die Systempräferenz verwenden. Schließlich werden der Hintergrund des Diagrammbereichs, die Beschriftungen und das Gitter ausgeblendet, indem ihre Sichtbarkeit auf false gesetzt wird.

Das Streudiagramm eignet sich gut zur Darstellung einer großen Anzahl von Datenpunkten, weshalb für jede "Zeile" und "Spalte" 3 Datenpunkte hinzugefügt werden. Da das Punktdiagramm nicht über das Konzept von Zeilen und Spalten verfügt, kann dies so gemacht werden:

for (var i = xValues.first.value; i <= xValues.second.value; i += 0.333) {
    for (var j = zValues.first.value; j <= zValues.second.value; j += 0.333)
        addDataPoint(i, j)
}

Da das Scatter-Diagramm viel mehr Datenpunkte hat als die beiden anderen Diagramme, ist es besser, die leichteste verfügbare mesh type für die Punkte zu verwenden:

mesh: Abstract3DSeries.Mesh.Point

Einbinden einer QtQuick3D-Szene

Damit die QtQuick3D Typen gefunden werden können, müssen sie in QML importiert werden:

import QtQuick3D

Eine QtQuick3D Szene kann über die Eigenschaft importScene in den Graphen importiert werden. Die Szene kann eine Kombination aus Models, Lights, reflection probes und anderen Nodes sein, die in einer Wurzel Node enthalten sind. In diesem Beispiel wird nur ein Rechteck mit einer Opazitätskarte hinzugefügt:

importScene: Node {
    Model {
        scale: Qt.vector3d(0.1, 0.1, 0.1)
        source: "#Rectangle"
        y: -2
        eulerRotation.x: -90
        materials: [
            PrincipledMaterial {
                baseColor: "#373F26"
                opacityMap: Texture {
                    source: "qrc:/images/opacitymap.png"
                }
            }
        ]
    }
}

Ändern des Ausblicks mit QtQuick3D

Damit die ExtendedSceneEnvironment gefunden werden kann, ist der folgende Import erforderlich:

import QtQuick3D.Helpers

Um die Standard-Szenenumgebung des Graphen außer Kraft zu setzen, wird die Eigenschaft environment mit einem ExtendedSceneEnvironment hinzugefügt. In diesem Fall werden backgroundMode, clearColor und tonemapMode gesetzt. Darüber hinaus ist glow aktiviert. Das Hinzufügen von Nachbearbeitungseffekten wie Glühen erfordert die Einstellung des Tonemap-Modus auf TonemapModeNone.

environment: ExtendedSceneEnvironment {
    backgroundMode: ExtendedSceneEnvironment.Color
    clearColor: scatterTheme.backgroundColor
    tonemapMode: ExtendedSceneEnvironment.TonemapModeNone
    glowEnabled: true
    ...

Um das Glühen stark zu machen, werden verschiedene andere Eigenschaften eingestellt.

Beispielprojekt @ code.qt.io

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.