From deaab27525898386ff9bf655e58810e744b518ee Mon Sep 17 00:00:00 2001 From: Mika Salmela Date: Thu, 4 Dec 2014 09:57:20 +0200 Subject: Initial version of Galaxy. Change-Id: I29898bed342022290c8c8a6c4459969ffba3df56 Reviewed-by: Mika Salmela --- tests/galaxy/cumulativedistributor.cpp | 143 ++++++++++++++ tests/galaxy/cumulativedistributor.h | 76 ++++++++ tests/galaxy/galaxy.pro | 23 +++ tests/galaxy/galaxydata.cpp | 340 +++++++++++++++++++++++++++++++++ tests/galaxy/galaxydata.h | 103 ++++++++++ tests/galaxy/main.cpp | 128 +++++++++++++ tests/galaxy/star.cpp | 51 +++++ tests/galaxy/star.h | 43 +++++ 8 files changed, 907 insertions(+) create mode 100644 tests/galaxy/cumulativedistributor.cpp create mode 100644 tests/galaxy/cumulativedistributor.h create mode 100644 tests/galaxy/galaxy.pro create mode 100644 tests/galaxy/galaxydata.cpp create mode 100644 tests/galaxy/galaxydata.h create mode 100644 tests/galaxy/main.cpp create mode 100644 tests/galaxy/star.cpp create mode 100644 tests/galaxy/star.h 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 + +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 +#include +#include + +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 m_vM1; + QVector m_vY1; + QVector m_vX1; + + QVector m_vM2; + QVector m_vY2; + QVector 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 +#include +#include +#include +#include +#include +#include +#include + +#include + +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 +#include +#include +#include + +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 + +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 +#include + +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 -- cgit v1.2.3