Qt開發技術:Q3D圖表開發筆記(四):Q3DSurface三維曲面圖顏色樣式詳解、Demo以及程式碼詳解

红胖子(红模仿)發表於2024-06-04

前言

  qt提供了q3d進行三維開發,雖然這個框架沒有得到大量運用也不是那麼成功,效能上也有很大的欠缺,但是普通的點到為止的應用展示還是可以的。
  其中就包括華麗絢爛的三維圖表,資料量不大的時候是可以使用的。
  前面介紹了基礎的q3d散點圖、柱狀圖、三維曲面圖,本片深入對三維曲面圖支援的顏色表現方式進行探討。

Demo:Q3DSurface散點圖顏色演示效果

  純色、選中點的顏色
  在這裡插入圖片描述

  漸進色、選中點的顏色  
  在這裡插入圖片描述

  按照y軸參與漸進色
  在這裡插入圖片描述

Q3D提供的三維圖表

  依賴QtDataVisualization。在安裝qt的時候要選擇安裝QtDataVisualization模組。

Q3DScatter散點圖

  Q3D的散點圖,效能大約支撐1000個點可以不卡頓,具體依賴pc,1000個點是什麼 概念,可以理解為:10x10x10的區域,每個區域一個資料點。
  在這裡插入圖片描述

Q3DBars柱狀圖

  Q3D的柱狀圖,效能跟散點圖類似。
   在這裡插入圖片描述

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

  Q3D的柱狀圖,效能跟散點圖類似。
  在這裡插入圖片描述

Q3DSurface平面曲線圖

簡介

  Q3DSurface類提供了渲染3D曲面圖的方法。該類使開發人員能夠渲染3D表面圖,並透過自由旋轉場景來檢視它們。可以透過QSurface3DSeries控制曲面的視覺,例如繪製模式和著色。
  Q3DSurface透過在使用者用滑鼠左鍵點選的資料點上顯示高亮顯示的球(當使用預設輸入處理程式時)或透過QSurface3DSeries進行選擇來支援選擇。選擇指標附帶一個標籤,在預設情況下,該標籤顯示資料點的值和點的座標。
  軸上顯示的值範圍和標籤格式可以透過QValue3DAxis進行控制。
  要旋轉圖形,請按住滑鼠右鍵並移動滑鼠。縮放是使用滑鼠滾輪完成的。兩者都假設預設的輸入處理程式正在使用中。
  如果沒有將任何軸明確設定為Q3DSurface,則會建立不帶標籤的臨時預設軸。這些預設軸可以透過軸訪問器進行修改,但只要明確設定了方向的任何軸,該方向的預設軸就會被破壞。

攝像機預製型別:CameraPreset

  注意:所有的東西都不能低於最低的Y平面從下網上看。
  列舉如下,在Demo中動態調整檢視效果:

  • CameraPresetNone:用於指示尚未設定預設或場景已自由旋轉
  • CameraPresetFrontLow:相機預設前低(實際y中間)
  • CameraPresetFront:相機預設前(實際前面俯檢視,約45°向下)
  • CameraPresetFrontHigh:相機預設前高(實際前面俯檢視,約60°向下)
  • CameraPresetLeftLow:相機預設左低
  • CameraPresetLeft:相機預設左
  • CameraPresetLeftHigh:相機預設左高
  • CameraPresetRightLow:相機預設右低
  • CameraPresetRight:相機預設右
  • CameraPresetRightHigh:相機預設右高
  • CameraPresetBehindLow:相機預設後低
  • CameraPresetBehind:相機預設後
  • CameraPresetBehindHigh:相機預設後高
  • CameraPresetIsometricLeft:相機預設左45°
  • CameraPresetIsometricLeftHigh:相機預設左45°高
  • CameraPresetIsometricRight:相機預設右45°
  • CameraPresetIsometricRightHigh:相機預設右45°高
  • CameraPresetDirectlyAbove:相機預設,中間往下看旋轉Y
  • CameraPresetDirectlyAboveCW45:相機預設,中間往下看正旋轉Y45°度不同
  • CameraPresetDirectlyAboveCCW45:相機預設,中間往下看逆旋轉Y45°角度不同
  • CameraPresetFrontBelow:相機預設前下
  • CameraPresetLeftBelow:相機預設左下
  • CameraPresetRightBelow:相機預設右下
  • CameraPresetBehindBelow:相機預設直接在後下,實際與xz不能再往下了
  • CameraPresetDirectlyBelow:相機預設直接在下,實際與xz不能再往下了,對於僅為正的條形,充當CameraPresetFrontLow。

顏色樣式:colorStyle

  注意:實測multiHightlightColor沒測出來,多選的時候是這個顏色,但是設定選擇模式無法一個曲面多選幾個點,以下都是這樣的測試結果。

  • ColorStyleUniform:物件以單一顏色渲染。使用的顏色在baseColors、singleHighlightColor和multiHighlightColor屬性中指定。
// 設定顏色樣式
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleUniform);
    // 設定顏色
    _pSurface3DSeries->setBaseColor(Qt::red);
    // 選中顏色
    _pSurface3DSeries->setSingleHighlightColor(Qt::blue);
    // 使用 _pQ3DSurface->setSelectionMode(QAbstract3DGraph::SelectionItem
    //                                    | QAbstract3DGraph::SelectionRow
    //                                    | QAbstract3DGraph::SelectionMultiSeries);
    // 也未測試出來
    _pSurface3DSeries->setMultiHighlightColor(Qt::green);
  • ColorStyleObjectGradient:無論物件的高度如何,物件都將使用每個物件的全漸變進行著色。使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate 屬性中指定。
    // 設定顏色樣式
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleObjectGradient);
    // 漸變色
    QLinearGradient linearGradient;
    linearGradient.setColorAt(0.0, Qt::red);
    linearGradient.setColorAt(0.333, Qt::blue);
    linearGradient.setColorAt(0.667, Qt::green);
    linearGradient.setColorAt(1.0, Qt::gray);
    // 設定顏色
    _pSurface3DSeries->setBaseGradient(linearGradient);
    // 選中顏色
    // 漸變色2
    QLinearGradient linearGradient2;
    linearGradient2.setColorAt(0.0, Qt::yellow);
    linearGradient2.setColorAt(1.0, Qt::gray);
    _pSurface3DSeries->setSingleHighlightGradient(linearGradient2);
    _pSurface3DSeries->setSingleHighlightColor(Qt::red);
//    _pSurface3DSeries->setMultiHighlightGraduate(Qt::green);
  • ColorStyleRangeGradient : 使用由物件的高度及其在Y軸上的位置確定的完整漸變的一部分對物件進行著色。使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate屬性中指定。
    // 設定顏色樣式
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
    // 漸變色
    QLinearGradient linearGradient;
    linearGradient.setColorAt(0.0, Qt::red);
    linearGradient.setColorAt(1.0, Qt::green);
    // 設定顏色
    _pSurface3DSeries->setBaseGradient(linearGradient);
    // 選中顏色
    // 漸變色2
    QLinearGradient linearGradient2;
    linearGradient2.setColorAt(0.0, Qt::yellow);
    linearGradient2.setColorAt(1.0, Qt::gray);
    _pSurface3DSeries->setSingleHighlightGradient(linearGradient2);
    _pSurface3DSeries->setSingleHighlightColor(Qt::red);
//    _pSurface3DSeries->setMultiHighlightGraduate(Qt::green);

Q3DDemo構建流程解析

步驟一:確認安裝QtDataVisualization模組

  如何確認,則是在幫助檔案中檢視是否有Q3dscatter類。一般是安裝了模組才會有對應的幫助檔案。沒有則重新安裝qt或者單獨安裝該模組。
  在這裡插入圖片描述

步驟二:工程配置檔案中加入模組

  Q3d是在資料視覺化模組中,需要在pro或者pri配置檔案中新增。

QT += datavisualization

  在這裡插入圖片描述

步驟三:新增使用到的標頭檔案

  使用到Q3DBar相關類中新增標頭檔案,主要使用到Q3DBar、QBar3DSeries、QBarDataRow等等。

#include <Q3DBars>
#include <Q3DTheme>
#include <Q3DSurface>
#include <QVector3D>

  在這裡插入圖片描述

步驟四:新增名稱空間

  這時候還是無法使用對應的類,需要新增名稱空間才行:

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

#if 0
    // 設定顏色樣式
    // ColorStyleUniform = 0    : 物件以單一顏色渲染。使用的顏色在baseColors、
    //                            singleHighlightColor和multiHighlightColor屬性中指定。
    // ColorStyleObjectGradient : 無論物件的高度如何,物件都將使用每個物件的全漸變進行著色。
    //                            使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate 屬性中指定。
    // ColorStyleRangeGradient  :
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleUniform);
    // 設定顏色
    _pSurface3DSeries->setBaseColor(Qt::red);
    // 選中顏色
    _pSurface3DSeries->setSingleHighlightColor(Qt::blue);
    // 使用 _pQ3DSurface->setSelectionMode(QAbstract3DGraph::SelectionItem
    //                                    | QAbstract3DGraph::SelectionRow
    //                                    | QAbstract3DGraph::SelectionMultiSeries);
    // 也未測試出來
    _pSurface3DSeries->setMultiHighlightColor(Qt::green);
#endif



#if 0
    // 設定顏色樣式
    // ColorStyleUniform = 0    : 物件以單一顏色渲染。使用的顏色在baseColors、
    //                            singleHighlightColor和multiHighlightColor屬性中指定。
    // ColorStyleObjectGradient : 無論物件的高度如何,物件都將使用每個物件的全漸變進行著色。
    //                            使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate 屬性中指定。
    // ColorStyleRangeGradient  :
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleObjectGradient);
    // 漸變色
    QLinearGradient linearGradient;
    linearGradient.setColorAt(0.0, Qt::red);
    linearGradient.setColorAt(0.333, Qt::blue);
    linearGradient.setColorAt(0.667, Qt::green);
    linearGradient.setColorAt(1.0, Qt::gray);
    // 設定顏色
    _pSurface3DSeries->setBaseGradient(linearGradient);
    // 選中顏色
    // 漸變色2
    QLinearGradient linearGradient2;
    linearGradient2.setColorAt(0.0, Qt::yellow);
    linearGradient2.setColorAt(1.0, Qt::gray);
    _pSurface3DSeries->setSingleHighlightGradient(linearGradient2);
    _pSurface3DSeries->setSingleHighlightColor(Qt::red);
//    _pSurface3DSeries->setMultiHighlightGraduate(Qt::green);
#endif

#if 1
    // 設定顏色樣式
    // ColorStyleUniform = 0    : 物件以單一顏色渲染。使用的顏色在baseColors、
    //                            singleHighlightColor和multiHighlightColor屬性中指定。
    // ColorStyleObjectGradient : 無論物件的高度如何,物件都將使用每個物件的全漸變進行著色。
    //                            使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate 屬性中指定。
    // ColorStyleRangeGradient  : 使用由物件的高度及其在Y軸上的位置確定的完整漸變的一部分對物件進行著色。
    //                            使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate屬性中指定。
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
    // 漸變色
    QLinearGradient linearGradient;
    linearGradient.setColorAt(0.0, Qt::red);
    linearGradient.setColorAt(1.0, Qt::green);
    // 設定顏色
    _pSurface3DSeries->setBaseGradient(linearGradient);
    // 選中顏色
    // 漸變色2
    QLinearGradient linearGradient2;
    linearGradient2.setColorAt(0.0, Qt::yellow);
    linearGradient2.setColorAt(1.0, Qt::gray);
    _pSurface3DSeries->setSingleHighlightGradient(linearGradient2);
    _pSurface3DSeries->setSingleHighlightColor(Qt::red);
//    _pSurface3DSeries->setMultiHighlightGraduate(Qt::green);
#endif

#if 0
    // 設定漸進色
    QLinearGradient *pLinearGradient = new QLinearGradient(0, 0,100,100);
    pLinearGradient->setColorAt(0, Qt::red);
    pLinearGradient->setColorAt(1.0, Qt::blue);
    _pSurface3DSeries->setBaseGradient(*pLinearGradient);
#endif


    // 檢視新增該曲線
    _pQ3DSurface->addSeries(_pSurface3DSeries);
    // 設定陰影質量
    _pQ3DSurface->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);
    // 設定視角
    _pQ3DSurface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetNone);
    // 設定子網格
    _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++)
        {
#if 0
            // 注意與笛卡爾座標進行對映
            *pSurfaceDataRow << QVector3D(m, n / 7 + m / 7, n);
#else
            // 注意與笛卡爾座標進行對映(超過180的下沉)
            *pSurfaceDataRow << QVector3D(m, n / 7 + m / 7 - (m > 180 ? n / 3 : 0), n);
#endif
        }
        *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();

Demo原始碼

Q3dSurfaceColorWidget.h

#ifndef Q3DSURFACECOLORWIDGET_H
#define Q3DSURFACECOLORWIDGET_H

#include <QWidget>
#include <Q3DSurface>
#include <Q3DTheme>
#include <QSurface3DSeries>
#include <QVector3D>


using namespace QtDataVisualization;

namespace Ui {
class Q3dSurfaceColorWidget;
}

class Q3dSurfaceColorWidget : public QWidget
{
    Q_OBJECT

public:
    explicit Q3dSurfaceColorWidget(QWidget *parent = 0);
    ~Q3dSurfaceColorWidget();

public:
    void setCameraPreset(Q3DCamera::CameraPreset cameraPreset);

protected:
    void initControl();


protected:
    void resizeEvent(QResizeEvent *event);

private slots:
    void on_comboBox_cameraPreset_currentIndexChanged(int index);

private:
    Ui::Q3dSurfaceColorWidget *ui;

private:
    Q3DSurface *_pQ3DSurface;               // q3d平面曲線圖
    QWidget *_pContainer;                   // q3d視窗容器
    QSurface3DSeries  *_pSurface3DSeries ;  // q3d柱狀圖資料
};

#endif // Q3DSURFACECOLORWIDGET_H

Q3dSurfaceColorWidget.cpp

#include "Q3dSurfaceColorWidget.h"
#include "ui_Q3dSurfaceColorWidget.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")

Q3dSurfaceColorWidget::Q3dSurfaceColorWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Q3dSurfaceColorWidget),
    _pQ3DSurface(0),
    _pContainer(0),
    _pSurface3DSeries(0)
{
    ui->setupUi(this);

    QString version = "v1.0.0";

    initControl();
}

Q3dSurfaceColorWidget::~Q3dSurfaceColorWidget()
{
    delete ui;
}

void Q3dSurfaceColorWidget::setCameraPreset(Q3DCamera::CameraPreset cameraPreset)
{
    // 設定視角
    // CameraPresetNone = -1,          :    用於指示尚未設定預設,或場景已自由旋轉。
    // CameraPresetFrontLow = 0,       :
    // CameraPresetFront,              :
    // CameraPresetFrontHigh,          :
    // CameraPresetLeftLow,            :
    // CameraPresetLeft,               :
    // CameraPresetLeftHigh,           :
    // CameraPresetRightLow,           :
    // CameraPresetRight,              :
    // CameraPresetRightHigh,          :
    // CameraPresetBehindLow,          :
    // CameraPresetBehind,             :
    // CameraPresetBehindHigh,         :
    // CameraPresetIsometricLeft,      :
    // CameraPresetIsometricLeftHigh,  :
    // CameraPresetIsometricRight,     :
    // CameraPresetIsometricRightHigh, :
    // CameraPresetDirectlyAbove,      :
    // CameraPresetDirectlyAboveCW45,  :
    // CameraPresetDirectlyAboveCCW45, :
    // CameraPresetFrontBelow,         :
    // CameraPresetLeftBelow,          :
    // CameraPresetRightBelow,         :
    // CameraPresetBehindBelow,        :
    // CameraPresetDirectlyBelow       :

    // 設定視角
    if(_pQ3DSurface)
    {
        _pQ3DSurface->scene()->activeCamera()->setCameraPreset(cameraPreset);
    }
}

void Q3dSurfaceColorWidget::initControl()
{
    // 視角預置
    {
        // 設定視角
        // CameraPresetNone = -1,          :    用於指示尚未設定預設,或場景已自由旋轉。
        // CameraPresetFrontLow = 0,       :
        // CameraPresetFront,              :
        // CameraPresetFrontHigh,          :
        // CameraPresetLeftLow,            :
        // CameraPresetLeft,               :
        // CameraPresetLeftHigh,           :
        // CameraPresetRightLow,           :
        // CameraPresetRight,              :
        // CameraPresetRightHigh,          :
        // CameraPresetBehindLow,          :
        // CameraPresetBehind,             :
        // CameraPresetBehindHigh,         :
        // CameraPresetIsometricLeft,      :
        // CameraPresetIsometricLeftHigh,  :
        // CameraPresetIsometricRight,     :
        // CameraPresetIsometricRightHigh, :
        // CameraPresetDirectlyAbove,      :
        // CameraPresetDirectlyAboveCW45,  :
        // CameraPresetDirectlyAboveCCW45, :
        // CameraPresetFrontBelow,         :
        // CameraPresetLeftBelow,          :
        // CameraPresetRightBelow,         :
        // CameraPresetBehindBelow,        :
        // CameraPresetDirectlyBelow       :
        ui->comboBox_cameraPreset->clear();
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetNone");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetFrontLow = 0");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetFront");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetFrontHigh");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetLeftLow");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetLeft");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetLeftHigh");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetRightLow");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetRight");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetRightHigh");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetBehindLow");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetBehind");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetBehindHigh");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetIsometricLeft");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetIsometricLeftHigh");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetIsometricRight");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetIsometricRightHigh");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetDirectlyAbove");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetDirectlyAboveCW45");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetDirectlyAboveCCW45");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetFrontBelow");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetLeftBelow");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetRightBelow");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetBehindBelow");
        ui->comboBox_cameraPreset->addItem("Q3DCamera::CameraPresetDirectlyBelow");

        ui->comboBox_cameraPreset->setCurrentText("Q3DCamera::CameraPresetNone");
    }

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

#if 0
    // 設定顏色樣式
    // ColorStyleUniform = 0    : 物件以單一顏色渲染。使用的顏色在baseColors、
    //                            singleHighlightColor和multiHighlightColor屬性中指定。
    // ColorStyleObjectGradient : 無論物件的高度如何,物件都將使用每個物件的全漸變進行著色。
    //                            使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate 屬性中指定。
    // ColorStyleRangeGradient  :
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleUniform);
    // 設定顏色
    _pSurface3DSeries->setBaseColor(Qt::red);
    // 選中顏色
    _pSurface3DSeries->setSingleHighlightColor(Qt::blue);
    // 使用 _pQ3DSurface->setSelectionMode(QAbstract3DGraph::SelectionItem
    //                                    | QAbstract3DGraph::SelectionRow
    //                                    | QAbstract3DGraph::SelectionMultiSeries);
    // 也未測試出來
    _pSurface3DSeries->setMultiHighlightColor(Qt::green);
#endif



#if 0
    // 設定顏色樣式
    // ColorStyleUniform = 0    : 物件以單一顏色渲染。使用的顏色在baseColors、
    //                            singleHighlightColor和multiHighlightColor屬性中指定。
    // ColorStyleObjectGradient : 無論物件的高度如何,物件都將使用每個物件的全漸變進行著色。
    //                            使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate 屬性中指定。
    // ColorStyleRangeGradient  :
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleObjectGradient);
    // 漸變色
    QLinearGradient linearGradient;
    linearGradient.setColorAt(0.0, Qt::red);
    linearGradient.setColorAt(0.333, Qt::blue);
    linearGradient.setColorAt(0.667, Qt::green);
    linearGradient.setColorAt(1.0, Qt::gray);
    // 設定顏色
    _pSurface3DSeries->setBaseGradient(linearGradient);
    // 選中顏色
    // 漸變色2
    QLinearGradient linearGradient2;
    linearGradient2.setColorAt(0.0, Qt::yellow);
    linearGradient2.setColorAt(1.0, Qt::gray);
    _pSurface3DSeries->setSingleHighlightGradient(linearGradient2);
    _pSurface3DSeries->setSingleHighlightColor(Qt::red);
//    _pSurface3DSeries->setMultiHighlightGraduate(Qt::green);
#endif

#if 1
    // 設定顏色樣式
    // ColorStyleUniform = 0    : 物件以單一顏色渲染。使用的顏色在baseColors、
    //                            singleHighlightColor和multiHighlightColor屬性中指定。
    // ColorStyleObjectGradient : 無論物件的高度如何,物件都將使用每個物件的全漸變進行著色。
    //                            使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate 屬性中指定。
    // ColorStyleRangeGradient  : 使用由物件的高度及其在Y軸上的位置確定的完整漸變的一部分對物件進行著色。
    //                            使用的漸變在baseGradients、singleHighlightGradient 和 multiHighlightGraduate屬性中指定。
    _pSurface3DSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
    // 漸變色
    QLinearGradient linearGradient;
    linearGradient.setColorAt(0.0, Qt::red);
    linearGradient.setColorAt(1.0, Qt::green);
    // 設定顏色
    _pSurface3DSeries->setBaseGradient(linearGradient);
    // 選中顏色
    // 漸變色2
    QLinearGradient linearGradient2;
    linearGradient2.setColorAt(0.0, Qt::yellow);
    linearGradient2.setColorAt(1.0, Qt::gray);
    _pSurface3DSeries->setSingleHighlightGradient(linearGradient2);
    _pSurface3DSeries->setSingleHighlightColor(Qt::red);
//    _pSurface3DSeries->setMultiHighlightGraduate(Qt::green);
#endif

#if 0
    // 設定漸進色
    QLinearGradient *pLinearGradient = new QLinearGradient(0, 0,100,100);
    pLinearGradient->setColorAt(0, Qt::red);
    pLinearGradient->setColorAt(1.0, Qt::blue);
    _pSurface3DSeries->setBaseGradient(*pLinearGradient);
#endif


    // 檢視新增該曲線
    _pQ3DSurface->addSeries(_pSurface3DSeries);
    // 設定陰影質量
    _pQ3DSurface->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);
    // 設定視角
    _pQ3DSurface->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetNone);
    // 設定子網格
    _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++)
        {
#if 0
            // 注意與笛卡爾座標進行對映
            *pSurfaceDataRow << QVector3D(m, n / 7 + m / 7, n);
#else
            // 注意與笛卡爾座標進行對映(超過180的下沉)
            *pSurfaceDataRow << QVector3D(m, n / 7 + m / 7 - (m > 180 ? n / 3 : 0), n);
#endif
        }
        *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 Q3dSurfaceColorWidget::resizeEvent(QResizeEvent *event)
{
#if 1
    if(_pContainer)
    {
        _pContainer->setGeometry(0, 50, rect().width(), rect().height() - 50);
        _pContainer->lower();
    }
#endif
}


void Q3dSurfaceColorWidget::on_comboBox_cameraPreset_currentIndexChanged(int index)
{
    setCameraPreset((Q3DCamera::CameraPreset)(index - 1));
}

工程模板v1.3.0

  在這裡插入圖片描述

相關文章