首页 >企业动态 > > 正文

Qt开发技术:Q3D图表开发笔记(三):Q3DSurface三维曲面图介绍、Demo以及代码详解-要闻

来源:博客园 2023-04-20 22:18:24
前言

qt提供了q3d进行三维开发,虽然这个框架没有得到大量运用也不是那么成功,性能上也有很大的欠缺,但是普通的点到为止的应用展示还是可以的。  其中就包括华丽绚烂的三维图表,数据量不大的时候是可以使用的。  前面介绍了基础的q3d散点图、柱状图,本篇介绍基础的三维曲面图。

Demo:Q3DSurface散点图演示效果Q3D提供的三维图表

依赖QtDataVisualization。在安装qt的时候要选择安装QtDataVisualization模块。


(相关资料图)

Q3DScatter散点图

Q3D的散点图,性能大约支撑1000个点可以不卡顿,具体依赖pc,1000个点是什么 概念,可以理解为:10x10x10的区域,每个区域一个数据点。  

Q3DBars柱状图

Q3D的柱状图,性能跟散点图类似。  

Q3DSurface平面凹凸图,平面纹理图,平面曲线图

Q3D的柱状图,性能跟散点图类似。  

Q3DSurface平面曲线图简介

Q3DSurface类提供了渲染3D曲面图的方法。该类使开发人员能够渲染3D表面图,并通过自由旋转场景来查看它们。可以通过QSurface3DSeries控制曲面的视觉财产,例如绘制模式和着色。  Q3DSurface通过在用户用鼠标左键点击的数据点上显示高亮显示的球(当使用默认输入处理程序时)或通过QSurface3DSeries进行选择来支持选择。选择指针附带一个标签,在默认情况下,该标签显示数据点的值和点的坐标。轴上显示的值范围和标签格式可以通过QValue3DAxis进行控制。  要旋转图形,请按住鼠标右键并移动鼠标。缩放是使用鼠标滚轮完成的。两者都假设默认的输入处理程序正在使用中。  如果没有将任何轴明确设置为Q3DSurface,则会创建不带标签的临时默认轴。这些默认轴可以通过轴访问器进行修改,但只要明确设置了方向的任何轴,该方向的默认轴就会被破坏。

构造最小Q3D平面曲线图

首先,构造Q3D曲面。由于在本例中,我们将图形作为顶级窗口运行,因此需要清除Qt::FramelessWindowHint标志,该标志在默认情况下设置:

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

现在Q3DSurface已准备好接收要渲染的数据。创建数据元素以接收值:

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();

创建和显示此图所需的完整代码为:

#include 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();}

运行效果:  

场景可以被旋转、放大,并且可以选择一个项目来查看其位置,但在这个最小的代码示例中不包括其他交互。

Q3Ddemo构建流程解析步骤一:确认安装QtDataVisualization模块

如何确认,则是在帮助文件中查看是否有Q3dscatter类。一般是安装了模块才会有对应的帮助文件。没有则重新安装qt或者单独安装该模块。  

步骤二:工程配置文件中加入模块

Q3d是在数据可视化模块中,需要在pro或者pri配置文件中添加。

QT += datavisualization
步骤三:添加使用到的头文件

使用到Q3DBar相关类中添加头文件,主要使用到Q3DBar、QBar3DSeries、QBarDataRow等等。

#include #include #include #include 
步骤四:添加命名空间

这时候还是无法使用对应的类,需要添加命名空间才行:

using namespace QtDataVisualization;
步骤五:Q3D的图标基础构建框架

下面是包含注释的Q3DSurface基础构建流程(注意轴的显示,查看末尾“入坑一”,注意数据的成面规则,查看“入坑二”

_pQ3DSurface = new Q3DSurface();_pContainer = QWidget::createWindowContainer(_pQ3DSurface, this);// 设置轴文本{    // 注意笛卡尔坐标    _pQ3DSurface->axisX()->setTitle("经度(°)");    _pQ3DSurface->axisX()->setTitleVisible(true);    _pQ3DSurface->axisY()->setTitle("高度(m)");    _pQ3DSurface->axisY()->setTitleVisible(true);    _pQ3DSurface->axisZ()->setTitle("纬度(°)");    _pQ3DSurface->axisZ()->setTitleVisible(true);}// 设置轴范围{    // 注意笛卡尔坐标    _pQ3DSurface->axisX()->setRange(0, 359);    _pQ3DSurface->axisY()->setRange(0, 100);    _pQ3DSurface->axisZ()->setRange(0, 359);}// 生成一个曲线_pSurface3DSeries = new QSurface3DSeries(_pQ3DSurface);// 设置渲染平滑_pSurface3DSeries->setMeshSmooth(true);// 设置渲染模式//   DrawWireframe           : 绘制栅格//   DrawSurface             : 绘制表面//   DrawSurfaceAndWireframe : 绘制栅格和图表面_pSurface3DSeries->setDrawMode(QSurface3DSeries::DrawSurface);// 视图添加该曲线_pQ3DSurface->addSeries(_pSurface3DSeries);// 设置阴影质量_pQ3DSurface->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);// 设置视角_pQ3DSurface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft);// 设置子网格_pQ3DSurface->activeTheme()->setGridEnabled(true);#if 1// 添加模拟数据QSurfaceDataArray *pSurfaceDataArray = new QSurfaceDataArray;#if 1#if 1// 这是 z 纬度for(int n = 0; n < 360; n++){    QSurfaceDataRow *pSurfaceDataRow  = new QSurfaceDataRow;    // 这是 x 经度    for(int m = 0; m < 360; m++)    {       // 注意与笛卡尔坐标进行映射       *pSurfaceDataRow << QVector3D(m, n / 7 + m / 7, n);    }    *pSurfaceDataArray << pSurfaceDataRow;}#elsefor(int n = 0; n < 360; n++){    QSurfaceDataRow *pSurfaceDataRow  = new QSurfaceDataRow;    // 这是 x 经度    for(int m = 0; m < 360; m++)    {       // 注意与笛卡尔坐标进行映射       *pSurfaceDataRow << QVector3D(m, qrand() % 100, n);       LOG << n << m;    }    *pSurfaceDataArray << pSurfaceDataRow;}#endif#elseQSurfaceDataRow *pSurfaceDataRow1  = new QSurfaceDataRow;QSurfaceDataRow *pSurfaceDataRow2  = new QSurfaceDataRow;QSurfaceDataRow *pSurfaceDataRow3  = new QSurfaceDataRow;// 行与行之间,要形成一个四点成面*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// 添加数据(自动冲掉之前的数据)_pSurface3DSeries->dataProxy()->resetArray(pSurfaceDataArray);#endif_pQ3DSurface->addSeries(_pSurface3DSeries);_pQ3DSurface->show();
Demo源码Q3dSurfaceWidget.h
#ifndef Q3DSURFACEWIDGET_H#define Q3DSURFACEWIDGET_H#include #include #include #include #include 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柱状图数据};#endif // Q3DSURFACEWIDGET_H
Q3dSurfaceWidget.cpp
#include "Q3dSurfaceWidget.h"#include "ui_Q3dSurfaceWidget.h"#include #include #include //#define LOG qDebug()<<__FILE__<<__LINE__//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__//#define LOG qDebug()<<__FILE__<<__LINE__<setupUi(this);    QString version = "v1.0.0";    initControl();}Q3dSurfaceWidget::~Q3dSurfaceWidget(){    delete ui;}void Q3dSurfaceWidget::initControl(){    _pQ3DSurface = new Q3DSurface();    _pContainer = QWidget::createWindowContainer(_pQ3DSurface, this);    // 设置轴文本    {        // 注意笛卡尔坐标        _pQ3DSurface->axisX()->setTitle("经度(°)");        _pQ3DSurface->axisX()->setTitleVisible(true);        _pQ3DSurface->axisY()->setTitle("高度(m)");        _pQ3DSurface->axisY()->setTitleVisible(true);        _pQ3DSurface->axisZ()->setTitle("纬度(°)");        _pQ3DSurface->axisZ()->setTitleVisible(true);    }    // 设置轴范围    {        // 注意笛卡尔坐标        _pQ3DSurface->axisX()->setRange(0, 359);        _pQ3DSurface->axisY()->setRange(0, 100);        _pQ3DSurface->axisZ()->setRange(0, 359);    }    // 生成一个曲线    _pSurface3DSeries = new QSurface3DSeries(_pQ3DSurface);    // 设置渲染平滑    _pSurface3DSeries->setMeshSmooth(true);    // 设置渲染模式    //   DrawWireframe           : 绘制栅格    //   DrawSurface             : 绘制表面    //   DrawSurfaceAndWireframe : 绘制栅格和图表面    _pSurface3DSeries->setDrawMode(QSurface3DSeries::DrawSurface);    // 视图添加该曲线    _pQ3DSurface->addSeries(_pSurface3DSeries);    // 设置阴影质量    _pQ3DSurface->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);    // 设置视角    _pQ3DSurface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetIsometricLeft);    // 设置子网格    _pQ3DSurface->activeTheme()->setGridEnabled(true);#if 1    // 添加模拟数据    QSurfaceDataArray *pSurfaceDataArray = new QSurfaceDataArray;#if 1#if 1    // 这是 z 纬度    for(int n = 0; n < 360; n++)    {        QSurfaceDataRow *pSurfaceDataRow  = new QSurfaceDataRow;        // 这是 x 经度        for(int m = 0; m < 360; m++)        {           // 注意与笛卡尔坐标进行映射           *pSurfaceDataRow << QVector3D(m, n / 7 + m / 7, n);        }        *pSurfaceDataArray << pSurfaceDataRow;    }#else    for(int n = 0; n < 360; n++)    {        QSurfaceDataRow *pSurfaceDataRow  = new QSurfaceDataRow;        // 这是 x 经度        for(int m = 0; m < 360; m++)        {           // 注意与笛卡尔坐标进行映射           *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;    // 行与行之间,要形成一个四点成面    *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    // 添加数据(自动冲掉之前的数据)    _pSurface3DSeries->dataProxy()->resetArray(pSurfaceDataArray);#endif    _pQ3DSurface->addSeries(_pSurface3DSeries);    _pQ3DSurface->show();}void Q3dSurfaceWidget::resizeEvent(QResizeEvent *event){    if(_pContainer)    {        _pContainer->setGeometry(rect());    }}
工程模板v1.2.0入坑入坑一:xyz坐标系不对问题

x精度,y维度,z高度(海拔高度)映射错误  

原因

x,y,z实际是遵循笛卡尔坐标集

解决

先理解坐标,然后z轴方向,数据也要替换(按照x,y,z来排列,改为x,z,y) &emso;

入坑二:曲面显示不对问题

数据显示映射错误

原因

点成面,需要遵循4点成面的规则,和opengl相关3点成面和4点成面的原理类似。  

解决

相邻行与行之间,要形成面,修改后展示如下:

上一篇: 下一篇:
x
推荐阅读

Qt开发技术:Q3D图表开发笔记(三):Q3DSurface三维曲面图介绍、Demo以及代码详解-要闻

2023-04-20

【天天热闻】随着市场重新调整加息预期,金价跌破2000美元

2023-04-20

孟晚舟当值华为轮值董事长后首发言:跃升数字生产力正当时

2023-04-20

看好中国经济!小摩、花旗、瑞银等上调今年GDP预期,后市预期这样…

2023-04-20

北京市举行长峰医院火灾事故情况通报会

2023-04-20

构成伪造公司债券罪的条件有哪些 天天热闻

2023-04-20

资讯推荐:投诉冠中匠合同套路

2023-04-20

环球热头条丨全国生猪疫情总体平稳,猪肉价格起落有望趋于平缓

2023-04-20

国光股份:股权增资及转让协议中没有约定对赌条款 天天热文

2023-04-20

2022年初中级经济师考试补考成绩怎么算?-世界要闻

2023-04-20

环球要闻:带货变卖货,出租车司机贩卖毒品被批捕

2023-04-20

环球速讯:WTT澳门冠军赛张本智和晋级八强 WTT澳门冠军赛2023男单1/8决赛达科·约奇克3-2梁靖崑

2023-04-20

河北馆陶开展世界地球日活动|微动态

2023-04-20

天天热点!什么人不能吃牛油果吃牛油果有什么禁忌

2023-04-20

当前滚动:如何制作椭圆形桌子_适合送给女孩子的生日礼物送什么

2023-04-20

关于满配妮夜妲白的一些看法

2023-04-20

环球矿产2022年净利964.31万同比下滑25.23% 海运费和陆路运费增长

2023-04-20

IMF报告称美银行业动荡等因素加剧全球金融稳定风险,中方回应

2023-04-20

国家统计局:一季度房地产业GDP绝对值为19611亿元,比上年同期增长1.3% 全球时讯

2023-04-20

世界热议:益生股份:总体判断,今年白羽肉鸡行业的景气度高

2023-04-20

油墨上市公司龙头股有哪些?(2023/4/19) 世界快消息

2023-04-20

男子在迪士尼抽烟与工作人员起冲突?上海迪士尼回应

2023-04-20

有色金属板块全面回调,有色ETF大跌2.7%

2023-04-20

速看:“三诊”合参 追寻本真

2023-04-20

日本内阁官房长官松野博一:我们将在广岛举行的G7会议上讨论数字经济规则

2023-04-20

信用卡刷卡套现怎么样才安全 刷信用卡套现怎么样更不会被监控到_天天热点评

2023-04-20

DIY 纸板洗衣机和烘干机玩具套装 快播报

2023-04-20

谷雨节气的由来 竟与汉字的起源有关_全球新要闻

2023-04-20

速读:外公绑架4岁外孙女向女儿勒索50万 被送进监狱

2023-04-20

heart是什么意思中文_heart解释

2023-04-20

浪漫传说同人文续写(浪漫传说同人文)

2023-04-20

大众朗逸仪表板上的图示灯大全_大众车朗逸仪表灯图解_世界热推荐

2023-04-20

2023北京市农业农村局所属事业单位招聘笔试公告_环球时快讯

2023-04-20

港股收评:三大指数齐跌,恒指下挫近300点,濠赌股逆势走强

2023-04-20

悬崖绝壁的绝的意思是什么? 悬崖绝壁的绝什么意思_世界快播

2023-04-20

win7旗舰版密钥生成器 最新资讯

2023-04-20

全球快消息!贵安新区建设万亩蓝莓产业园

2023-04-20

中证国新央企ESG成长100指数发布 聚焦央企成长动能 快消息

2023-04-19

【世界新视野】中广核技发布电子束处理特种废物技术品牌“和美”

2023-04-19

对行政处罚决定书不服的怎样能告赢技巧有那些?

2023-04-19

女足世界杯我们有信心——专访国脚吴澄舒

2023-04-19

当前滚动:惠威AW-75真无线耳机图赏:别致、个性外形下,高品质音质

2023-04-19

环球热推荐:2023第一季,餐饮行业大复苏

2023-04-19

武汉周生生今日金价多少一克(2023年4月19日) 天天报道

2023-04-19

北京市场|精彩纷呈,不见不散! 快消息

2023-04-19

焦点滚动:一口榴莲、一口芒果!榴芒奶盖沙琪玛大促:0.98元/个

2023-04-19

南通川姜:全力以赴打赢文明城市创建攻坚战 当前速讯

2023-04-19

【独家焦点】甘源食品董秘回复:淘宝天猫超市销售的数据为天猫超市平台官方数据

2023-04-19

头条焦点:同比增长17.8%!牡丹江全市口岸出入境货物量累计达到238.9万吨

2023-04-19

传音控股(688036)4月19日主力资金净卖出4688.28万元-天天通讯

2023-04-19

安阳市召开曹操高陵遗址博物馆高质量发展专家座谈会_每日聚焦

2023-04-19

内部渠道购买演唱会门票?三个诈骗套路需警惕_世界即时

2023-04-19

老鼠嫁女的故事_老鼠嫁女的寓意

2023-04-19

2023 款欧拉芭蕾猫复古纯电汽车上市:首搭女性安全架构“暖科技”

2023-04-19

天天信息:发改委:下大力气稳定汽车消费,加快推进充电桩和城市停车设施建设,大力推动新能源汽车下乡

2023-04-19

前置器 CON011/916-XXX

2023-04-19

中东部将迎“俯冲式”降温 南方新一轮降雨明日登场

2023-04-19

2023免疫检测行业今后的发展与投资策略

2023-04-19

网络热梗背后 猪脚饭何以吃出“男人的浪漫”? 全球新视野

2023-04-19

港股恒生指数弱势震荡跌0.49% 东方甄选涨逾12%_全球热闻

2023-04-19

全球央行大举购金,释放什么信号?

2023-04-19

焦点快报!GPT-4 用于医疗领域,帮助医护回复患者和分析记录

2023-04-19

沙尘暴蓝色预警!北京北部等地区将有扬沙或浮尘 天天观焦点

2023-04-19

【环球热闻】544-HPPolestar4CoupeSUV成为迄今为止最快的Polestar

2023-04-19

河北省养老金最新消息 河北2023年养老金会涨多少呢

2023-04-19

观察:百龙创园(605016):4月19日技术指标出现观望信号-“黑三兵”

2023-04-19

世界热头条丨洛阳钼业:TFM混合矿项目中区项目已实现短流程投料试车

2023-04-19

天天动态:烟火气回归,罗湖商业城客流大幅上涨 品“一盅两件”,香港客络绎不绝情有独钟 三十年老品牌!“港人后花园”又旺了

2023-04-19

快播:女孩买衣服被老板娘相中做儿媳,买衣服送男朋友!

2023-04-19

天天亮点!上古卷轴5dlc加载顺序 上古卷轴5dlc怎么加载

2023-04-19

每日速读!太原:男子酒后欲轻生 紧急时刻民警夺下手中农药

2023-04-19

住宅销售面积增速13个月来首次同比转正 世界热闻

2023-04-19

世界热头条丨对话|江歌妈妈:女儿离开两千多天后 继续为名誉而战

2023-04-19

规模300亿 期限17年 广东集成电路基金二期启动 打造“集成电路第三极” 通讯

2023-04-19

16年的等待!米兰06/07赛季后首次晋级欧冠四强

2023-04-19

4-0淘汰切尔西!罗德里戈致敬C罗,皇马英超6连斩,曼城瑟瑟发抖

2023-04-19

观点:早安温馨问候语简短_早安温馨问候语

2023-04-19

锡林郭勒盟与京津冀等地多企业签约引资超4亿元|观速讯

2023-04-19

世界关注:中行基金定投怎么查询_中行基金定投

2023-04-19

cs1.6地图名_cs1 6地图名称|头条焦点

2023-04-19

真强!莫兰德抢下23个篮板 创辽宁队史季后赛单场篮板新高 世界关注

2023-04-19

当前视点!时差七小时是哪个国家_时差七小时电影简介

2023-04-19

美议员称芝加哥青少年暴乱只是“大规模抗议” 引网友谴责

2023-04-19

生存_生存的英文

2023-04-19

世界微速讯:来,一起从太空俯瞰祖国春耕锦绣画卷!

2023-04-19

探访广西弄岗保护区上“新”又登“高”背后的“故事”_当前视讯

2023-04-19

苏丹冲突地区多数医院已暂停服务|世界报资讯

2023-04-19

赞美庐山的诗句-关于庐山的诗句

2023-04-19

全球速看:国网天津电力一批电网项目投产

2023-04-19

实施英文单词是什么_实施英文_每日快看

2023-04-19

化工行业点评:国内纯MDI市场小幅推涨 甲醇期货市场维持高位震荡

2023-04-19

文化地产行业发展模式 文化地产行业市场前景

2023-04-18

鸦片英国人最早将鸦片传入中国_英国人最早将鸦片传入中国 速读

2023-04-18

天天快讯:真我挑战旗舰影像:真我11系列主摄传感器尺寸刷新记录

2023-04-18

千味央厨2022年营收14.89亿元,预制菜销售额同比增长101.23%

2023-04-18

优酷《长月烬明》带火花甲粉外卖搜索翻倍 天天时快讯

2023-04-18

税务师税法二考试题目类型有哪几种?难吗?

2023-04-18

有关机器人的动画电影(和机器人有关的电影)

2023-04-18

世界要闻:通光线缆:公司暂没有关于数字化经济人工智能方面的应用

2023-04-18

世界热资讯!2023年第一季度全国检察机关记录报告过问或干预插手检察办案等重大事项5.1万余件

2023-04-18