本页内容

数学方程

数学方程的可视化。

“数学方程”演示了如何在 QML 中利用所有可用的图形类型可视化数学方程。它还展示了如何将QtQuick3D 场景集成到图形中,以及如何使用ExtendedSceneEnvironment 调整图形的外观。

带有发光效果和控制按钮的、显示数学方程的3D表面

有关 QML 应用程序基本功能的更多信息,请参阅《简单的散点图》。

运行示例

您可以通过以下方式运行该示例:

设置

所有图类型的数据均可存储在同一个ListModel 中:

ListModel {
    id: dataModel
}

在图系列中,针对每种图类型分别设置模型:

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"
    }
}

设置角色可使模型中的数据自动映射到相应的坐标轴上。

解析方程

可在文本框中输入方程,使用以下运算符和数学函数,以及使用这些函数所需的特殊字符:

运算符函数字符
+ - * / % ^sin cos tan log exp sqrt( ) ,

由于处理的数据包含两个坐标轴和数值,因此支持将x 和y 作为参数。方程中的运算符周围可以有空格,因此以下两种写法均可:

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

方程通过 JavaScript 方程解析器和计算器进行解析,该组件已导入到 QML 中:

import "calculator.js" as Calc

该计算器由tanguy_k 以TypeScript 语言发布在Stack Overflow上,后被转换为 JavaScript 以便在 QML 中使用。

每当方程发生变化或列数、行数更新时,方程参数都会被重新填充。

遍历行和列:

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

为x 和y 填入数值:

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

随后将方程传递给 JavaScript 计算器以获取结果,并将结果插入到已定义的角色中,从而添加到数据模型中:

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

如果公式中存在错误、未知运算符或数学函数,将捕获计算器抛出的错误,并显示错误对话框:

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

显示来自计算器的错误消息:

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

图表

这三种图表类型均使用同一数据模型。不过,在配置图表时存在一些差异。

面图

表面图用于直接展示数据,无需进行任何特定修改。它会在每一行和每一列渲染方程及其计算结果。

唯一进行的更改是设置坐标轴的分段数量:

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

主题中设置了范围渐变,以突出显示数据的高值和低值:

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

该渐变效果已在其他位置定义,以便其他主题也能使用。

条形图

条形图同样采用了范围渐变。该渐变利用了轻微的透明度,使查看数值更加便捷,而无需大幅旋转图表。已添加一个滑块来控制透明度级别。

散点图

对于散点图,该主题进行了更多调整,以适应QtQuick3D 的集成。

首先,它将使用与另外两种图表不同的渐变效果。其次,与另外两种图表采用系统偏好设置不同,此处强制使用深色配色方案。最后,通过将可见性设置为 false,隐藏了绘图区域的背景、标签和网格。

散点图擅长展示大量数据点,因此每行和每列都增加了 3 个数据点。散点图本身没有行和列的概念,因此可以这样做:

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)
}

由于散点图的数据点远多于其他两种图表,因此最好为数据点选用最浅色的mesh type :

mesh: Abstract3DSeries.Mesh.Point

集成 QtQuick3D 场景

要使用QtQuick3D 类型,必须将其导入到QML中:

import QtQuick3D

可以通过importScene 属性将QtQuick3D 场景导入图中。该场景可以由包含在根Node中的Models、Light、reflection probes 以及其他Node组成。在本例中,仅添加了一个带有不透明度贴图的矩形:

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"
                }
            }
        ]
    }
}

使用 QtQuick3D 更改外观

要定位ExtendedSceneEnvironment ,需要进行以下导入:

import QtQuick3D.Helpers

要覆盖图形的默认场景环境,需通过ExtendedSceneEnvironment 添加environment 属性。在此示例中,已设置backgroundMode 、clearColor 和tonemapMode 。此外,还启用了glow 。若要添加发光等后期处理效果,需将色调映射模式设置为TonemapModeNone 。

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

为了增强光晕效果,还设置了其他几个相关属性。

示例项目 @ code.qt.io

© 2026 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.