mirror of https://github.com/qt/qtdatavis3d.git
Initial version of Galaxy.
Change-Id: I29898bed342022290c8c8a6c4459969ffba3df56 Reviewed-by: Mika Salmela <mika.salmela@theqtcompany.com>
This commit is contained in:
parent
9644652e37
commit
deaab27525
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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/*
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue