qt使用q3dsurface绘制三维曲面图

一. 内容简介

在QT中使用Q3Dsurface绘制三维图。项目需要,而大部分教程都是比较简单的绘制,不能满足需求,本教程将三维数组数据绘制成三维曲面,在绘制三维曲面时,我原本以为是给入数据,然后由框架拟合出曲面,其实不是,本质上是一个一个点连接的,需要按顺序连接好节点,即一行一列连接,否则曲面就会看不出形状。

二. 软件环境

2.1QT 5.14.1

QT编译器采用的是MSVC2017 64bit

2.2文中测试代码

链接:https://pan.baidu.com/s/1fSvwg6eJzUocXh2vg_clkQ?pwd=1234

三.主要流程

3.1pro文件中添加相关组件

3.2搭建三维显示模块

3.3填入相关数据

3.4其他设置

3.5结果展示

3.6点击按钮更改图象数据以及样式

3.7案例补充

3.8三维样式美化

3.9多次绘制三维图,程序闪退问题

四.具体步骤

4.1pro文件中添加相关组件

Q3Dsurface属于datavisualizationd组件,需要添加相应配置

// pro文件添加
QT       += datavisualization
// 头文件添加
#include 
#include 
// 更新一下,还得加两个东西
// 这个是布局用的
#include 
// 不加这个会报错,定义的变量
using namespace QtDataVisualization;
// 头文件还要把变量给定义上,方便后边改图的数据
QSurface3DSeries *series;
Q3DSurface *groupBox;
QSurfaceDataArray * dataArray;

4.2搭建三维显示模块

	// 这个写完,三维的结构就有了
    groupBox = new Q3DSurface;
    groupBox->axisX()->setTitle("X轴");
    groupBox->axisY()->setTitle("Y轴");
    groupBox->axisZ()->setTitle("Z轴");
    groupBox->axisY()->setRange(-5,10);
    groupBox->axisX()->setRange(-11,11);
    groupBox->axisZ()->setRange(-11,11);

    //将三维图与数据进行绑定
    QSurfaceDataProxy * proxy = new QSurfaceDataProxy;
    series = new QSurface3DSeries(proxy);
    /// 这个就已经将数据和图绑定了,后边更改图数据时候,直接改series即可
    groupBox->addSeries(series);

    QVBoxLayout* vLayout = new QVBoxLayout();
    // 还有这个地方,是将groupBox和vLayout绑定到一起,直接改groupBox,页面里面的三维图也会跟着改变的
    vLayout->addWidget(createWindowContainer(groupBox));
    ui->widget->setLayout(vLayout);
    dataArray = new QSurfaceDataArray;

4.3填入相关数据

这块按照自己的三维数组的数据,x,y,z填入,但是QT三维图轴顺序和正常不一样,需要改下数据顺序。
墨西哥草帽数据

    int N = 41;
    dataArray->reserve(N);
    float x=-10,y,z;
    int i,j;
    for(i = 1;i <= N;i++){
         QSurfaceDataRow *newRow = new QSurfaceDataRow(N);
         y = -10;
         int index = 0;
         for(j=1;j<=N;j++){
             z=qSqrt(x*x+y*y);
             if(z!=0)
                 z=10*qSin(z)/z;
             else
                 z=10;
             (*newRow)[index++].setPosition(QVector3D(x,z,y));
             y=y+0.5;
             
         }
         x=x+0.5;
         *dataArray<<newRow;
    }
    series->dataProxy()->resetArray(dataArray);

qt使用q3dsurface绘制三维曲面图_第1张图片

感觉qt这个绘图是把opengl做了一个封装的

	QSurfaceDataArray * dataArray_p = new QSurfaceDataArray;
    //数据
    int N = 73;//根据行进行设置
    int M =73;//根据列进行设置
	// 行列设置不好的话,图像会扭曲
    dataArray_p->reserve(N);
    int i,j;
    for(i = 1;i <= N;i++){
         QSurfaceDataRow *newRow = new QSurfaceDataRow(M);
         int index = 0;
         for(j=1;j<=M;j++){
             //QT三维图绘制,轴并不是按照x,y,z这个顺序走的,具体怎么走的可以试试,中间是数据常规的z轴
             (*newRow)[index++].setPosition(QVector3D(i,out_p[i][j],j));
         }
         *dataArray_p<<newRow;
    }
    series_p->dataProxy()->resetArray(dataArray_p);

再放一个,数组好像是7272,还是7373,可以试试

        dataArray->clear();
        content_img->axisY()->setRange(min - min * 0.01, max + max * 0.01);
        content_img->axisX()->setRange(0, N + 1 + 1);
        content_img->axisZ()->setRange(0, N + 1 + 1);
        // 按行列填数据
        int NN = N + 1;
        dataArray->reserve(NN);
        for (int i = 1; i <= NN; i++)
        {
            QSurfaceDataRow *newRow = new QSurfaceDataRow(NN);
            int index = 0;
            for (int j = 1; j <= NN; j++)
            {
                (*newRow)[index++].setPosition(QVector3D(i, out_h[i][j], j));
            }
            *dataArray << newRow;
        }
        // 更新数据
        series->dataProxy()->resetArray(dataArray);
        ui->bottom_console->appendPlainText(QString("气膜厚度 最大值: %1,最小值: %2.").arg(max).arg(min));

4.4其他设置

设置渐变

    QLinearGradient gr;
   gr.setColorAt(0.0, QColor(247, 41, 0));
   gr.setColorAt(0.25, QColor(212, 168, 0));
   gr.setColorAt(0.50, QColor(12, 235, 13));
   gr.setColorAt(0.75, QColor(0, 134, 212));
   gr.setColorAt(1.0, QColor(174, 15, 245));
   content_img->seriesList().at(0)->setBaseGradient(gr);
   content_img->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);

qt使用q3dsurface绘制三维曲面图_第2张图片

设置曲面样式

    series_p->setDrawMode(QSurface3DSeries::DrawFlags(2));

如果ui文件更改了,编译却没有更新,重新构建将出问题的这个ui_widget.h备份后删除,并将之前编译产生的release/debug文件夹以及.pro.user文件都删除,然后重新打开qt,清理项目,重新qmake。

4.5结果展示

数据用自己的数据绘制就好,数据不太方便展示,就拿墨西哥草帽展示吧,
qt使用q3dsurface绘制三维曲面图_第3张图片
这种不全的情况就是范围给小了,设定范围要比值稍微大一点点,就可以了,
qt使用q3dsurface绘制三维曲面图_第4张图片

      groupBox_h_3D->axisY()->setRange(-5,10);
      groupBox_h_3D->axisX()->setRange(-11,11);
      groupBox_h_3D->axisZ()->setRange(-11,11);

qt使用q3dsurface绘制三维曲面图_第5张图片

4.6点击按钮更改图象数据以及样式

这个是后加的,头文件加的东西都在上边,下边代码我是写在mainwindow构造函数里面的

    groupBox = new Q3DSurface;
    groupBox->axisX()->setTitle("X轴");
    groupBox->axisY()->setTitle("Y轴");
    groupBox->axisZ()->setTitle("Z轴");
    groupBox->axisY()->setRange(-5,10);
    groupBox->axisX()->setRange(-11,11);
    groupBox->axisZ()->setRange(-11,11);

    //将三维图与数据进行绑定
    QSurfaceDataProxy * proxy = new QSurfaceDataProxy;
    series = new QSurface3DSeries(proxy);
    groupBox->addSeries(series);
    //将三维图在组中显示,布局如果需要的话,在添加一个 #include 
    QVBoxLayout* vLayout = new QVBoxLayout();
    vLayout->addWidget(createWindowContainer(groupBox));
    ui->widget->setLayout(vLayout);
    dataArray = new QSurfaceDataArray;

    
    int N = 41;
    dataArray->reserve(N);
    float x=-10,y,z;
    int i,j;
    for(i = 1;i <= N;i++){
         QSurfaceDataRow *newRow = new QSurfaceDataRow(N);
         y = -10;
         int index = 0;
         for(j=1;j<=N;j++){
             z=qSqrt(x*x+y*y);
             if(z!=0)
                 z=10*qSin(z)/z;
             else
                 z=10;
             (*newRow)[index++].setPosition(QVector3D(x,z,y));
             y=y+0.5;
             
         }
         x=x+0.5;
         *dataArray<<newRow;
    }
    series->dataProxy()->resetArray(dataArray);

执行代码

qt使用q3dsurface绘制三维曲面图_第6张图片
然后开始写按钮事件,比较简单,看下意思,类比一下就好了

void MainWindow::on_pushButton_clicked()
{
	// 这个clear是必写的,写在开头,把dataArray数据清一下,不然很容易程序异常退出,还不好找问题
    dataArray->clear();

	// 这个地方是更改图的尺寸,就上面说的,已经绑定在一起了,直接改就可以了
    groupBox->axisY()->setRange(-5,300);
    
    // 这块的数据就假装换了吧,重新给series换下数据
    int N = 41;
    dataArray->reserve(N);
    float x=-10,y,z;
    int i,j;
    for(i = 1;i <= N;i++){
         QSurfaceDataRow *newRow = new QSurfaceDataRow(N);
         y = -10;
         int index = 0;
         for(j=1;j<=N;j++){
             z=qSqrt(x*x+y*y);
             if(z!=0)
                 z=10*qSin(z)/z;
             else
                 z=10;
             (*newRow)[index++].setPosition(QVector3D(x,z,y));
             y=y+0.5;
         }
         x=x+0.5;
         *dataArray<<newRow;
    }
    series->dataProxy()->resetArray(dataArray);
}

执行,然后点击按钮
qt使用q3dsurface绘制三维曲面图_第7张图片
基本上修改图的数据和结构就没问题了,剩下的就根据需要填数据和更改图的信息了。

4.7案例补充

来自评论区的数据
头文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 
#include "data.h"
using namespace QtDataVisualization;
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
public:
    QSurface3DSeries *series;
    Q3DSurface *groupBox;
    QSurfaceDataArray * dataArray;
    double points[442][3] = {
     {-3.000000 ,-3.000000 ,0.000068},
     {-3.000000 ,-2.700000 ,0.000293},
     {-3.000000 ,-2.400000 ,0.001005},
     {-3.000000 ,-2.100000 ,0.002641},
     {-3.000000 ,-1.800000 ,0.004862},
     {-3.000000 ,-1.500000 ,0.004188},
     {-3.000000 ,-1.200000 ,-0.008477},
     {-3.000000 ,-0.900000 ,-0.045467},
     {-3.000000 ,-0.600000 ,-0.111168},
     {-3.000000 ,-0.300000 ,-0.189170},
     {-3.000000 ,0.000000 ,-0.244939},
     {-3.000000 ,0.300000 ,-0.249505},
     {-3.000000 ,0.600000 ,-0.203007},
     {-3.000000 ,0.900000 ,-0.132861},
     {-3.000000 ,1.200000 ,-0.070095},
     {-3.000000 ,1.500000 ,-0.029760},
     {-3.000000 ,1.800000 ,-0.010103},
     {-3.000000 ,2.100000 ,-0.002704},
     {-3.000000 ,2.400000 ,-0.000554},
     {-3.000000 ,2.700000 ,-0.000080},
     {-3.000000 ,3.000000 ,-0.000006},
     {-2.700000 ,-3.000000 ,0.000186},
     {-2.700000 ,-2.700000 ,0.000800},
     {-2.700000 ,-2.400000 ,0.002701},
     {-2.700000 ,-2.100000 ,0.006842},
     {-2.700000 ,-1.800000 ,0.011387},
     {-2.700000 ,-1.500000 ,0.004427},
     {-2.700000 ,-1.200000 ,-0.043181},
     {-2.700000 ,-0.900000 ,-0.169456},
     {-2.700000 ,-0.600000 ,-0.385742},
     {-2.700000 ,-0.300000 ,-0.637074},
     {-2.700000 ,0.000000 ,-0.812338},
     {-2.700000 ,0.300000 ,-0.820339},
     {-2.700000 ,0.600000 ,-0.664003},
     {-2.700000 ,0.900000 ,-0.433137},
     {-2.700000 ,1.200000 ,-0.227982},
     {-2.700000 ,1.500000 ,-0.096588},
     {-2.700000 ,1.800000 ,-0.032703},
     {-2.700000 ,2.100000 ,-0.008715},
     {-2.700000 ,2.400000 ,-0.001768},
     {-2.700000 ,2.700000 ,-0.000250},
     {-2.700000 ,3.000000 ,-0.000016},
     {-2.400000 ,-3.000000 ,0.000422},
     {-2.400000 ,-2.700000 ,0.001824},
     {-2.400000 ,-2.400000 ,0.006162},
     {-2.400000 ,-2.100000 ,0.015477},
     {-2.400000 ,-1.800000 ,0.024730},
     {-2.400000 ,-1.500000 ,0.003698},
     {-2.400000 ,-1.200000 ,-0.121008},
     {-2.400000 ,-0.900000 ,-0.445265},
     {-2.400000 ,-0.600000 ,-0.997917},
     {-2.400000 ,-0.300000 ,-1.639519},
     {-2.400000 ,0.000000 ,-2.086536},
     {-2.400000 ,0.300000 ,-2.104865},
     {-2.400000 ,0.600000 ,-1.701265},
     {-2.400000 ,0.900000 ,-1.106622},
     {-2.400000 ,1.200000 ,-0.579364},
     {-2.400000 ,1.500000 ,-0.243111},
     {-2.400000 ,1.800000 ,-0.080922},
     {-2.400000 ,2.100000 ,-0.020897},
     {-2.400000 ,2.400000 ,-0.003972},
     {-2.400000 ,2.700000 ,-0.000467},
     {-2.400000 ,3.000000 ,0.000002},
     {-2.100000 ,-3.000000 ,0.000758},
     {-2.100000 ,-2.700000 ,0.003381},
     {-2.100000 ,-2.400000 ,0.011833},
     {-2.100000 ,-2.100000 ,0.031094},
     {-2.100000 ,-1.800000 ,0.054210},
     {-2.100000 ,-1.500000 ,0.026680},
     {-2.100000 ,-1.200000 ,-0.193177},
     {-2.100000 ,-0.900000 ,-0.801436},
     {-2.100000 ,-0.600000 ,-1.873828},
     {-2.100000 ,-0.300000 ,-3.151625},
     {-2.100000 ,0.000000 ,-4.069706},
     {-2.100000 ,0.300000 ,-4.140071},
     {-2.100000 ,0.600000 ,-3.355470},
     {-2.100000 ,0.900000 ,-2.174742},
     {-2.100000 ,1.200000 ,-1.124849},
     {-2.100000 ,1.500000 ,-0.460265},
     {-2.100000 ,1.800000 ,-0.145949},
     {-2.100000 ,2.100000 ,-0.034122},
     {-2.100000 ,2.400000 ,-0.005007},
     {-2.100000 ,2.700000 ,-0.000036},
     {-2.100000 ,3.000000 ,0.000225},
     {-1.800000 ,-3.000000 ,0.000934},
     {-1.800000 ,-2.700000 ,0.004611},
     {-1.800000 ,-2.400000 ,0.017836},
     {-1.800000 ,-2.100000 ,0.052742},
     {-1.800000 ,-1.800000 ,0.111953},
     {-1.800000 ,-1.500000 ,0.135139},
     {-1.800000 ,-1.200000 ,-0.077418},
     {-1.800000 ,-0.900000 ,-0.847329},
     {-1.800000 ,-0.600000 ,-2.363920},
     {-1.800000 ,-0.300000 ,-4.308261},
     {-1.800000 ,0.000000 ,-5.818408},
     {-1.800000 ,0.300000 ,-6.066756},
     {-1.800000 ,0.600000 ,-4.960190},
     {-1.800000 ,0.900000 ,-3.189389},
     {-1.800000 ,1.200000 ,-1.600269},
     {-1.800000 ,1.500000 ,-0.611370},
     {-1.800000 ,1.800000 ,-0.166244},
     {-1.800000 ,2.100000 ,-0.024599},
     {-1.800000 ,2.400000 ,0.002919},
     {-1.800000 ,2.700000 ,0.003185},
     {-1.800000 ,3.000000 ,0.001144},
     {-1.500000 ,-3.000000 ,0.000192},
     {-1.500000 ,-2.700000 ,0.002596},
     {-1.500000 ,-2.400000 ,0.015568},
     {-1.500000 ,-2.100000 ,0.062365},
     {-1.500000 ,-1.800000 ,0.178047},
     {-1.500000 ,-1.500000 ,0.353903},
     {-1.500000 ,-1.200000 ,0.411329},
     {-1.500000 ,-0.900000 ,-0.065832},
     {-1.500000 ,-0.600000 ,-1.481688},
     {-1.500000 ,-0.300000 ,-3.674417},
     {-1.500000 ,0.000000 ,-5.667352},
     {-1.500000 ,0.300000 ,-6.300365},
     {-1.500000 ,0.600000 ,-5.252627},
     {-1.500000 ,0.900000 ,-3.292726},
     {-1.500000 ,1.200000 ,-1.502585},
     {-1.500000 ,1.500000 ,-0.440424},
     {-1.500000 ,1.800000 ,-0.029021},
     {-1.500000 ,2.100000 ,0.050342},
     {-1.500000 ,2.400000 ,0.033528},
     {-1.500000 ,2.700000 ,0.012913},
     {-1.500000 ,3.000000 ,0.003600},
     {-1.200000 ,-3.000000 ,-0.002755},
     {-1.200000 ,-2.700000 ,-0.008045},
     {-1.200000 ,-2.400000 ,-0.013206},
     {-1.200000 ,-2.100000 ,0.010420},
     {-1.200000 ,-1.800000 ,0.146377},
     {-1.200000 ,-1.500000 ,0.509474},
     {-1.200000 ,-1.200000 ,1.073202},
     {-1.200000 ,-0.900000 ,1.427592},
     {-1.200000 ,-0.600000 ,0.876206},
     {-1.200000 ,-0.300000 ,-0.864700},
     {-1.200000 ,0.000000 ,-3.013152},
     {-1.200000 ,0.300000 ,-4.168756},
     {-1.200000 ,0.600000 ,-3.632724},
     {-1.200000 ,0.900000 ,-2.031204},
     {-1.200000 ,1.200000 ,-0.534210},
     {-1.200000 ,1.500000 ,0.222456},
     {-1.200000 ,1.800000 ,0.349102},
     {-1.200000 ,2.100000 ,0.225344},
     {-1.200000 ,2.400000 ,0.098849},
     {-1.200000 ,2.700000 ,0.032608},
     {-1.200000 ,3.000000 ,0.008414},
     {-0.900000 ,-3.000000 ,-0.008953},
     {-0.900000 ,-2.700000 ,-0.032154},
     {-0.900000 ,-2.400000 ,-0.087140},
     {-0.900000 ,-2.100000 ,-0.163045},
     {-0.900000 ,-1.800000 ,-0.144261},
     {-0.900000 ,-1.500000 ,0.237908},
     {-0.900000 ,-1.200000 ,1.215248},
     {-0.900000 ,-0.900000 ,2.514839},
     {-0.900000 ,-0.600000 ,3.174202},
     {-0.900000 ,-0.300000 ,2.320941},
     {-0.900000 ,0.000000 ,0.343307},
     {-0.900000 ,0.300000 ,-1.204810},
     {-0.900000 ,0.600000 ,-1.203180},
     {-0.900000 ,0.900000 ,-0.068894},
     {-0.900000 ,1.200000 ,0.974118},
     {-0.900000 ,1.500000 ,1.243193},
     {-0.900000 ,1.800000 ,0.924921},
     {-0.900000 ,2.100000 ,0.489816},
     {-0.900000 ,2.400000 ,0.197123},
     {-0.900000 ,2.700000 ,0.062171},
     {-0.900000 ,3.000000 ,0.015636},
     {-0.600000 ,-3.000000 ,-0.017750},
     {-0.600000 ,-2.700000 ,-0.067619},
     {-0.600000 ,-2.400000 ,-0.201949},
     {-0.600000 ,-2.100000 ,-0.457725},
     {-0.600000 ,-1.800000 ,-0.731462},
     {-0.600000 ,-1.500000 ,-0.634331},
     {-0.600000 ,-1.200000 ,0.343353},
     {-0.600000 ,-0.900000 ,2.160214},
     {-0.600000 ,-0.600000 ,3.720137},
     {-0.600000 ,-0.300000 ,3.663117},
     {-0.600000 ,0.000000 ,2.013918},
     {-0.600000 ,0.300000 ,0.438600},
     {-0.600000 ,0.600000 ,0.374154},
     {-0.600000 ,0.900000 ,1.473947},
     {-0.600000 ,1.200000 ,2.355339},
     {-0.600000 ,1.500000 ,2.271368},
     {-0.600000 ,1.800000 ,1.537984},
     {-0.600000 ,2.100000 ,0.780755},
     {-0.600000 ,2.400000 ,0.307441},
     {-0.600000 ,2.700000 ,0.095800},
     {-0.600000 ,3.000000 ,0.023925},
     {-0.300000 ,-3.000000 ,-0.026150},
     {-0.300000 ,-2.700000 ,-0.102223},
     {-0.300000 ,-2.400000 ,-0.317416},
     {-0.300000 ,-2.100000 ,-0.767732},
     {-0.300000 ,-1.800000 ,-1.395157},
     {-0.300000 ,-1.500000 ,-1.753722},
     {-0.300000 ,-1.200000 ,-1.119761},
     {-0.300000 ,-0.900000 ,0.709572},
     {-0.300000 ,-0.600000 ,2.654929},
     {-0.300000 ,-0.300000 ,3.094026},
     {-0.300000 ,0.000000 ,1.815670},
     {-0.300000 ,0.300000 ,0.527114},
     {-0.300000 ,0.600000 ,0.801788},
     {-0.300000 ,0.900000 ,2.230365},
     {-0.300000 ,1.200000 ,3.234207},
     {-0.300000 ,1.500000 ,3.008162},
     {-0.300000 ,1.800000 ,2.003795},
     {-0.300000 ,2.100000 ,1.008907},
     {-0.300000 ,2.400000 ,0.395575},
     {-0.300000 ,2.700000 ,0.122985},
     {-0.300000 ,3.000000 ,0.030681},
     {0.000000 ,-3.000000 ,-0.030401},
     {0.000000 ,-2.700000 ,-0.120309},
     {0.000000 ,-2.400000 ,-0.380282},
     {0.000000 ,-2.100000 ,-0.945722},
     {0.000000 ,-1.800000 ,-1.804182},
     {0.000000 ,-1.500000 ,-2.514010},
     {0.000000 ,-1.200000 ,-2.259910},
     {0.000000 ,-0.900000 ,-0.669896},
     {0.000000 ,-0.600000 ,1.301386},
     {0.000000 ,-0.300000 ,2.006214},
     {0.000000 ,0.000000 ,1.103638},
     {0.000000 ,0.300000 ,0.192641},
     {0.000000 ,0.600000 ,0.792967},
     {0.000000 ,0.900000 ,2.447181},
     {0.000000 ,1.200000 ,3.535944},
     {0.000000 ,1.500000 ,3.270106},
     {0.000000 ,1.800000 ,2.170710},
     {0.000000 ,2.100000 ,1.090871},
     {0.000000 ,2.400000 ,0.427301},
     {0.000000 ,2.700000 ,0.132794},
     {0.000000 ,3.000000 ,0.033125},
     {0.300000 ,-3.000000 ,-0.028680},
     {0.300000 ,-2.700000 ,-0.114190},
     {0.300000 ,-2.400000 ,-0.364059},
     {0.300000 ,-2.100000 ,-0.917215},
     {0.300000 ,-1.800000 ,-1.787762},
     {0.300000 ,-1.500000 ,-2.595080},
     {0.300000 ,-1.200000 ,-2.582006},
     {0.300000 ,-0.900000 ,-1.333207},
     {0.300000 ,-0.600000 ,0.392056},
     {0.300000 ,-0.300000 ,1.150931},
     {0.300000 ,0.000000 ,0.575767},
     {0.300000 ,0.300000 ,-0.007444},
     {0.300000 ,0.600000 ,0.689411},
     {0.300000 ,0.900000 ,2.244410},
     {0.300000 ,1.200000 ,3.232559},
     {0.300000 ,1.500000 ,2.979001},
     {0.300000 ,1.800000 ,1.973343},
     {0.300000 ,2.100000 ,0.990557},
     {0.300000 ,2.400000 ,0.387782},
     {0.300000 ,2.700000 ,0.120483},
     {0.300000 ,3.000000 ,0.030052},
     {0.600000 ,-3.000000 ,-0.022206},
     {0.600000 ,-2.700000 ,-0.088593},
     {0.600000 ,-2.400000 ,-0.283204},
     {0.600000 ,-2.100000 ,-0.716066},
     {0.600000 ,-1.800000 ,-1.402699},
     {0.600000 ,-1.500000 ,-2.051234},
     {0.600000 ,-1.200000 ,-2.065167},
     {0.600000 ,-0.900000 ,-1.090133},
     {0.600000 ,-0.600000 ,0.325428},
     {0.600000 ,-0.300000 ,1.064439},
     {0.600000 ,0.000000 ,0.774428},
     {0.600000 ,0.300000 ,0.389260},
     {0.600000 ,0.600000 ,0.871670},
     {0.600000 ,0.900000 ,1.946288},
     {0.600000 ,1.200000 ,2.590382},
     {0.600000 ,1.500000 ,2.324478},
     {0.600000 ,1.800000 ,1.522213},
     {0.600000 ,2.100000 ,0.759755},
     {0.600000 ,2.400000 ,0.296504},
     {0.600000 ,2.700000 ,0.091956},
     {0.600000 ,3.000000 ,0.022912},
     {0.900000 ,-3.000000 ,-0.014009},
     {0.900000 ,-2.700000 ,-0.055556},
     {0.900000 ,-2.400000 ,-0.175822},
     {0.900000 ,-2.100000 ,-0.436652},
     {0.900000 ,-1.800000 ,-0.825556},
     {0.900000 ,-1.500000 ,-1.111468},
     {0.900000 ,-1.200000 ,-0.852904},
     {0.900000 ,-0.900000 ,0.212440},
     {0.900000 ,-0.600000 ,1.679683},
     {0.900000 ,-0.300000 ,2.660271},
     {0.900000 ,0.000000 ,2.707999},
     {0.900000 ,0.300000 ,2.302930},
     {0.900000 ,0.600000 ,2.139698},
     {0.900000 ,0.900000 ,2.255397},
     {0.900000 ,1.200000 ,2.191481},
     {0.900000 ,1.500000 ,1.720801},
     {0.900000 ,1.800000 ,1.058263},
     {0.900000 ,2.100000 ,0.511185},
     {0.900000 ,2.400000 ,0.195834},
     {0.900000 ,2.700000 ,0.060059},
     {0.900000 ,3.000000 ,0.014858},
     {1.200000 ,-3.000000 ,-0.006945},
     {1.200000 ,-2.700000 ,-0.026703},
     {1.200000 ,-2.400000 ,-0.080183},
     {1.200000 ,-2.100000 ,-0.180180},
     {1.200000 ,-1.800000 ,-0.269572},
     {1.200000 ,-1.500000 ,-0.130879},
     {1.200000 ,-1.200000 ,0.588730},
     {1.200000 ,-0.900000 ,2.082124},
     {1.200000 ,-0.600000 ,3.996847},
     {1.200000 ,-0.300000 ,5.496197},
     {1.200000 ,0.000000 ,5.919244},
     {1.200000 ,0.300000 ,5.327268},
     {1.200000 ,0.600000 ,4.274501},
     {1.200000 ,0.900000 ,3.201417},
     {1.200000 ,1.200000 ,2.232322},
     {1.200000 ,1.500000 ,1.389897},
     {1.200000 ,1.800000 ,0.739233},
     {1.200000 ,2.100000 ,0.326622},
     {1.200000 ,2.400000 ,0.118348},
     {1.200000 ,2.700000 ,0.035016},
     {1.200000 ,3.000000 ,0.008458},
     {1.500000 ,-3.000000 ,-0.002435},
     {1.500000 ,-2.700000 ,-0.008252},
     {1.500000 ,-2.400000 ,-0.018887},
     {1.500000 ,-2.100000 ,-0.015303},
     {1.500000 ,-1.800000 ,0.089361},
     {1.500000 ,-1.500000 ,0.505803},
     {1.500000 ,-1.200000 ,1.531370},
     {1.500000 ,-0.900000 ,3.312423},
     {1.500000 ,-0.600000 ,5.523781},
     {1.500000 ,-0.300000 ,7.355614},
     {1.500000 ,0.000000 ,8.009545},
     {1.500000 ,0.300000 ,7.285686},
     {1.500000 ,0.600000 ,5.655269},
     {1.500000 ,0.900000 ,3.817973},
     {1.500000 ,1.200000 ,2.267949},
     {1.500000 ,1.500000 ,1.185343},
     {1.500000 ,1.800000 ,0.539478},
     {1.500000 ,2.100000 ,0.210638},
     {1.500000 ,2.400000 ,0.069575},
     {1.500000 ,2.700000 ,0.019240},
     {1.500000 ,3.000000 ,0.004425},
     {1.800000 ,-3.000000 ,-0.000360},
     {1.800000 ,-2.700000 ,-0.000055},
     {1.800000 ,-2.400000 ,0.006894},
     {1.800000 ,-2.100000 ,0.048003},
     {1.800000 ,-1.800000 ,0.206257},
     {1.800000 ,-1.500000 ,0.653831},
     {1.800000 ,-1.200000 ,1.616615},
     {1.800000 ,-0.900000 ,3.198324},
     {1.800000 ,-0.600000 ,5.138882},
     {1.800000 ,-0.300000 ,6.776986},
     {1.800000 ,0.000000 ,7.401464},
     {1.800000 ,0.300000 ,6.752066},
     {1.800000 ,0.600000 ,5.189364},
     {1.800000 ,0.900000 ,3.387729},
     {1.800000 ,1.200000 ,1.891415},
     {1.800000 ,1.500000 ,0.906946},
     {1.800000 ,1.800000 ,0.373783},
     {1.800000 ,2.100000 ,0.132056},
     {1.800000 ,2.400000 ,0.039794},
     {1.800000 ,2.700000 ,0.010167},
     {1.800000 ,3.000000 ,0.002190},
     {2.100000 ,-3.000000 ,0.000217},
     {2.100000 ,-2.700000 ,0.001801},
     {2.100000 ,-2.400000 ,0.010539},
     {2.100000 ,-2.100000 ,0.047303},
     {2.100000 ,-1.800000 ,0.168434},
     {2.100000 ,-1.500000 ,0.483970},
     {2.100000 ,-1.200000 ,1.133558},
     {2.100000 ,-0.900000 ,2.179044},
     {2.100000 ,-0.600000 ,3.455691},
     {2.100000 ,-0.300000 ,4.541002},
     {2.100000 ,0.000000 ,4.964498},
     {2.100000 ,0.300000 ,4.533449},
     {2.100000 ,0.600000 ,3.471635},
     {2.100000 ,0.900000 ,2.238094},
     {2.100000 ,1.200000 ,1.219034},
     {2.100000 ,1.500000 ,0.562633},
     {2.100000 ,1.800000 ,0.220475},
     {2.100000 ,2.100000 ,0.073407},
     {2.100000 ,2.400000 ,0.020755},
     {2.100000 ,2.700000 ,0.004975},
     {2.100000 ,3.000000 ,0.001009},
     {2.400000 ,-3.000000 ,0.000207},
     {2.400000 ,-2.700000 ,0.001301},
     {2.400000 ,-2.400000 ,0.006583},
     {2.400000 ,-2.100000 ,0.027116},
     {2.400000 ,-1.800000 ,0.091522},
     {2.400000 ,-1.500000 ,0.254264},
     {2.400000 ,-1.200000 ,0.583402},
     {2.400000 ,-0.900000 ,1.108549},
     {2.400000 ,-0.600000 ,1.748488},
     {2.400000 ,-0.300000 ,2.294150},
     {2.400000 ,0.000000 ,2.509140},
     {2.400000 ,0.300000 ,2.292217},
     {2.400000 ,0.600000 ,1.752661},
     {2.400000 ,0.900000 ,1.123894},
     {2.400000 ,1.200000 ,0.605587},
     {2.400000 ,1.500000 ,0.274672},
     {2.400000 ,1.800000 ,0.105020},
     {2.400000 ,2.100000 ,0.033885},
     {2.400000 ,2.400000 ,0.009232},
     {2.400000 ,2.700000 ,0.002124},
     {2.400000 ,3.000000 ,0.000412},
     {2.700000 ,-3.000000 ,0.000099},
     {2.700000 ,-2.700000 ,0.000579},
     {2.700000 ,-2.400000 ,0.002798},
     {2.700000 ,-2.100000 ,0.011168},
     {2.700000 ,-1.800000 ,0.036883},
     {2.700000 ,-1.500000 ,0.100984},
     {2.700000 ,-1.200000 ,0.229566},
     {2.700000 ,-0.900000 ,0.433884},
     {2.700000 ,-0.600000 ,0.682620},
     {2.700000 ,-0.300000 ,0.895009},
     {2.700000 ,0.000000 ,0.979069},
     {2.700000 ,0.300000 ,0.894594},
     {2.700000 ,0.600000 ,0.683528},
     {2.700000 ,0.900000 ,0.437211},
     {2.700000 ,1.200000 ,0.234373},
     {2.700000 ,1.500000 ,0.105404},
     {2.700000 ,1.800000 ,0.039806},
     {2.700000 ,2.100000 ,0.012634},
     {2.700000 ,2.400000 ,0.003372},
     {2.700000 ,2.700000 ,0.000757},
     {2.700000 ,3.000000 ,0.000143},
     {3.000000 ,-3.000000 ,0.000033},
     {3.000000 ,-2.700000 ,0.000189},
     {3.000000 ,-2.400000 ,0.000893},
     {3.000000 ,-2.100000 ,0.003513},
     {3.000000 ,-1.800000 ,0.011480},
     {3.000000 ,-1.500000 ,0.031208},
     {3.000000 ,-1.200000 ,0.070617},
     {3.000000 ,-0.900000 ,0.133106},
     {3.000000 ,-0.600000 ,0.209141},
     {3.000000 ,-0.300000 ,0.274112},
     {3.000000 ,0.000000 ,0.299886},
     {3.000000 ,0.300000 ,0.274038},
     {3.000000 ,0.600000 ,0.209306},
     {3.000000 ,0.900000 ,0.133708},
     {3.000000 ,1.200000 ,0.071486},
     {3.000000 ,1.500000 ,0.032008},
     {3.000000 ,1.800000 ,0.012009},
     {3.000000 ,2.100000 ,0.003778},
     {3.000000 ,2.400000 ,0.000997},
     {3.000000 ,2.700000 ,0.000221},
     {3.000000 ,3.000000 ,0.000041}
    };
private slots:
    void on_pushButton_clicked();
    void on_pushButton_2_clicked();
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

cpp代码

    groupBox = new Q3DSurface;
    groupBox->axisX()->setTitle("X轴");
    groupBox->axisY()->setTitle("Y轴");
    groupBox->axisZ()->setTitle("Z轴");
    groupBox->axisY()->setRange(-8,8);

    //将三维图与数据进行绑定
    QSurfaceDataProxy * proxy = new QSurfaceDataProxy;
    series = new QSurface3DSeries(proxy);
    groupBox->addSeries(series);
    //将三维图在组中显示,布局如果需要的话,在添加一个 #include 
    QVBoxLayout* vLayout = new QVBoxLayout();
    vLayout->addWidget(createWindowContainer(groupBox));
    ui->widget->setLayout(vLayout);
    dataArray = new QSurfaceDataArray;
    dataArray->clear();
    QLinearGradient gr;
    gr.setColorAt(0.0, Qt::darkGreen);
    gr.setColorAt(0.5, Qt::yellow);
    gr.setColorAt(0.8, Qt::red);
    gr.setColorAt(1.0, Qt::darkRed);
    groupBox->seriesList().at(0)->setBaseGradient(gr);
    groupBox->seriesList().at(0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
    // 整个数据有442个,我取了420个,分为22x20,就22行,20列,
    
    int NN = 21;//设置行
    //放上边会卡死,不道为啥
    groupBox->axisX()->setRange(-3.5,3.5);
    groupBox->axisZ()->setRange(-3.5,3.5);
    dataArray->reserve(NN);
    for(int i = 0;i <= NN;i++){
         QSurfaceDataRow *newRow = new QSurfaceDataRow(20);
         int index = 0;
         // 19是列
         for(int j=0;j<=19;j++){
             (*newRow)[index++].setPosition(QVector3D(points[j+i*NN][0],points[j+i*NN][2],points[j+i*NN][1]));
         }
         *dataArray<<newRow;
    }
    series->dataProxy()->resetArray(dataArray);

结果展示。
qt使用q3dsurface绘制三维曲面图_第8张图片

4.8三维样式美化

样式就可以直接拿这个拷一下,三维图看着会好看一些,我代码其他地方还在调,就不让我自己的图,样式就和这个差不多,这个图是QT里面的例子,代码也是从里面拿的。

    // h表
    // 下面是处理 content_img_h
    content_img_h = new Q3DSurface;
    // 设置阴影的,之前没有这个,没有出图时是有阴影的
    content_img_h->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftMedium);
    // 主题相关
    content_img_h->activeTheme()->setBackgroundEnabled(false);
    content_img_h->activeTheme()->setFont(QFont("Times New Roman", 60));
    content_img_h->activeTheme()->setLabelBackgroundEnabled(true);

    content_img_h->axisY()->setTitle("无量纲膜厚");
//    content_img_h->axisY()->setSegmentCount(4);
//    content_img_h->axisY()->setSubSegmentCount(3);
//    content_img_h->axisY()->setRange(-20.0f, 20.0f);
    content_img_h->axisY()->setAutoAdjustRange(true); //自动调整y轴范围
    content_img_h->axisY()->setLabelFormat(QString(QStringLiteral("%.3f ") + ""));
    content_img_h->axisY()->setLabelAutoRotation(30.0f);
    content_img_h->axisY()->setTitleVisible(true); //显示y轴标题
    content_img_h->axisY()->setTitleFixed(true); //固定y轴标题位置


    content_img_h->axisX()->setTitle("周向");
    content_img_h->axisX()->setLabelAutoRotation(30.0f);
    content_img_h->axisX()->setTitleVisible(true);
    content_img_h->axisX()->setLabelFormat(QString(QStringLiteral("%.0f ")));

    content_img_h->axisZ()->setTitle("轴向");
    content_img_h->axisZ()->setLabelAutoRotation(30.0f);
    content_img_h->axisZ()->setTitleVisible(true);
    content_img_h->axisZ()->setLabelFormat(QString(QStringLiteral("%.0f ")));
    content_img_h->scene()->activeCamera()->setCameraPosition(-45.0f, 0.0f,0.0f);
    content_img_h->scene()->activeCamera()->setZoomLevel(80);

qt使用q3dsurface绘制三维曲面图_第9张图片

4.9多次绘制三维图,程序闪退问题

多次绘制三维图程序闪退主要是因为这块代码,官方例子里面也是这样写的,里面每次都new一个newRow对象,如果数据量大的话,就是堆内存就不够了。

        dataArray->reserve(NN);
        for (int i = 1; i <= NN; i++)
        {
            QSurfaceDataRow *newRow = new QSurfaceDataRow(NN);
            int index = 0;
            for (int j = 1; j <= NN; j++)
            {
                (*newRow)[index++].setPosition(QVector3D(i, out_h[i][j], j));
            }
            *dataArray << newRow;
        }

我一开始是想着直接在下面delete newRow,然后会发现图就什么数据都没有了,因为dataArry中存放的就是newRow的地址,如果释放的话,数据就丢了。dataArry中存的不是地址,而是数据地址的位置,所以不能直接释放

        dataArray->reserve(NN);
        for (int i = 1; i <= NN; i++)
        {
            QSurfaceDataRow *newRow = new QSurfaceDataRow(NN);
            int index = 0;
            for (int j = 1; j <= NN; j++)
            {
                (*newRow)[index++].setPosition(QVector3D(i, out_h[i][j], j));
            }
            *dataArray << newRow;
            delete newRow;
        }

然后我是在更新完后做的,释放但是会闪退,我觉着可能是因为series->dataProxy()->resetArray(dataArray);是一个异步处理,在处理时候有一部分内存已经被释放了,所以就闪退了。

        dataArray->reserve(NN);
        for (int i = 1; i <= NN; i++)
        {
            QSurfaceDataRow *newRow = new QSurfaceDataRow(NN);
            int index = 0;
            for (int j = 1; j <= NN; j++)
            {
                (*newRow)[index++].setPosition(QVector3D(i, out_h[i][j], j));
            }
            *dataArray << newRow;
        }
        // 更新数据
        series->dataProxy()->resetArray(dataArray);
        for (int i = 0; i < dataArray->size(); i++) {
            delete dataArray->at(i);
        }

解决办法就,每次写数据前,把上次的释放就可以了

        // 释放之前申请的内存
        for (int i = 0; i < dataArray->size(); i++) {
            delete dataArray->at(i);
        }
        // 清空保存的地址
        dataArray->clear();

        content_img->axisY()->setRange(min - min * 0.01, max + max * 0.01);
        content_img->axisX()->setRange(0, N + 1 + 1);
        content_img->axisZ()->setRange(0, N + 1 + 1);
        // 按行列填数据
        int NN = N + 1;
        dataArray->reserve(NN);
        for (int i = 1; i <= NN; i++)
        {
            QSurfaceDataRow *newRow = new QSurfaceDataRow(NN);
            int index = 0;
            for (int j = 1; j <= NN; j++)
            {
                (*newRow)[index++].setPosition(QVector3D(i, out_h[i][j], j));
            }
            *dataArray << newRow;
        }
        // 更新数据
        series->dataProxy()->resetArray(dataArray);

你可能感兴趣的:(QT,qt,开发语言)