surface 3D绘制动态三维曲面
绘制动态三维曲面的方法有很多,这里介绍使用surface 3D进行绘制
之前我去网络上检索了大量关于:《qt 绘制三维曲面 》的文章,无异于很多文章都是直接搬运的官方demo
- **首先创建一个qt demo,在pro文件中添加qt组件: Qt Data Visualization
QT += datavisualization
- 然后添加相关头文件以及命名空间指令
#include <QtDataVisualization> // QT 可以不用添加这个头文件,但是在vs qt中需要添加,否则会在编译时报错,具体因环境而异
#include <QtDataVisualization/Q3DSurface>
#include <QtDataVisualization/QSurfaceDataProxy>
#include <QtDataVisualization/QHeightMapSurfaceDataProxy>
#include <QtDataVisualization/QSurface3DSeries>
- 接下来就是在main函数入口创建一个三维曲面的容器,以及显示的widget
Q3DSurface* pSurface3D = new Q3DSurface();
QWidget* widget = new QWidget;
- 通过官方demo了解到绘制一个三维曲面时需要有数据对象,然后若要实现动态三维曲面效果还得从绘制的数据进行处理,以下方法是通过使用定时器事件,通过随机数对Y轴数据上的改变,从而实现三维动态效果,
// auto
QTime time;
double tmpY = 0;
for (int m = 0; m < line; m++) {
QSurfaceDataRow* dotData = new QSurfaceDataRow;
for (int n = 0; n < points; n++) { // 把每一条线的每个坐标点 放在一条线中
time = QTime::currentTime();
qsrand(time.msec() * 1000 + time.second() * 1000);
tmpY = qrand() % 50 * 0.001 * srand[m][n];
dotData->push_back(QVector3D(m, tmpY, n));
}
m_pDataArray->append(dotData); // 将所有线的数据追加到dataArray数组中
}
这里在第二个循环里面对time赋值,主要是使得第一个与第二个数据不同,理论上可行,但是每循环一次时间特别短,有可能会使得某连续两次循环的time值一样,如果使用Sleep(1),当曲面的坐标点数据量庞大,这又会导致ui处于假死状态,所以我又使用了srand 100*100的数组随机数,最终效果如下:
https://live.youkuaiyun.com/v/258408
- 这么杂乱的效果,让我们不太容易接受,因为使用的都是随机数,对自己的数据进行绘制动态三维曲面,这才是我的主要目的,于是有了如下的代码:
for (int i = 0; i < line; i++) {
QSurfaceDataRow* dataRow = new QSurfaceDataRow;
for (int j = 0; j < point; j++) {
dataRow->push_back(listData.at(index++)); // 每一条线的所有坐标点
}
m_pDataArray->append(dataRow); // 所有的线绘制成一个曲面
}
但是这里大家就会发现,对自己的数据不断的去追加,三维曲面就不断的增加,但是并感觉不到真正的‘动起来’,可以试试在每一次追加数据重绘前,先将由构成曲面的每条线的第一个坐标点数据清除,这样不就让它动起来了。当然,相信有大佬肯定还有其他更简单的方法,欢迎评论区一起讨论咯。
若本文有不足之处,欢迎大家指正。