1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Data Visualization module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include "surfacegraph.h"
31
32#include <QtDataVisualization/QValue3DAxis>
33#include <QtDataVisualization/Q3DTheme>
34#include <QtGui/QImage>
35#include <QtCore/qmath.h>
36
37using namespace QtDataVisualization;
38
39const int sampleCountX = 50;
40const int sampleCountZ = 50;
41const int heightMapGridStepX = 6;
42const int heightMapGridStepZ = 6;
43const float sampleMin = -8.0f;
44const float sampleMax = 8.0f;
45
46SurfaceGraph::SurfaceGraph(Q3DSurface *surface)
47 : m_graph(surface)
48{
49 m_graph->setAxisX(new QValue3DAxis);
50 m_graph->setAxisY(new QValue3DAxis);
51 m_graph->setAxisZ(new QValue3DAxis);
52
53 //! [0]
54 m_sqrtSinProxy = new QSurfaceDataProxy();
55 m_sqrtSinSeries = new QSurface3DSeries(m_sqrtSinProxy);
56 //! [0]
57 fillSqrtSinProxy();
58
59 //! [2]
60 QImage heightMapImage(":/maps/mountain");
61 m_heightMapProxy = new QHeightMapSurfaceDataProxy(heightMapImage);
62 m_heightMapSeries = new QSurface3DSeries(m_heightMapProxy);
63 m_heightMapSeries->setItemLabelFormat(QStringLiteral("(@xLabel, @zLabel): @yLabel"));
64 m_heightMapProxy->setValueRanges(minX: 34.0f, maxX: 40.0f, minZ: 18.0f, maxZ: 24.0f);
65 //! [2]
66 m_heightMapWidth = heightMapImage.width();
67 m_heightMapHeight = heightMapImage.height();
68}
69
70SurfaceGraph::~SurfaceGraph()
71{
72 delete m_graph;
73}
74
75//! [1]
76void SurfaceGraph::fillSqrtSinProxy()
77{
78 float stepX = (sampleMax - sampleMin) / float(sampleCountX - 1);
79 float stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1);
80
81 QSurfaceDataArray *dataArray = new QSurfaceDataArray;
82 dataArray->reserve(alloc: sampleCountZ);
83 for (int i = 0 ; i < sampleCountZ ; i++) {
84 QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX);
85 // Keep values within range bounds, since just adding step can cause minor drift due
86 // to the rounding errors.
87 float z = qMin(a: sampleMax, b: (i * stepZ + sampleMin));
88 int index = 0;
89 for (int j = 0; j < sampleCountX; j++) {
90 float x = qMin(a: sampleMax, b: (j * stepX + sampleMin));
91 float R = qSqrt(v: z * z + x * x) + 0.01f;
92 float y = (qSin(v: R) / R + 0.24f) * 1.61f;
93 (*newRow)[index++].setPosition(QVector3D(x, y, z));
94 }
95 *dataArray << newRow;
96 }
97
98 m_sqrtSinProxy->resetArray(newArray: dataArray);
99}
100//! [1]
101
102void SurfaceGraph::enableSqrtSinModel(bool enable)
103{
104 if (enable) {
105 //! [3]
106 m_sqrtSinSeries->setDrawMode(QSurface3DSeries::DrawSurfaceAndWireframe);
107 m_sqrtSinSeries->setFlatShadingEnabled(true);
108
109 m_graph->axisX()->setLabelFormat("%.2f");
110 m_graph->axisZ()->setLabelFormat("%.2f");
111 m_graph->axisX()->setRange(min: sampleMin, max: sampleMax);
112 m_graph->axisY()->setRange(min: 0.0f, max: 2.0f);
113 m_graph->axisZ()->setRange(min: sampleMin, max: sampleMax);
114 m_graph->axisX()->setLabelAutoRotation(30);
115 m_graph->axisY()->setLabelAutoRotation(90);
116 m_graph->axisZ()->setLabelAutoRotation(30);
117
118 m_graph->removeSeries(series: m_heightMapSeries);
119 m_graph->addSeries(series: m_sqrtSinSeries);
120 //! [3]
121
122 //! [8]
123 // Reset range sliders for Sqrt&Sin
124 m_rangeMinX = sampleMin;
125 m_rangeMinZ = sampleMin;
126 m_stepX = (sampleMax - sampleMin) / float(sampleCountX - 1);
127 m_stepZ = (sampleMax - sampleMin) / float(sampleCountZ - 1);
128 m_axisMinSliderX->setMaximum(sampleCountX - 2);
129 m_axisMinSliderX->setValue(0);
130 m_axisMaxSliderX->setMaximum(sampleCountX - 1);
131 m_axisMaxSliderX->setValue(sampleCountX - 1);
132 m_axisMinSliderZ->setMaximum(sampleCountZ - 2);
133 m_axisMinSliderZ->setValue(0);
134 m_axisMaxSliderZ->setMaximum(sampleCountZ - 1);
135 m_axisMaxSliderZ->setValue(sampleCountZ - 1);
136 //! [8]
137 }
138}
139
140void SurfaceGraph::enableHeightMapModel(bool enable)
141{
142 if (enable) {
143 //! [4]
144 m_heightMapSeries->setDrawMode(QSurface3DSeries::DrawSurface);
145 m_heightMapSeries->setFlatShadingEnabled(false);
146
147 m_graph->axisX()->setLabelFormat("%.1f N");
148 m_graph->axisZ()->setLabelFormat("%.1f E");
149 m_graph->axisX()->setRange(min: 34.0f, max: 40.0f);
150 m_graph->axisY()->setAutoAdjustRange(true);
151 m_graph->axisZ()->setRange(min: 18.0f, max: 24.0f);
152
153 m_graph->axisX()->setTitle(QStringLiteral("Latitude"));
154 m_graph->axisY()->setTitle(QStringLiteral("Height"));
155 m_graph->axisZ()->setTitle(QStringLiteral("Longitude"));
156
157 m_graph->removeSeries(series: m_sqrtSinSeries);
158 m_graph->addSeries(series: m_heightMapSeries);
159 //! [4]
160
161 // Reset range sliders for height map
162 int mapGridCountX = m_heightMapWidth / heightMapGridStepX;
163 int mapGridCountZ = m_heightMapHeight / heightMapGridStepZ;
164 m_rangeMinX = 34.0f;
165 m_rangeMinZ = 18.0f;
166 m_stepX = 6.0f / float(mapGridCountX - 1);
167 m_stepZ = 6.0f / float(mapGridCountZ - 1);
168 m_axisMinSliderX->setMaximum(mapGridCountX - 2);
169 m_axisMinSliderX->setValue(0);
170 m_axisMaxSliderX->setMaximum(mapGridCountX - 1);
171 m_axisMaxSliderX->setValue(mapGridCountX - 1);
172 m_axisMinSliderZ->setMaximum(mapGridCountZ - 2);
173 m_axisMinSliderZ->setValue(0);
174 m_axisMaxSliderZ->setMaximum(mapGridCountZ - 1);
175 m_axisMaxSliderZ->setValue(mapGridCountZ - 1);
176 }
177}
178
179void SurfaceGraph::adjustXMin(int min)
180{
181 float minX = m_stepX * float(min) + m_rangeMinX;
182
183 int max = m_axisMaxSliderX->value();
184 if (min >= max) {
185 max = min + 1;
186 m_axisMaxSliderX->setValue(max);
187 }
188 float maxX = m_stepX * max + m_rangeMinX;
189
190 setAxisXRange(min: minX, max: maxX);
191}
192
193void SurfaceGraph::adjustXMax(int max)
194{
195 float maxX = m_stepX * float(max) + m_rangeMinX;
196
197 int min = m_axisMinSliderX->value();
198 if (max <= min) {
199 min = max - 1;
200 m_axisMinSliderX->setValue(min);
201 }
202 float minX = m_stepX * min + m_rangeMinX;
203
204 setAxisXRange(min: minX, max: maxX);
205}
206
207void SurfaceGraph::adjustZMin(int min)
208{
209 float minZ = m_stepZ * float(min) + m_rangeMinZ;
210
211 int max = m_axisMaxSliderZ->value();
212 if (min >= max) {
213 max = min + 1;
214 m_axisMaxSliderZ->setValue(max);
215 }
216 float maxZ = m_stepZ * max + m_rangeMinZ;
217
218 setAxisZRange(min: minZ, max: maxZ);
219}
220
221void SurfaceGraph::adjustZMax(int max)
222{
223 float maxX = m_stepZ * float(max) + m_rangeMinZ;
224
225 int min = m_axisMinSliderZ->value();
226 if (max <= min) {
227 min = max - 1;
228 m_axisMinSliderZ->setValue(min);
229 }
230 float minX = m_stepZ * min + m_rangeMinZ;
231
232 setAxisZRange(min: minX, max: maxX);
233}
234
235//! [5]
236void SurfaceGraph::setAxisXRange(float min, float max)
237{
238 m_graph->axisX()->setRange(min, max);
239}
240
241void SurfaceGraph::setAxisZRange(float min, float max)
242{
243 m_graph->axisZ()->setRange(min, max);
244}
245//! [5]
246
247//! [6]
248void SurfaceGraph::changeTheme(int theme)
249{
250 m_graph->activeTheme()->setType(Q3DTheme::Theme(theme));
251}
252//! [6]
253
254void SurfaceGraph::setBlackToYellowGradient()
255{
256 //! [7]
257 QLinearGradient gr;
258 gr.setColorAt(pos: 0.0, color: Qt::black);
259 gr.setColorAt(pos: 0.33, color: Qt::blue);
260 gr.setColorAt(pos: 0.67, color: Qt::red);
261 gr.setColorAt(pos: 1.0, color: Qt::yellow);
262
263 m_graph->seriesList().at(i: 0)->setBaseGradient(gr);
264 m_graph->seriesList().at(i: 0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
265 //! [7]
266}
267
268void SurfaceGraph::setGreenToRedGradient()
269{
270 QLinearGradient gr;
271 gr.setColorAt(pos: 0.0, color: Qt::darkGreen);
272 gr.setColorAt(pos: 0.5, color: Qt::yellow);
273 gr.setColorAt(pos: 0.8, color: Qt::red);
274 gr.setColorAt(pos: 1.0, color: Qt::darkRed);
275
276 m_graph->seriesList().at(i: 0)->setBaseGradient(gr);
277 m_graph->seriesList().at(i: 0)->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
278}
279
280

source code of qtdatavis3d/examples/datavisualization/surface/surfacegraph.cpp