summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/galaxy/cumulativedistributor.cpp143
-rw-r--r--tests/galaxy/cumulativedistributor.h76
-rw-r--r--tests/galaxy/galaxy.pro23
-rw-r--r--tests/galaxy/galaxydata.cpp340
-rw-r--r--tests/galaxy/galaxydata.h103
-rw-r--r--tests/galaxy/main.cpp128
-rw-r--r--tests/galaxy/star.cpp51
-rw-r--r--tests/galaxy/star.h43
8 files changed, 907 insertions, 0 deletions
diff --git a/tests/galaxy/cumulativedistributor.cpp b/tests/galaxy/cumulativedistributor.cpp
new file mode 100644
index 00000000..0171b4d4
--- /dev/null
+++ b/tests/galaxy/cumulativedistributor.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.io
+**
+** This file is part of the Qt Data Visualization module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+****************************************************************************/
+
+/*
+ * Galaxy creation code obtained from http://beltoforion.de/galaxy/galaxy_en.html
+ * Thanks to Ingo Berg, great work.
+ * Licensed under a Creative Commons Attribution 3.0 License
+ * http://creativecommons.org/licenses/by/3.0/
+ */
+
+#include "cumulativedistributor.h"
+
+#include <QDebug>
+
+CumulativeDistributor::CumulativeDistributor()
+ : m_pDistFun(NULL),
+ m_vM1(),
+ m_vY1(),
+ m_vX1(),
+ m_vM2(),
+ m_vY2(),
+ m_vX2()
+{
+}
+
+CumulativeDistributor::~CumulativeDistributor()
+{
+}
+
+void CumulativeDistributor::setupRealistic(qreal I0, qreal k, qreal a,
+ qreal RBulge, qreal min, qreal max,
+ int nSteps)
+{
+ m_fMin = min;
+ m_fMax = max;
+ m_nSteps = nSteps;
+
+ m_I0 = I0;
+ m_k = k;
+ m_a = a;
+ m_RBulge = RBulge;
+
+ m_pDistFun = &CumulativeDistributor::Intensity;
+
+ // build the distribution function
+ buildCDF(m_nSteps);
+}
+
+void CumulativeDistributor::buildCDF(int nSteps)
+{
+ qreal h = (m_fMax - m_fMin) / nSteps;
+ qreal x = 0, y = 0;
+
+ m_vX1.clear();
+ m_vY1.clear();
+ m_vX2.clear();
+ m_vM1.clear();
+ m_vM1.clear();
+
+ // Simpson rule for integration of the distribution function
+ m_vY1.push_back(0.0);
+ m_vX1.push_back(0.0);
+ for (int i = 0; i < nSteps; i += 2) {
+ x = (i + 2) * h;
+ y += h/3 * ((this->*m_pDistFun)(m_fMin + i*h) + 4*(this->*m_pDistFun)(m_fMin + (i+1)*h) + (this->*m_pDistFun)(m_fMin + (i+2)*h) );
+
+ m_vM1.push_back((y - m_vY1.back()) / (2*h));
+ m_vX1.push_back(x);
+ m_vY1.push_back(y);
+ }
+
+ // normieren
+ for (int i = 0; i < m_vM1.size(); i++) {
+ m_vY1[i] /= m_vY1.back();
+ m_vM1[i] /= m_vY1.back();
+ }
+
+ m_vY2.clear();
+ m_vM2.clear();
+ m_vY2.push_back(0.0);
+
+ qreal p = 0;
+ h = 1.0 / nSteps;
+ for (int i = 1, k = 0; i < nSteps; ++i) {
+ p = (qreal)i * h;
+
+ for (; m_vY1[k+1] <= p; ++k) {
+ }
+
+ y = m_vX1[k] + (p - m_vY1[k]) / m_vM1[k];
+
+ m_vM2.push_back( (y - m_vY2.back()) / h);
+ m_vX2.push_back(p);
+ m_vY2.push_back(y);
+ }
+}
+
+qreal CumulativeDistributor::valFromProp(qreal fVal)
+{
+ if (fVal < 0.0 || fVal > 1.0)
+ throw std::runtime_error("out of range");
+
+ qreal h = 1.0 / m_vY2.size();
+
+ int i = int(fVal / h);
+ qreal remainder = fVal - i*h;
+
+ int min = qMin(m_vY2.size(), m_vM2.size());
+ if (i >= min)
+ i = min - 1;
+
+ return (m_vY2[i] + m_vM2[i] * remainder);
+}
+
+qreal CumulativeDistributor::IntensityBulge(qreal R, qreal I0, qreal k)
+{
+ return I0 * exp(-k * pow(R, 0.25));
+}
+
+qreal CumulativeDistributor::IntensityDisc(qreal R, qreal I0, qreal a)
+{
+ return I0 * exp(-R/a);
+}
+
+qreal CumulativeDistributor::Intensity(qreal x)
+{
+ return (x < m_RBulge) ? IntensityBulge(x, m_I0, m_k) : IntensityDisc(x - m_RBulge, IntensityBulge(m_RBulge, m_I0, m_k), m_a);
+}
diff --git a/tests/galaxy/cumulativedistributor.h b/tests/galaxy/cumulativedistributor.h
new file mode 100644
index 00000000..ba7a6dfc
--- /dev/null
+++ b/tests/galaxy/cumulativedistributor.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.io
+**
+** This file is part of the Qt Data Visualization module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+****************************************************************************/
+
+/*
+ * Galaxy creation code obtained from http://beltoforion.de/galaxy/galaxy_en.html
+ * Thanks to Ingo Berg, great work.
+ * Licensed under a Creative Commons Attribution 3.0 License
+ * http://creativecommons.org/licenses/by/3.0/
+ */
+
+#ifndef CUMULATIVEDISTRIBUTOR_H
+#define CUMULATIVEDISTRIBUTOR_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/QVector2D>
+#include <QtCore/QVector>
+
+class CumulativeDistributor
+{
+public:
+ typedef qreal (CumulativeDistributor::*dist_fun_t)(qreal x);
+
+ CumulativeDistributor();
+ virtual ~CumulativeDistributor();
+
+ qreal PropFromVal(qreal fVal);
+ qreal ValFromProp(qreal fVal);
+
+ void setupRealistic(qreal I0, qreal k, qreal a, qreal RBulge, qreal min,
+ qreal max, int nSteps);
+ qreal valFromProp(qreal fVal);
+
+private:
+ dist_fun_t m_pDistFun;
+ qreal m_fMin;
+ qreal m_fMax;
+ qreal m_fWidth;
+ int m_nSteps;
+
+ // parameters for realistic star distribution
+ qreal m_I0;
+ qreal m_k;
+ qreal m_a;
+ qreal m_RBulge;
+
+ QVector<qreal> m_vM1;
+ QVector<qreal> m_vY1;
+ QVector<qreal> m_vX1;
+
+ QVector<qreal> m_vM2;
+ QVector<qreal> m_vY2;
+ QVector<qreal> m_vX2;
+
+ void buildCDF(int nSteps);
+
+ qreal IntensityBulge(qreal R, qreal I0, qreal k);
+ qreal IntensityDisc(qreal R, qreal I0, qreal a);
+ qreal Intensity(qreal x);
+};
+
+#endif // CUMULATIVEDISTRIBUTOR_H
diff --git a/tests/galaxy/galaxy.pro b/tests/galaxy/galaxy.pro
new file mode 100644
index 00000000..0b602e16
--- /dev/null
+++ b/tests/galaxy/galaxy.pro
@@ -0,0 +1,23 @@
+android|ios|winrt {
+ error( "This example is not supported for android, ios, or winrt." )
+}
+
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
+
+SOURCES += main.cpp \
+ galaxydata.cpp \
+ star.cpp \
+ cumulativedistributor.cpp
+
+HEADERS += \
+ cumulativedistributor.h \
+ galaxydata.h \
+ star.h
+
+QT += widgets
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
+
diff --git a/tests/galaxy/galaxydata.cpp b/tests/galaxy/galaxydata.cpp
new file mode 100644
index 00000000..43dbd9e8
--- /dev/null
+++ b/tests/galaxy/galaxydata.cpp
@@ -0,0 +1,340 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.io
+**
+** This file is part of the Qt Data Visualization module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+****************************************************************************/
+
+/*
+ * Galaxy creation code obtained from http://beltoforion.de/galaxy/galaxy_en.html
+ * Thanks to Ingo Berg, great work.
+ * Licensed under a Creative Commons Attribution 3.0 License
+ * http://creativecommons.org/licenses/by/3.0/
+ *
+ */
+
+#include "galaxydata.h"
+#include "cumulativedistributor.h"
+#include "star.h"
+#include <QtDataVisualization/qscatterdataproxy.h>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qscatter3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
+#include <QtCore/qmath.h>
+#include <QPainter>
+
+#include <QDebug>
+
+using namespace QtDataVisualization;
+
+static const int numOfStars = 30000;
+static const qreal rand_max = qreal(RAND_MAX);
+
+GalaxyData::GalaxyData(Q3DScatter *scatter,
+ qreal rad,
+ qreal radCore,
+ qreal deltaAng,
+ qreal ex1,
+ qreal ex2)
+ : m_graph(scatter),
+ m_pStars(0),
+ m_radGalaxy(rad),
+ m_radCore(radCore),
+ m_angleOffset(deltaAng),
+ m_elEx1(ex1),
+ m_elEx2(ex2),
+ m_radFarField(m_radGalaxy * 2),
+ m_filtered(false),
+ m_tableSize(0)
+{
+ m_graph->activeTheme()->setType(Q3DTheme::ThemeEbony);
+ m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);
+
+ m_graph->axisX()->setRange(-25000.0f, 25000.0f);
+ //m_graph->axisY()->setRange(m_minY, m_minY + m_rangeY);
+ m_graph->axisZ()->setRange(-25000.0f, 25000.0f);
+
+ createNormalSeries();
+
+ m_dataArray = new QScatterDataArray;
+ m_dataArray->resize(numOfStars);
+
+ createGalaxy();
+}
+
+GalaxyData::~GalaxyData()
+{
+ delete m_graph;
+}
+
+void GalaxyData::createGalaxy()
+{
+ if (m_pStars)
+ delete [] m_pStars;
+ m_pStars = new Star[numOfStars];
+
+ m_minx = 9999.9;
+ m_maxx = -9999.0;
+ m_miny = 9999.9;
+ m_maxy = -9999.0;
+
+ // First star is the black hole at the center
+ m_pStars[0].m_a = 0;
+ m_pStars[0].m_b = 0;
+ m_pStars[0].m_angle = 0;
+ m_pStars[0].m_theta = 0;
+ m_pStars[0].m_center = QVector2D(0.0f, 0.0f);
+ m_pStars[0].calcXY();
+
+ // second star is at the edge of the core area
+ m_pStars[1].m_a = m_radCore;
+ m_pStars[1].m_b = m_radCore * getExcentricity(m_radCore);
+ m_pStars[1].m_angle = getAngularOffset(m_radCore);
+ m_pStars[1].m_theta = 0;
+ m_pStars[1].m_center = QVector2D(0.0f, 0.0f);
+ m_pStars[1].calcXY();
+ checkMinMax(m_pStars[1]);
+
+ // third star is at the edge of the disk
+ m_pStars[2].m_a = m_radGalaxy;
+ m_pStars[2].m_b = m_radGalaxy * getExcentricity(m_radGalaxy);
+ m_pStars[2].m_angle = getAngularOffset(m_radGalaxy);
+ m_pStars[2].m_theta = 0;
+ m_pStars[2].m_center = QVector2D(0.0f, 0.0f);
+ m_pStars[2].calcXY();
+ checkMinMax(m_pStars[2]);
+
+ CumulativeDistributor cd;
+ cd.setupRealistic(1.0, // Maximalintensität
+ 0.02, // k (bulge)
+ m_radGalaxy/3.0, // disc skalenlänge
+ m_radCore, // bulge radius
+ 0, // start der intensitätskurve
+ m_radFarField, // ende der intensitätskurve
+ 1000.0); // Anzahl der stützstellen
+
+ for (int i = 3; i < numOfStars; ++i) {
+ qreal rad = cd.valFromProp(qreal(qrand()) / rand_max);
+
+ m_pStars[i].m_a = rad;
+ m_pStars[i].m_b = rad * getExcentricity(rad);
+ m_pStars[i].m_angle = getAngularOffset(rad);
+ m_pStars[i].m_theta = 360.0 * ((double)rand() / RAND_MAX);
+ m_pStars[i].m_center = QVector2D(0.0f, 0.0f);
+ m_pStars[i].calcXY();
+
+ checkMinMax(m_pStars[i]);
+ }
+
+ qreal max = qMax(m_maxx, m_maxy);
+ qreal min = -qMin(m_minx, m_miny);
+ max = qMax(min, max);
+ m_range = int((max + 500.0) / 1000.0) * 1000;
+ m_graph->axisX()->setRange(-float(m_range), float(m_range));
+ m_graph->axisZ()->setRange(-float(m_range), float(m_range));
+
+ if (!m_filtered)
+ createNormalDataView();
+ else
+ createFilteredView();
+}
+
+void GalaxyData::createNormalSeries()
+{
+ QScatterDataProxy *proxy = new QScatterDataProxy;
+ QScatter3DSeries *series = new QScatter3DSeries(proxy);
+ series->setMesh(QAbstract3DSeries::MeshPoint);
+ m_graph->addSeries(series);
+}
+
+void GalaxyData::createNormalDataView()
+{
+ QScatterDataItem *ptrToDataArray = &m_dataArray->first();
+
+ for (uint i = 0; i < numOfStars; i++) {
+ ptrToDataArray->setPosition(QVector3D(m_pStars[i].m_pos.x(),
+ 0.0f,
+ m_pStars[i].m_pos.y()));
+ ptrToDataArray++;
+ }
+
+ m_graph->seriesList().at(0)->dataProxy()->resetArray(m_dataArray);
+}
+
+void GalaxyData::createFilteredView()
+{
+ int steps = (m_range / 1000) * 2;
+ int tableSize = steps * steps;
+ int *table = new int[tableSize];
+ for (int i = 0; i < tableSize; i++)
+ table[i] = 0;
+ qreal add = qreal(m_range);
+ int max = 0;
+
+ for (uint i = 0; i < numOfStars; i++) {
+ int x = int(m_pStars[i].m_pos.x() + add) / 1000;
+ int y = int(m_pStars[i].m_pos.y() + add) / 1000;
+ table[y * steps + x] = table[y * steps + x] + 1;
+
+ if (max < table[y * steps + x])
+ max = table[y * steps + x];
+ }
+
+ QLinearGradient gr(0, 0, 1, 100);
+ gr.setColorAt(0.0, Qt::white);
+ gr.setColorAt(0.05, Qt::green);
+// gr.setColorAt(0.10, Qt::red);
+// gr.setColorAt(0.15, Qt::darkGreen);
+ gr.setColorAt(1.0, Qt::red);
+ QImage image(QSize(1, 100), QImage::Format_RGB32);
+ QPainter pmp(&image);
+ pmp.setBrush(QBrush(gr));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 1, 100);
+
+ if (tableSize != m_tableSize) {
+ createFilteredSeries(tableSize);
+ m_tableSize = tableSize;
+ }
+
+ for (int y = 0; y < steps; y++) {
+ for (int x = 0; x < steps; x++) {
+ if (table[y * steps + x]) {
+ QScatterDataArray *dataArray = new QScatterDataArray;
+ dataArray->resize(1);
+ QScatterDataItem *ptrToDataArray = &dataArray->first();
+ ptrToDataArray->setPosition(QVector3D(float(x) * 1000.0f - add + 500.0f,
+ (float(table[y * steps + x]) / float(max)) * 2.0f - 1.0f,
+ float(y) * 1000.0f - add + 500.0f));
+
+ QScatter3DSeries *series = m_graph->seriesList().at(y * steps + x);
+ series->dataProxy()->resetArray(dataArray);
+ int pos = (float(table[y * steps + x]) / float(max)) * 100;
+ pos = qMin(pos, 99);
+ QRgb color = image.pixel(0, pos);
+ series->setBaseColor(QColor(color));
+ series->setItemSize(0.1f);
+ }
+ }
+ }
+
+ qDebug() << "max = " << max;
+}
+
+void GalaxyData::createFilteredSeries(int tableSize)
+{
+ int size = m_graph->seriesList().size();
+ for (int i = 0; i < size; i++)
+ m_graph->removeSeries(m_graph->seriesList().at(0));
+
+ for (int i = 0; i < tableSize; i++) {
+ QScatterDataProxy *proxy = new QScatterDataProxy;
+ QScatter3DSeries *series = new QScatter3DSeries(proxy);
+ series->setMesh(QAbstract3DSeries::MeshCube);
+ m_graph->addSeries(series);
+ }
+}
+
+void GalaxyData::checkMinMax(const Star &star)
+{
+ if (star.m_pos.x() < m_minx)
+ m_minx = star.m_pos.x();
+ if (star.m_pos.x() > m_maxx)
+ m_maxx = star.m_pos.x();
+ if (star.m_pos.y() < m_miny)
+ m_miny = star.m_pos.y();
+ if (star.m_pos.y() > m_maxy)
+ m_maxy = star.m_pos.y();
+}
+
+qreal GalaxyData::getExcentricity(qreal r) const
+{
+ if (r < m_radCore)
+ {
+ // Core region of the galaxy. Innermost part is round
+ // excentricity increasing linear to the border of the core.
+ return 1 + (r / m_radCore) * (m_elEx1-1);
+ } else if (r > m_radCore && r <= m_radGalaxy) {
+ return m_elEx1 + (r - m_radCore) / (m_radGalaxy - m_radCore) * (m_elEx2 - m_elEx1);
+ } else if (r > m_radGalaxy && r < m_radFarField) {
+ // excentricity is slowly reduced to 1.
+ return m_elEx2 + (r - m_radGalaxy) / (m_radFarField - m_radGalaxy) * (1 - m_elEx2);
+ } else {
+ return 1.0;
+ }
+}
+
+qreal GalaxyData::getAngularOffset(qreal rad) const
+{
+ return rad * m_angleOffset;
+}
+
+void GalaxyData::radiusGalaxyChanged(int value)
+{
+ m_radGalaxy = qreal(value);
+ createGalaxy();
+}
+
+void GalaxyData::radiusCoreChanged(int value)
+{
+ m_radCore = qreal(value);
+ createGalaxy();
+}
+
+void GalaxyData::angleOffsetChanged(int value)
+{
+ m_angleOffset = qreal(value) / 100000.0;
+ createGalaxy();
+}
+
+void GalaxyData::eccentricityInnerChanged(int value)
+{
+ m_elEx1 = qreal(value) / 100.0;
+ createGalaxy();
+}
+
+void GalaxyData::eccentricityOuterChanged(int value)
+{
+ m_elEx2 = qreal(value) / 100.0;
+ createGalaxy();
+}
+
+void GalaxyData::setFilteredEnabled(bool enabled)
+{
+ m_filtered = enabled;
+ if (enabled) {
+ m_graph->removeSeries(m_graph->seriesList().at(0));
+
+ createFilteredView();
+ } else {
+ int size = m_graph->seriesList().size();
+ for (int i = 0; i < size; i++)
+ m_graph->removeSeries(m_graph->seriesList().at(0));
+ m_tableSize = 0;
+
+ createNormalSeries();
+ createNormalDataView();
+ }
+}
+
+void GalaxyData::resetValues()
+{
+ m_radiusGalaxySlider->setValue(15000);
+ m_radiusCoreSlider->setValue(4000);
+ m_angleOffsetSlider->setValue(40);
+ m_eccentricityInnerSlider->setValue(90);
+ m_eccentricityOuterSlider->setValue(90);
+}
diff --git a/tests/galaxy/galaxydata.h b/tests/galaxy/galaxydata.h
new file mode 100644
index 00000000..88a9025a
--- /dev/null
+++ b/tests/galaxy/galaxydata.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.io
+**
+** This file is part of the Qt Data Visualization module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+****************************************************************************/
+
+#ifndef SCATTERDATAMODIFIER_H
+#define SCATTERDATAMODIFIER_H
+
+#include "star.h"
+
+#include <QtDataVisualization/q3dscatter.h>
+#include <QtDataVisualization/qabstract3dseries.h>
+#include <QtGui/QFont>
+#include <QtWidgets/QSlider>
+
+using namespace QtDataVisualization;
+
+class GalaxyData : public QObject
+{
+ Q_OBJECT
+public:
+ explicit GalaxyData(Q3DScatter *scatter,
+ qreal rad = 13000,
+ qreal radCore = 4000.0,
+ qreal deltaAng = 0.0004,
+ qreal ex1 = 0.9,
+ qreal ex2 = 0.9);
+ ~GalaxyData();
+
+ qreal getExcentricity(qreal r) const;
+ qreal getAngularOffset(qreal rad) const;
+
+ void radiusGalaxyChanged(int value);
+ void radiusCoreChanged(int value);
+ void angleOffsetChanged(int value);
+ void eccentricityInnerChanged(int value);
+ void eccentricityOuterChanged(int value);
+ void resetValues();
+ void setFilteredEnabled(bool enabled);
+ inline void setSliders(QSlider *rg,
+ QSlider *rc,
+ QSlider *ao,
+ QSlider *ei,
+ QSlider *eo) {
+ m_radiusGalaxySlider = rg;
+ m_radiusCoreSlider = rc;
+ m_angleOffsetSlider = ao;
+ m_eccentricityInnerSlider = ei;
+ m_eccentricityOuterSlider = eo;
+ }
+
+private:
+ void createGalaxy();
+ void checkMinMax(const Star &star);
+ void createNormalDataView();
+ void createFilteredView();
+ void createNormalSeries();
+ void createFilteredSeries(int tableSize);
+ qreal value;
+
+private:
+ Q3DScatter *m_graph;
+ QScatterDataArray *m_dataArray;
+ Star *m_pStars;
+
+ qreal m_elEx1; // Excentricity of the innermost ellipse
+ qreal m_elEx2; // Excentricity of the outermost ellipse
+
+ qreal m_angleOffset; // Angular offset per parsec
+
+ qreal m_radCore; // Radius of the inner core
+ qreal m_radGalaxy; // Radius of the galaxy
+ qreal m_radFarField; // The radius after which all density waves must have circular shape
+
+ QSlider *m_radiusGalaxySlider;
+ QSlider *m_radiusCoreSlider;
+ QSlider *m_angleOffsetSlider;
+ QSlider *m_eccentricityInnerSlider;
+ QSlider *m_eccentricityOuterSlider;
+
+ qreal m_minx = 9999.9;
+ qreal m_maxx = -9999.0;
+ qreal m_miny = 9999.9;
+ qreal m_maxy = -9999.0;
+ int m_range;
+ bool m_filtered;
+ int m_tableSize;
+};
+
+#endif
diff --git a/tests/galaxy/main.cpp b/tests/galaxy/main.cpp
new file mode 100644
index 00000000..1a6ee7b2
--- /dev/null
+++ b/tests/galaxy/main.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.io
+**
+** This file is part of the Qt Data Visualization module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+****************************************************************************/
+
+#include "galaxydata.h"
+
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QHBoxLayout>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QFontComboBox>
+#include <QtWidgets/QLabel>
+#include <QtGui/QScreen>
+#include <QtGui/QFontDatabase>
+
+int main(int argc, char **argv)
+{
+ //! [0]
+ QApplication app(argc, argv);
+ Q3DScatter *graph = new Q3DScatter();
+ QWidget *container = QWidget::createWindowContainer(graph);
+ //! [0]
+
+ QSize screenSize = graph->screen()->size();
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.5));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+ vLayout->setAlignment(Qt::AlignTop);
+
+ widget->setWindowTitle(QStringLiteral("A Galaxy"));
+
+ QSlider *radiusGalaxySlider = new QSlider(Qt::Horizontal, widget);
+ radiusGalaxySlider->setMinimum(1000);
+ radiusGalaxySlider->setMaximum(40000);
+ radiusGalaxySlider->setValue(15000);
+ radiusGalaxySlider->setEnabled(true);
+
+ QSlider *radiusCoreSlider = new QSlider(Qt::Horizontal, widget);
+ radiusCoreSlider->setMinimum(1000);
+ radiusCoreSlider->setMaximum(30000);
+ radiusCoreSlider->setValue(4000);
+ radiusCoreSlider->setEnabled(true);
+
+ QSlider *angleOffsetSlider = new QSlider(Qt::Horizontal, widget);
+ angleOffsetSlider->setMinimum(10);
+ angleOffsetSlider->setMaximum(70);
+ angleOffsetSlider->setValue(40);
+ angleOffsetSlider->setEnabled(true);
+
+ QSlider *eccentricityInnerSlider = new QSlider(Qt::Horizontal, widget);
+ eccentricityInnerSlider->setMinimum(10);
+ eccentricityInnerSlider->setMaximum(200);
+ eccentricityInnerSlider->setValue(90);
+ eccentricityInnerSlider->setEnabled(true);
+
+ QSlider *eccentricityOuterSlider = new QSlider(Qt::Horizontal, widget);
+ eccentricityOuterSlider->setMinimum(10);
+ eccentricityOuterSlider->setMaximum(200);
+ eccentricityOuterSlider->setValue(90);
+ eccentricityOuterSlider->setEnabled(true);
+
+ QPushButton *resetButton = new QPushButton(widget);
+ resetButton->setText(QStringLiteral("Reset values"));
+
+ QCheckBox *filteredCheckBox = new QCheckBox(widget);
+ filteredCheckBox->setText(QStringLiteral("Filtered"));
+ filteredCheckBox->setChecked(false);
+
+ vLayout->addWidget(new QLabel(QStringLiteral("Galaxy radius")));
+ vLayout->addWidget(radiusGalaxySlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Core radius")));
+ vLayout->addWidget(radiusCoreSlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Angle offset")));
+ vLayout->addWidget(angleOffsetSlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Eccentricity inner")));
+ vLayout->addWidget(eccentricityInnerSlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Eccentricity outer")));
+ vLayout->addWidget(eccentricityOuterSlider);
+ vLayout->addWidget(resetButton);
+ vLayout->addWidget(filteredCheckBox);
+
+ GalaxyData *modifier = new GalaxyData(graph);
+
+ QObject::connect(radiusGalaxySlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::radiusGalaxyChanged);
+ QObject::connect(radiusCoreSlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::radiusCoreChanged);
+ QObject::connect(angleOffsetSlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::angleOffsetChanged);
+ QObject::connect(eccentricityInnerSlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::eccentricityInnerChanged);
+ QObject::connect(eccentricityOuterSlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::eccentricityOuterChanged);
+ QObject::connect(resetButton, &QPushButton::clicked,
+ modifier, &GalaxyData::resetValues);
+ QObject::connect(filteredCheckBox, &QCheckBox::stateChanged,
+ modifier, &GalaxyData::setFilteredEnabled);
+
+ modifier->setSliders(radiusGalaxySlider, radiusCoreSlider, angleOffsetSlider,
+ eccentricityInnerSlider, eccentricityOuterSlider);
+
+ widget->show();
+ return app.exec();
+}
diff --git a/tests/galaxy/star.cpp b/tests/galaxy/star.cpp
new file mode 100644
index 00000000..dd94698c
--- /dev/null
+++ b/tests/galaxy/star.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.io
+**
+** This file is part of the Qt Data Visualization module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+****************************************************************************/
+
+#include "star.h"
+
+#include <QtCore/qmath.h>
+
+static const double DEG_TO_RAD = M_PI / 180.0;
+
+Star::Star()
+ : m_theta(0),
+ m_a(0),
+ m_b(0),
+ m_center(QVector2D(0.0f, 0.0f))
+{
+}
+
+const void Star::calcXY()
+{
+ qreal &a = m_a;
+ qreal &b = m_b;
+ qreal &theta = m_theta;
+ const QVector2D &p = m_center;
+
+ qreal beta = -m_angle;
+ qreal alpha = theta * DEG_TO_RAD;
+
+ // temporaries to save cpu time
+ qreal cosalpha = qCos(alpha);
+ qreal sinalpha = qSin(alpha);
+ qreal cosbeta = qCos(beta);
+ qreal sinbeta = qSin(beta);
+
+ m_pos = QVector2D(p.x() + (a * cosalpha * cosbeta - b * sinalpha * sinbeta),
+ p.y() + (a * cosalpha * sinbeta + b * sinalpha * cosbeta));
+}
diff --git a/tests/galaxy/star.h b/tests/galaxy/star.h
new file mode 100644
index 00000000..4b18a405
--- /dev/null
+++ b/tests/galaxy/star.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.io
+**
+** This file is part of the Qt Data Visualization module.
+**
+** Licensees holding valid commercial license for Qt may use this file in
+** accordance with the Qt License Agreement provided with the Software
+** or, alternatively, in accordance with the terms contained in a written
+** agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.io
+**
+****************************************************************************/
+
+#ifndef STAR_H
+#define STAR_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/QVector2D>
+
+class Star
+{
+public:
+ Star();
+ const void calcXY();
+
+ qreal m_theta; // position auf der ellipse
+ qreal m_velTheta; // angular velocity
+ qreal m_angle; // Schräglage der Ellipse
+ qreal m_a; // kleine halbachse
+ qreal m_b; // große halbachse
+ qreal m_temp; // star temperature
+ qreal m_mag; // brightness;
+ QVector2D m_center; // center of the elliptical orbit
+ QVector2D m_vel; // Current velocity (calculated)
+ QVector2D m_pos; // current position in kartesion koordinates
+};
+
+#endif // STAR_H