最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

Qt開發(fā)技術(shù):Q3D圖表開發(fā)筆記(三):Q3DSurface三維曲面圖介紹、Demo以及代碼詳解

2023-04-20 14:15 作者:紅胖子_AAA紅模仿  | 我要投稿

前言

??qt提供了q3d進(jìn)行三維開發(fā),雖然這個(gè)框架沒有得到大量運(yùn)用也不是那么成功,性能上也有很大的欠缺,但是普通的點(diǎn)到為止的應(yīng)用展示還是可以的。
??其中就包括華麗絢爛的三維圖表,數(shù)據(jù)量不大的時(shí)候是可以使用的。
??前面介紹了基礎(chǔ)的q3d散點(diǎn)圖、柱狀圖,本篇介紹基礎(chǔ)的三維曲面圖。

Demo:Q3DSurface散點(diǎn)圖演示效果

??


??


??

Q3D提供的三維圖表

??依賴QtDataVisualization。在安裝qt的時(shí)候要選擇安裝QtDataVisualization模塊。

Q3DScatter散點(diǎn)圖

??Q3D的散點(diǎn)圖,性能大約支撐1000個(gè)點(diǎn)可以不卡頓,具體依賴pc,1000個(gè)點(diǎn)是什么 概念,可以理解為:10x10x10的區(qū)域,每個(gè)區(qū)域一個(gè)數(shù)據(jù)點(diǎn)。
??

Q3DBars柱狀圖

??Q3D的柱狀圖,性能跟散點(diǎn)圖類似。
???

Q3DSurface平面凹凸圖,平面紋理圖,平面曲線圖

??Q3D的柱狀圖,性能跟散點(diǎn)圖類似。
??

Q3DSurface平面曲線圖

簡介

??Q3DSurface類提供了渲染3D曲面圖的方法。該類使開發(fā)人員能夠渲染3D表面圖,并通過自由旋轉(zhuǎn)場景來查看它們??梢酝ㄟ^QSurface3DSeries控制曲面的視覺財(cái)產(chǎn),例如繪制模式和著色。
??Q3DSurface通過在用戶用鼠標(biāo)左鍵點(diǎn)擊的數(shù)據(jù)點(diǎn)上顯示高亮顯示的球(當(dāng)使用默認(rèn)輸入處理程序時(shí))或通過QSurface3DSeries進(jìn)行選擇來支持選擇。選擇指針附帶一個(gè)標(biāo)簽,在默認(rèn)情況下,該標(biāo)簽顯示數(shù)據(jù)點(diǎn)的值和點(diǎn)的坐標(biāo)。
軸上顯示的值范圍和標(biāo)簽格式可以通過QValue3DAxis進(jìn)行控制。
??要旋轉(zhuǎn)圖形,請(qǐng)按住鼠標(biāo)右鍵并移動(dòng)鼠標(biāo)。縮放是使用鼠標(biāo)滾輪完成的。兩者都假設(shè)默認(rèn)的輸入處理程序正在使用中。
??如果沒有將任何軸明確設(shè)置為Q3DSurface,則會(huì)創(chuàng)建不帶標(biāo)簽的臨時(shí)默認(rèn)軸。這些默認(rèn)軸可以通過軸訪問器進(jìn)行修改,但只要明確設(shè)置了方向的任何軸,該方向的默認(rèn)軸就會(huì)被破壞。

構(gòu)造最小Q3D平面曲線圖

??首先,構(gòu)造Q3D曲面。由于在本例中,我們將圖形作為頂級(jí)窗口運(yùn)行,因此需要清除Qt::FramelessWindowHint標(biāo)志,該標(biāo)志在默認(rèn)情況下設(shè)置:

Q3DSurface surface; surface.setFlags(surface.flags() ^ Qt::FramelessWindowHint);

??現(xiàn)在Q3DSurface已準(zhǔn)備好接收要渲染的數(shù)據(jù)。創(chuàng)建數(shù)據(jù)元素以接收值:

QSurfaceDataArray *data = new QSurfaceDataArray;QSurfaceDataRow *dataRow1 = new QSurfaceDataRow;QSurfaceDataRow *dataRow2 = new QSurfaceDataRow;

??首先將數(shù)據(jù)喂給行元素,然后將它們的指針添加到數(shù)據(jù)元素:

*dataRow1 << QVector3D(0.0f, 0.1f, 0.5f) << QVector3D(1.0f, 0.5f, 0.5f);*dataRow2 << QVector3D(0.0f, 1.8f, 1.0f) << QVector3D(1.0f, 1.2f, 1.0f);*data << dataRow1 << dataRow2;、

??創(chuàng)建新系列并為其設(shè)置數(shù)據(jù):

QSurface3DSeries *series = new QSurface3DSeries;series->dataProxy()->resetArray(data); ? surface.addSeries(series);

??最后,設(shè)置為可見:

surface.show();

??創(chuàng)建和顯示此圖所需的完整代碼為:

#include <QtDataVisualization>using namespace QtDataVisualization;int main(int argc, char **argv){ ? ?QGuiApplication app(argc, argv); ? ?Q3DSurface surface; ? ?surface.setFlags(surface.flags() ^ Qt::FramelessWindowHint); ? ?QSurfaceDataArray *data = new QSurfaceDataArray; ? ?QSurfaceDataRow *dataRow1 = new QSurfaceDataRow; ? ?QSurfaceDataRow *dataRow2 = new QSurfaceDataRow; ? ?*dataRow1 << QVector3D(0.0f, 0.1f, 0.5f) << QVector3D(1.0f, 0.5f, 0.5f); ? ?*dataRow2 << QVector3D(0.0f, 1.8f, 1.0f) << QVector3D(1.0f, 1.2f, 1.0f); ? ?*data << dataRow1 << dataRow2; ? ?QSurface3DSeries *series = new QSurface3DSeries; ? ?series->dataProxy()->resetArray(data); ? ?surface.addSeries(series); ? ?surface.show(); ? ?return app.exec();}

??運(yùn)行效果:
??

??場景可以被旋轉(zhuǎn)、放大,并且可以選擇一個(gè)項(xiàng)目來查看其位置,但在這個(gè)最小的代碼示例中不包括其他交互。

Q3Ddemo構(gòu)建流程解析

步驟一:確認(rèn)安裝QtDataVisualization模塊

??如何確認(rèn),則是在幫助文件中查看是否有Q3dscatter類。一般是安裝了模塊才會(huì)有對(duì)應(yīng)的幫助文件。沒有則重新安裝qt或者單獨(dú)安裝該模塊。
??

步驟二:工程配置文件中加入模塊

??Q3d是在數(shù)據(jù)可視化模塊中,需要在pro或者pri配置文件中添加。

QT += datavisualization

??

步驟三:添加使用到的頭文件

??使用到Q3DBar相關(guān)類中添加頭文件,主要使用到Q3DBar、QBar3DSeries、QBarDataRow等等。

#include <Q3DBars>#include <Q3DTheme>#include <QBar3DSeries>#include <QVector3D>

??

步驟四:添加命名空間

??這時(shí)候還是無法使用對(duì)應(yīng)的類,需要添加命名空間才行:

using namespace QtDataVisualization;

??

步驟五:Q3D的圖標(biāo)基礎(chǔ)構(gòu)建框架

??下面是包含注釋的Q3DSurface基礎(chǔ)構(gòu)建流程(注意軸的顯示,查看末尾“入坑一”,注意數(shù)據(jù)的成面規(guī)則,查看“入坑二

_pQ3DSurface = new Q3DSurface();_pContainer = QWidget::createWindowContainer(_pQ3DSurface, this);// 設(shè)置軸文本{ ? ?// 注意笛卡爾坐標(biāo) ? ?_pQ3DSurface->axisX()->setTitle("經(jīng)度(°)"); ? ?_pQ3DSurface->axisX()->setTitleVisible(true); ? ?_pQ3DSurface->axisY()->setTitle("高度(m)"); ? ?_pQ3DSurface->axisY()->setTitleVisible(true); ? ?_pQ3DSurface->axisZ()->setTitle("緯度(°)"); ? ?_pQ3DSurface->axisZ()->setTitleVisible(true);}// 設(shè)置軸范圍{ ? ?// 注意笛卡爾坐標(biāo) ? ?_pQ3DSurface->axisX()->setRange(0, 359); ? ?_pQ3DSurface->axisY()->setRange(0, 100); ? ?_pQ3DSurface->axisZ()->setRange(0, 359);}// 生成一個(gè)曲線_pSurface3DSeries = new QSurface3DSeries(_pQ3DSurface);// 設(shè)置渲染平滑_pSurface3DSeries->setMeshSmooth(true);// 設(shè)置渲染模式// ? DrawWireframe ? ? ? ? ? : 繪制柵格// ? DrawSurface ? ? ? ? ? ? : 繪制表面// ? DrawSurfaceAndWireframe : 繪制柵格和圖表面_pSurface3DSeries->setDrawMode(QSurface3DSeries::DrawSurface);// 視圖添加該曲線_pQ3DSurface->addSeries(_pSurface3DSeries);// 設(shè)置陰影質(zhì)量_pQ3DSurface->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);// 設(shè)置視角_pQ3DSurface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft);// 設(shè)置子網(wǎng)格_pQ3DSurface->activeTheme()->setGridEnabled(true);#if 1// 添加模擬數(shù)據(jù)QSurfaceDataArray *pSurfaceDataArray = new QSurfaceDataArray;#if 1#if 1// 這是 z 緯度for(int n = 0; n < 360; n++){ ? ?QSurfaceDataRow *pSurfaceDataRow ?= new QSurfaceDataRow; ? ?// 這是 x 經(jīng)度 ? ?for(int m = 0; m < 360; m++) ? ?{ ? ? ? // 注意與笛卡爾坐標(biāo)進(jìn)行映射 ? ? ? *pSurfaceDataRow << QVector3D(m, n / 7 + m / 7, n); ? ?} ? ?*pSurfaceDataArray << pSurfaceDataRow;}#elsefor(int n = 0; n < 360; n++){ ? ?QSurfaceDataRow *pSurfaceDataRow ?= new QSurfaceDataRow; ? ?// 這是 x 經(jīng)度 ? ?for(int m = 0; m < 360; m++) ? ?{ ? ? ? // 注意與笛卡爾坐標(biāo)進(jìn)行映射 ? ? ? *pSurfaceDataRow << QVector3D(m, qrand() % 100, n); ? ? ? LOG << n << m; ? ?} ? ?*pSurfaceDataArray << pSurfaceDataRow;}#endif#elseQSurfaceDataRow *pSurfaceDataRow1 ?= new QSurfaceDataRow;QSurfaceDataRow *pSurfaceDataRow2 ?= new QSurfaceDataRow;QSurfaceDataRow *pSurfaceDataRow3 ?= new QSurfaceDataRow;// 行與行之間,要形成一個(gè)四點(diǎn)成面*pSurfaceDataRow1 << QVector3D(0, 0, 0) ?<< QVector3D(359, 20, 0);*pSurfaceDataRow2 << QVector3D(50, 20, 179) ?<< QVector3D(359, 40, 179);*pSurfaceDataRow3 << QVector3D(100, 80, 359) ?<< QVector3D(359, 100, 359);*pSurfaceDataArray << pSurfaceDataRow1 << pSurfaceDataRow2 << pSurfaceDataRow3;#endif// 添加數(shù)據(jù)(自動(dòng)沖掉之前的數(shù)據(jù))_pSurface3DSeries->dataProxy()->resetArray(pSurfaceDataArray);#endif_pQ3DSurface->addSeries(_pSurface3DSeries);_pQ3DSurface->show();

Demo源碼

Q3dSurfaceWidget.h

#ifndef Q3DSURFACEWIDGET_H#define Q3DSURFACEWIDGET_H#include <QWidget>#include <Q3DSurface>#include <Q3DTheme>#include <QSurface3DSeries>#include <QVector3D>using namespace QtDataVisualization;namespace Ui {class Q3dSurfaceWidget;}class Q3dSurfaceWidget : public QWidget{ ? ?Q_OBJECTpublic: ? ?explicit Q3dSurfaceWidget(QWidget *parent = 0); ? ?~Q3dSurfaceWidget();protected: ? ?void initControl();protected: ? ?void resizeEvent(QResizeEvent *event);private: ? ?Ui::Q3dSurfaceWidget *ui;private: ? ?Q3DSurface *_pQ3DSurface; ? ? ? ? ?// q3d平面曲線圖 ? ?QWidget *_pContainer; ? ? ? ? ? // q3d窗口容器 ? ?QSurface3DSeries ?*_pSurface3DSeries ; ? ?// q3d柱狀圖數(shù)據(jù)};#endif // Q3DSURFACEWIDGET_H

Q3dSurfaceWidget.cpp

#include "Q3dSurfaceWidget.h"#include "ui_Q3dSurfaceWidget.h"#include <Q3DTheme>#include <QDebug>#include <QDateTime>//#define LOG qDebug()<<__FILE__<<__LINE__//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")Q3dSurfaceWidget::Q3dSurfaceWidget(QWidget *parent) : ? ?QWidget(parent), ? ?ui(new Ui::Q3dSurfaceWidget), ? ?_pQ3DSurface(0), ? ?_pContainer(0), ? ?_pSurface3DSeries(0){ ? ?ui->setupUi(this); ? ?QString version = "v1.0.0"; ? ?initControl();}Q3dSurfaceWidget::~Q3dSurfaceWidget(){ ? ?delete ui;}void Q3dSurfaceWidget::initControl(){ ? ?_pQ3DSurface = new Q3DSurface(); ? ?_pContainer = QWidget::createWindowContainer(_pQ3DSurface, this); ? ?// 設(shè)置軸文本 ? ?{ ? ? ? ?// 注意笛卡爾坐標(biāo) ? ? ? ?_pQ3DSurface->axisX()->setTitle("經(jīng)度(°)"); ? ? ? ?_pQ3DSurface->axisX()->setTitleVisible(true); ? ? ? ?_pQ3DSurface->axisY()->setTitle("高度(m)"); ? ? ? ?_pQ3DSurface->axisY()->setTitleVisible(true); ? ? ? ?_pQ3DSurface->axisZ()->setTitle("緯度(°)"); ? ? ? ?_pQ3DSurface->axisZ()->setTitleVisible(true); ? ?} ? ?// 設(shè)置軸范圍 ? ?{ ? ? ? ?// 注意笛卡爾坐標(biāo) ? ? ? ?_pQ3DSurface->axisX()->setRange(0, 359); ? ? ? ?_pQ3DSurface->axisY()->setRange(0, 100); ? ? ? ?_pQ3DSurface->axisZ()->setRange(0, 359); ? ?} ? ?// 生成一個(gè)曲線 ? ?_pSurface3DSeries = new QSurface3DSeries(_pQ3DSurface); ? ?// 設(shè)置渲染平滑 ? ?_pSurface3DSeries->setMeshSmooth(true); ? ?// 設(shè)置渲染模式 ? ?// ? DrawWireframe ? ? ? ? ? : 繪制柵格 ? ?// ? DrawSurface ? ? ? ? ? ? : 繪制表面 ? ?// ? DrawSurfaceAndWireframe : 繪制柵格和圖表面 ? ?_pSurface3DSeries->setDrawMode(QSurface3DSeries::DrawSurface); ? ?// 視圖添加該曲線 ? ?_pQ3DSurface->addSeries(_pSurface3DSeries); ? ?// 設(shè)置陰影質(zhì)量 ? ?_pQ3DSurface->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow); ? ?// 設(shè)置視角 ? ?_pQ3DSurface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft); ? ?// 設(shè)置子網(wǎng)格 ? ?_pQ3DSurface->activeTheme()->setGridEnabled(true);#if 1 ? ?// 添加模擬數(shù)據(jù) ? ?QSurfaceDataArray *pSurfaceDataArray = new QSurfaceDataArray;#if 1#if 1 ? ?// 這是 z 緯度 ? ?for(int n = 0; n < 360; n++) ? ?{ ? ? ? ?QSurfaceDataRow *pSurfaceDataRow ?= new QSurfaceDataRow; ? ? ? ?// 這是 x 經(jīng)度 ? ? ? ?for(int m = 0; m < 360; m++) ? ? ? ?{ ? ? ? ? ? // 注意與笛卡爾坐標(biāo)進(jìn)行映射 ? ? ? ? ? *pSurfaceDataRow << QVector3D(m, n / 7 + m / 7, n); ? ? ? ?} ? ? ? ?*pSurfaceDataArray << pSurfaceDataRow; ? ?}#else ? ?for(int n = 0; n < 360; n++) ? ?{ ? ? ? ?QSurfaceDataRow *pSurfaceDataRow ?= new QSurfaceDataRow; ? ? ? ?// 這是 x 經(jīng)度 ? ? ? ?for(int m = 0; m < 360; m++) ? ? ? ?{ ? ? ? ? ? // 注意與笛卡爾坐標(biāo)進(jìn)行映射 ? ? ? ? ? *pSurfaceDataRow << QVector3D(m, qrand() % 100, n); ? ? ? ? ? LOG << n << m; ? ? ? ?} ? ? ? ?*pSurfaceDataArray << pSurfaceDataRow; ? ?}#endif#else ? ?QSurfaceDataRow *pSurfaceDataRow1 ?= new QSurfaceDataRow; ? ?QSurfaceDataRow *pSurfaceDataRow2 ?= new QSurfaceDataRow; ? ?QSurfaceDataRow *pSurfaceDataRow3 ?= new QSurfaceDataRow; ? ?// 行與行之間,要形成一個(gè)四點(diǎn)成面 ? ?*pSurfaceDataRow1 << QVector3D(0, 0, 0) ?<< QVector3D(359, 20, 0); ? ?*pSurfaceDataRow2 << QVector3D(50, 20, 179) ?<< QVector3D(359, 40, 179); ? ?*pSurfaceDataRow3 << QVector3D(100, 80, 359) ?<< QVector3D(359, 100, 359); ? ?*pSurfaceDataArray << pSurfaceDataRow1 << pSurfaceDataRow2 << pSurfaceDataRow3;#endif ? ?// 添加數(shù)據(jù)(自動(dòng)沖掉之前的數(shù)據(jù)) ? ?_pSurface3DSeries->dataProxy()->resetArray(pSurfaceDataArray);#endif ? ?_pQ3DSurface->addSeries(_pSurface3DSeries); ? ?_pQ3DSurface->show();}void Q3dSurfaceWidget::resizeEvent(QResizeEvent *event){ ? ?if(_pContainer) ? ?{ ? ? ? ?_pContainer->setGeometry(rect()); ? ?}}

工程模板v1.2.0

??

入坑

入坑一:xyz坐標(biāo)系不對(duì)

問題

??x精度,y維度,z高度(海拔高度)映射錯(cuò)誤
??

原因

??x,y,z實(shí)際是遵循笛卡爾坐標(biāo)集

解決

??先理解坐標(biāo),然后z軸方向,數(shù)據(jù)也要替換(按照x,y,z來排列,改為x,z,y)
?&emso;

入坑二:曲面顯示不對(duì)

問題

??數(shù)據(jù)顯示映射錯(cuò)誤

原因

??點(diǎn)成面,需要遵循4點(diǎn)成面的規(guī)則,和opengl相關(guān)3點(diǎn)成面和4點(diǎn)成面的原理類似。
??

??


??

解決

??相鄰行與行之間,要形成面,修改后展示如下:

??


??


Qt開發(fā)技術(shù):Q3D圖表開發(fā)筆記(三):Q3DSurface三維曲面圖介紹、Demo以及代碼詳解的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
康马县| 昭平县| 石渠县| 东至县| 泽库县| 景洪市| 安徽省| 四平市| 孟连| 郁南县| 新泰市| 淮北市| 迁安市| 巴楚县| 南岸区| 长宁区| 福海县| 宁乡县| 南通市| 嘉峪关市| 桃源县| 卢湾区| 潢川县| 定州市| 苍梧县| 鄂尔多斯市| 延寿县| 涪陵区| 乐至县| 扶余县| 阿坝县| 邮箱| 广饶县| 察隅县| 龙口市| 余干县| 泸定县| 饶平县| 中卫市| 沁源县| 和龙市|