diff options
author | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-06-19 09:54:03 +0300 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@digia.com> | 2014-06-26 10:43:30 +0300 |
commit | ec195a34594dea6145af5e8f2fedc2f9401d0f14 (patch) | |
tree | 407a1553a16461bd495c25a0b75af5289bd44210 | |
parent | 03baf7bc0b3bf07625e1111fe50c5262047ee302 (diff) |
Polar graph support, phase one
- Polar property for toggling the polar mode
- Example added. Example docs will be added in another patch once all
of the functionality the example needs has been implemented.
- Only surface graph supports polar so far. Scatter to be added later.
Change-Id: I54d36f764ac1771ac88f73a5f3a2142f2309f6e8
Reviewed-by: Mika Salmela <mika.salmela@digia.com>
31 files changed, 2575 insertions, 240 deletions
diff --git a/examples/datavisualization/datavisualization.pro b/examples/datavisualization/datavisualization.pro index 1f72820c..c078630d 100644 --- a/examples/datavisualization/datavisualization.pro +++ b/examples/datavisualization/datavisualization.pro @@ -8,7 +8,8 @@ SUBDIRS += qmlbars \ qmloscilloscope \ qmlsurfacelayers \ qmlaxisformatter \ - qmlaxisdrag + qmlaxisdrag \ + qmlspectrogram !android:!ios { SUBDIRS += bars \ diff --git a/examples/datavisualization/qmlspectrogram/doc/src/qmlspectrogram.qdoc b/examples/datavisualization/qmlspectrogram/doc/src/qmlspectrogram.qdoc new file mode 100644 index 00000000..6ebba93b --- /dev/null +++ b/examples/datavisualization/qmlspectrogram/doc/src/qmlspectrogram.qdoc @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise 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.digia.com +** +****************************************************************************/ + +/*! + \example qmlspectrogram + \title Qt Quick 2 Spectrogram Example + \ingroup qtdatavisualization_examples + \brief Showing spectrogram graph in a QML application. + + The Qt Quick 2 surface example demonstrates how to show a polar and cartesian spectrograms + and how to utilize orthographic projection to show them in 2D. + + TODO!!! + + \image qmlspectrogram-example.png + + The focus in this example is on showing how to display spectrograms, so the basic + functionality is not explained. For more detailed QML example documentation, + see \l{Qt Quick 2 Scatter Example}. + + \section1 TODO + + \snippet qmlspectrogram/qml/qmlspectrogram/main.qml 0 + + \section1 Example contents +*/ diff --git a/examples/datavisualization/qmlspectrogram/main.cpp b/examples/datavisualization/qmlspectrogram/main.cpp new file mode 100644 index 00000000..87665564 --- /dev/null +++ b/examples/datavisualization/qmlspectrogram/main.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise 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.digia.com +** +****************************************************************************/ + +#include <QtGui/QGuiApplication> +#include <QtCore/QDir> +#include <QtQuick/QQuickView> +#include <QtQml/QQmlApplicationEngine> + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + + QQmlApplicationEngine engine; + + // The following are needed to make examples run without having to install the module + // in desktop environments. +#ifdef Q_OS_WIN + QString extraImportPath(QStringLiteral("%1/../../../../%2")); +#else + QString extraImportPath(QStringLiteral("%1/../../../%2")); +#endif + engine.addImportPath(extraImportPath.arg(QGuiApplication::applicationDirPath(), + QString::fromLatin1("qml"))); + engine.load(QUrl(QStringLiteral("qrc:/qml/qml/qmlspectrogram/main.qml"))); + + return app.exec(); +} diff --git a/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/Data.qml b/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/Data.qml new file mode 100644 index 00000000..fc54edf4 --- /dev/null +++ b/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/Data.qml @@ -0,0 +1,1560 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise 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.digia.com +** +****************************************************************************/ + +import QtQuick 2.1 + +Item { + property alias model: dataModel + + ListModel { + id: dataModel + ListElement{ radius: "0"; angle: "0"; value: "50"; } + ListElement{ radius: "0"; angle: "5"; value: "54.3578"; } + ListElement{ radius: "0"; angle: "10"; value: "58.6824"; } + ListElement{ radius: "0"; angle: "15"; value: "62.941"; } + ListElement{ radius: "0"; angle: "20"; value: "67.101"; } + ListElement{ radius: "0"; angle: "25"; value: "71.1309"; } + ListElement{ radius: "0"; angle: "30"; value: "75"; } + ListElement{ radius: "0"; angle: "35"; value: "78.6788"; } + ListElement{ radius: "0"; angle: "40"; value: "82.1394"; } + ListElement{ radius: "0"; angle: "45"; value: "85.3553"; } + ListElement{ radius: "0"; angle: "50"; value: "88.3022"; } + ListElement{ radius: "0"; angle: "55"; value: "90.9576"; } + ListElement{ radius: "0"; angle: "60"; value: "93.3013"; } + ListElement{ radius: "0"; angle: "65"; value: "95.3154"; } + ListElement{ radius: "0"; angle: "70"; value: "96.9846"; } + ListElement{ radius: "0"; angle: "75"; value: "98.2963"; } + ListElement{ radius: "0"; angle: "80"; value: "99.2404"; } + ListElement{ radius: "0"; angle: "85"; value: "99.8097"; } + ListElement{ radius: "0"; angle: "90"; value: "100"; } + ListElement{ radius: "0"; angle: "95"; value: "99.8097"; } + ListElement{ radius: "0"; angle: "100"; value: "99.2404"; } + ListElement{ radius: "0"; angle: "105"; value: "98.2963"; } + ListElement{ radius: "0"; angle: "110"; value: "96.9846"; } + ListElement{ radius: "0"; angle: "115"; value: "95.3154"; } + ListElement{ radius: "0"; angle: "120"; value: "93.3013"; } + ListElement{ radius: "0"; angle: "125"; value: "90.9576"; } + ListElement{ radius: "0"; angle: "130"; value: "88.3022"; } + ListElement{ radius: "0"; angle: "135"; value: "85.3553"; } + ListElement{ radius: "0"; angle: "140"; value: "82.1394"; } + ListElement{ radius: "0"; angle: "145"; value: "78.6788"; } + ListElement{ radius: "0"; angle: "150"; value: "75"; } + ListElement{ radius: "0"; angle: "155"; value: "71.1309"; } + ListElement{ radius: "0"; angle: "160"; value: "67.101"; } + ListElement{ radius: "0"; angle: "165"; value: "62.941"; } + ListElement{ radius: "0"; angle: "170"; value: "58.6824"; } + ListElement{ radius: "0"; angle: "175"; value: "54.3578"; } + ListElement{ radius: "0"; angle: "180"; value: "50"; } + ListElement{ radius: "0"; angle: "185"; value: "45.6422"; } + ListElement{ radius: "0"; angle: "190"; value: "41.3176"; } + ListElement{ radius: "0"; angle: "195"; value: "37.059"; } + ListElement{ radius: "0"; angle: "200"; value: "32.899"; } + ListElement{ radius: "0"; angle: "205"; value: "28.8691"; } + ListElement{ radius: "0"; angle: "210"; value: "25"; } + ListElement{ radius: "0"; angle: "215"; value: "21.3212"; } + ListElement{ radius: "0"; angle: "220"; value: "17.8606"; } + ListElement{ radius: "0"; angle: "225"; value: "14.6447"; } + ListElement{ radius: "0"; angle: "230"; value: "11.6978"; } + ListElement{ radius: "0"; angle: "235"; value: "9.0424"; } + ListElement{ radius: "0"; angle: "240"; value: "6.69873"; } + ListElement{ radius: "0"; angle: "245"; value: "4.68461"; } + ListElement{ radius: "0"; angle: "250"; value: "3.01537"; } + ListElement{ radius: "0"; angle: "255"; value: "1.70371"; } + ListElement{ radius: "0"; angle: "260"; value: "0.759612"; } + ListElement{ radius: "0"; angle: "265"; value: "0.190265"; } + ListElement{ radius: "0"; angle: "270"; value: "0"; } + ListElement{ radius: "0"; angle: "275"; value: "0.190265"; } + ListElement{ radius: "0"; angle: "280"; value: "0.759612"; } + ListElement{ radius: "0"; angle: "285"; value: "1.70371"; } + ListElement{ radius: "0"; angle: "290"; value: "3.01537"; } + ListElement{ radius: "0"; angle: "295"; value: "4.68461"; } + ListElement{ radius: "0"; angle: "300"; value: "6.69873"; } + ListElement{ radius: "0"; angle: "305"; value: "9.0424"; } + ListElement{ radius: "0"; angle: "310"; value: "11.6978"; } + ListElement{ radius: "0"; angle: "315"; value: "14.6447"; } + ListElement{ radius: "0"; angle: "320"; value: "17.8606"; } + ListElement{ radius: "0"; angle: "325"; value: "21.3212"; } + ListElement{ radius: "0"; angle: "330"; value: "25"; } + ListElement{ radius: "0"; angle: "335"; value: "28.8691"; } + ListElement{ radius: "0"; angle: "340"; value: "32.899"; } + ListElement{ radius: "0"; angle: "345"; value: "37.059"; } + ListElement{ radius: "0"; angle: "350"; value: "41.3176"; } + ListElement{ radius: "0"; angle: "355"; value: "45.6422"; } + ListElement{ radius: "0"; angle: "360"; value: "50"; } + ListElement{ radius: "5"; angle: "0"; value: "49.3844"; } + ListElement{ radius: "5"; angle: "5"; value: "53.7422"; } + ListElement{ radius: "5"; angle: "10"; value: "58.0668"; } + ListElement{ radius: "5"; angle: "15"; value: "62.3254"; } + ListElement{ radius: "5"; angle: "20"; value: "66.4854"; } + ListElement{ radius: "5"; angle: "25"; value: "70.5153"; } + ListElement{ radius: "5"; angle: "30"; value: "74.3844"; } + ListElement{ radius: "5"; angle: "35"; value: "78.0632"; } + ListElement{ radius: "5"; angle: "40"; value: "81.5238"; } + ListElement{ radius: "5"; angle: "45"; value: "84.7398"; } + ListElement{ radius: "5"; angle: "50"; value: "87.6866"; } + ListElement{ radius: "5"; angle: "55"; value: "90.342"; } + ListElement{ radius: "5"; angle: "60"; value: "92.6857"; } + ListElement{ radius: "5"; angle: "65"; value: "94.6998"; } + ListElement{ radius: "5"; angle: "70"; value: "96.369"; } + ListElement{ radius: "5"; angle: "75"; value: "97.6807"; } + ListElement{ radius: "5"; angle: "80"; value: "98.6248"; } + ListElement{ radius: "5"; angle: "85"; value: "99.1942"; } + ListElement{ radius: "5"; angle: "90"; value: "99.3844"; } + ListElement{ radius: "5"; angle: "95"; value: "99.1942"; } + ListElement{ radius: "5"; angle: "100"; value: "98.6248"; } + ListElement{ radius: "5"; angle: "105"; value: "97.6807"; } + ListElement{ radius: "5"; angle: "110"; value: "96.369"; } + ListElement{ radius: "5"; angle: "115"; value: "94.6998"; } + ListElement{ radius: "5"; angle: "120"; value: "92.6857"; } + ListElement{ radius: "5"; angle: "125"; value: "90.342"; } + ListElement{ radius: "5"; angle: "130"; value: "87.6866"; } + ListElement{ radius: "5"; angle: "135"; value: "84.7398"; } + ListElement{ radius: "5"; angle: "140"; value: "81.5238"; } + ListElement{ radius: "5"; angle: "145"; value: "78.0632"; } + ListElement{ radius: "5"; angle: "150"; value: "74.3844"; } + ListElement{ radius: "5"; angle: "155"; value: "70.5153"; } + ListElement{ radius: "5"; angle: "160"; value: "66.4854"; } + ListElement{ radius: "5"; angle: "165"; value: "62.3254"; } + ListElement{ radius: "5"; angle: "170"; value: "58.0668"; } + ListElement{ radius: "5"; angle: "175"; value: "53.7422"; } + ListElement{ radius: "5"; angle: "180"; value: "49.3844"; } + ListElement{ radius: "5"; angle: "185"; value: "45.0266"; } + ListElement{ radius: "5"; angle: "190"; value: "40.702"; } + ListElement{ radius: "5"; angle: "195"; value: "36.4435"; } + ListElement{ radius: "5"; angle: "200"; value: "32.2834"; } + ListElement{ radius: "5"; angle: "205"; value: "28.2535"; } + ListElement{ radius: "5"; angle: "210"; value: "24.3844"; } + ListElement{ radius: "5"; angle: "215"; value: "20.7056"; } + ListElement{ radius: "5"; angle: "220"; value: "17.245"; } + ListElement{ radius: "5"; angle: "225"; value: "14.0291"; } + ListElement{ radius: "5"; angle: "230"; value: "11.0822"; } + ListElement{ radius: "5"; angle: "235"; value: "8.42681"; } + ListElement{ radius: "5"; angle: "240"; value: "6.08315"; } + ListElement{ radius: "5"; angle: "245"; value: "4.06903"; } + ListElement{ radius: "5"; angle: "250"; value: "2.39979"; } + ListElement{ radius: "5"; angle: "255"; value: "1.08813"; } + ListElement{ radius: "5"; angle: "260"; value: "0.144029"; } + ListElement{ radius: "5"; angle: "265"; value: "-0.425318"; } + ListElement{ radius: "5"; angle: "270"; value: "-0.615583"; } + ListElement{ radius: "5"; angle: "275"; value: "-0.425318"; } + ListElement{ radius: "5"; angle: "280"; value: "0.144029"; } + ListElement{ radius: "5"; angle: "285"; value: "1.08813"; } + ListElement{ radius: "5"; angle: "290"; value: "2.39979"; } + ListElement{ radius: "5"; angle: "295"; value: "4.06903"; } + ListElement{ radius: "5"; angle: "300"; value: "6.08315"; } + ListElement{ radius: "5"; angle: "305"; value: "8.42681"; } + ListElement{ radius: "5"; angle: "310"; value: "11.0822"; } + ListElement{ radius: "5"; angle: "315"; value: "14.0291"; } + ListElement{ radius: "5"; angle: "320"; value: "17.245"; } + ListElement{ radius: "5"; angle: "325"; value: "20.7056"; } + ListElement{ radius: "5"; angle: "330"; value: "24.3844"; } + ListElement{ radius: "5"; angle: "335"; value: "28.2535"; } + ListElement{ radius: "5"; angle: "340"; value: "32.2834"; } + ListElement{ radius: "5"; angle: "345"; value: "36.4435"; } + ListElement{ radius: "5"; angle: "350"; value: "40.702"; } + ListElement{ radius: "5"; angle: "355"; value: "45.0266"; } + ListElement{ radius: "5"; angle: "360"; value: "49.3844"; } + ListElement{ radius: "10"; angle: "0"; value: "47.5528"; } + ListElement{ radius: "10"; angle: "5"; value: "51.9106"; } + ListElement{ radius: "10"; angle: "10"; value: "56.2352"; } + ListElement{ radius: "10"; angle: "15"; value: "60.4938"; } + ListElement{ radius: "10"; angle: "20"; value: "64.6538"; } + ListElement{ radius: "10"; angle: "25"; value: "68.6837"; } + ListElement{ radius: "10"; angle: "30"; value: "72.5528"; } + ListElement{ radius: "10"; angle: "35"; value: "76.2316"; } + ListElement{ radius: "10"; angle: "40"; value: "79.6922"; } + ListElement{ radius: "10"; angle: "45"; value: "82.9082"; } + ListElement{ radius: "10"; angle: "50"; value: "85.855"; } + ListElement{ radius: "10"; angle: "55"; value: "88.5104"; } + ListElement{ radius: "10"; angle: "60"; value: "90.8541"; } + ListElement{ radius: "10"; angle: "65"; value: "92.8682"; } + ListElement{ radius: "10"; angle: "70"; value: "94.5375"; } + ListElement{ radius: "10"; angle: "75"; value: "95.8491"; } + ListElement{ radius: "10"; angle: "80"; value: "96.7932"; } + ListElement{ radius: "10"; angle: "85"; value: "97.3626"; } + ListElement{ radius: "10"; angle: "90"; value: "97.5528"; } + ListElement{ radius: "10"; angle: "95"; value: "97.3626"; } + ListElement{ radius: "10"; angle: "100"; value: "96.7932"; } + ListElement{ radius: "10"; angle: "105"; value: "95.8491"; } + ListElement{ radius: "10"; angle: "110"; value: "94.5375"; } + ListElement{ radius: "10"; angle: "115"; value: "92.8682"; } + ListElement{ radius: "10"; angle: "120"; value: "90.8541"; } + ListElement{ radius: "10"; angle: "125"; value: "88.5104"; } + ListElement{ radius: "10"; angle: "130"; value: "85.855"; } + ListElement{ radius: "10"; angle: "135"; value: "82.9082"; } + ListElement{ radius: "10"; angle: "140"; value: "79.6922"; } + ListElement{ radius: "10"; angle: "145"; value: "76.2316"; } + ListElement{ radius: "10"; angle: "150"; value: "72.5528"; } + ListElement{ radius: "10"; angle: "155"; value: "68.6837"; } + ListElement{ radius: "10"; angle: "160"; value: "64.6538"; } + ListElement{ radius: "10"; angle: "165"; value: "60.4938"; } + ListElement{ radius: "10"; angle: "170"; value: "56.2352"; } + ListElement{ radius: "10"; angle: "175"; value: "51.9106"; } + ListElement{ radius: "10"; angle: "180"; value: "47.5528"; } + ListElement{ radius: "10"; angle: "185"; value: "43.195"; } + ListElement{ radius: "10"; angle: "190"; value: "38.8704"; } + ListElement{ radius: "10"; angle: "195"; value: "34.6119"; } + ListElement{ radius: "10"; angle: "200"; value: "30.4518"; } + ListElement{ radius: "10"; angle: "205"; value: "26.4219"; } + ListElement{ radius: "10"; angle: "210"; value: "22.5528"; } + ListElement{ radius: "10"; angle: "215"; value: "18.874"; } + ListElement{ radius: "10"; angle: "220"; value: "15.4134"; } + ListElement{ radius: "10"; angle: "225"; value: "12.1975"; } + ListElement{ radius: "10"; angle: "230"; value: "9.2506"; } + ListElement{ radius: "10"; angle: "235"; value: "6.59522"; } + ListElement{ radius: "10"; angle: "240"; value: "4.25156"; } + ListElement{ radius: "10"; angle: "245"; value: "2.23744"; } + ListElement{ radius: "10"; angle: "250"; value: "0.568195"; } + ListElement{ radius: "10"; angle: "255"; value: "-0.743465"; } + ListElement{ radius: "10"; angle: "260"; value: "-1.68756"; } + ListElement{ radius: "10"; angle: "265"; value: "-2.25691"; } + ListElement{ radius: "10"; angle: "270"; value: "-2.44717"; } + ListElement{ radius: "10"; angle: "275"; value: "-2.25691"; } + ListElement{ radius: "10"; angle: "280"; value: "-1.68756"; } + ListElement{ radius: "10"; angle: "285"; value: "-0.743465"; } + ListElement{ radius: "10"; angle: "290"; value: "0.568195"; } + ListElement{ radius: "10"; angle: "295"; value: "2.23744"; } + ListElement{ radius: "10"; angle: "300"; value: "4.25156"; } + ListElement{ radius: "10"; angle: "305"; value: "6.59522"; } + ListElement{ radius: "10"; angle: "310"; value: "9.2506"; } + ListElement{ radius: "10"; angle: "315"; value: "12.1975"; } + ListElement{ radius: "10"; angle: "320"; value: "15.4134"; } + ListElement{ radius: "10"; angle: "325"; value: "18.874"; } + ListElement{ radius: "10"; angle: "330"; value: "22.5528"; } + ListElement{ radius: "10"; angle: "335"; value: "26.4219"; } + ListElement{ radius: "10"; angle: "340"; value: "30.4518"; } + ListElement{ radius: "10"; angle: "345"; value: "34.6119"; } + ListElement{ radius: "10"; angle: "350"; value: "38.8704"; } + ListElement{ radius: "10"; angle: "355"; value: "43.195"; } + ListElement{ radius: "10"; angle: "360"; value: "47.5528"; } + ListElement{ radius: "15"; angle: "0"; value: "44.5503"; } + ListElement{ radius: "15"; angle: "5"; value: "48.9081"; } + ListElement{ radius: "15"; angle: "10"; value: "53.2327"; } + ListElement{ radius: "15"; angle: "15"; value: "57.4913"; } + ListElement{ radius: "15"; angle: "20"; value: "61.6513"; } + ListElement{ radius: "15"; angle: "25"; value: "65.6812"; } + ListElement{ radius: "15"; angle: "30"; value: "69.5503"; } + ListElement{ radius: "15"; angle: "35"; value: "73.2291"; } + ListElement{ radius: "15"; angle: "40"; value: "76.6897"; } + ListElement{ radius: "15"; angle: "45"; value: "79.9057"; } + ListElement{ radius: "15"; angle: "50"; value: "82.8525"; } + ListElement{ radius: "15"; angle: "55"; value: "85.5079"; } + ListElement{ radius: "15"; angle: "60"; value: "87.8516"; } + ListElement{ radius: "15"; angle: "65"; value: "89.8657"; } + ListElement{ radius: "15"; angle: "70"; value: "91.535"; } + ListElement{ radius: "15"; angle: "75"; value: "92.8466"; } + ListElement{ radius: "15"; angle: "80"; value: "93.7907"; } + ListElement{ radius: "15"; angle: "85"; value: "94.3601"; } + ListElement{ radius: "15"; angle: "90"; value: "94.5503"; } + ListElement{ radius: "15"; angle: "95"; value: "94.3601"; } + ListElement{ radius: "15"; angle: "100"; value: "93.7907"; } + ListElement{ radius: "15"; angle: "105"; value: "92.8466"; } + ListElement{ radius: "15"; angle: "110"; value: "91.535"; } + ListElement{ radius: "15"; angle: "115"; value: "89.8657"; } + ListElement{ radius: "15"; angle: "120"; value: "87.8516"; } + ListElement{ radius: "15"; angle: "125"; value: "85.5079"; } + ListElement{ radius: "15"; angle: "130"; value: "82.8525"; } + ListElement{ radius: "15"; angle: "135"; value: "79.9057"; } + ListElement{ radius: "15"; angle: "140"; value: "76.6897"; } + ListElement{ radius: "15"; angle: "145"; value: "73.2291"; } + ListElement{ radius: "15"; angle: "150"; value: "69.5503"; } + ListElement{ radius: "15"; angle: "155"; value: "65.6812"; } + ListElement{ radius: "15"; angle: "160"; value: "61.6513"; } + ListElement{ radius: "15"; angle: "165"; value: "57.4913"; } + ListElement{ radius: "15"; angle: "170"; value: "53.2327"; } + ListElement{ radius: "15"; angle: "175"; value: "48.9081"; } + ListElement{ radius: "15"; angle: "180"; value: "44.5503"; } + ListElement{ radius: "15"; angle: "185"; value: "40.1925"; } + ListElement{ radius: "15"; angle: "190"; value: "35.8679"; } + ListElement{ radius: "15"; angle: "195"; value: "31.6094"; } + ListElement{ radius: "15"; angle: "200"; value: "27.4493"; } + ListElement{ radius: "15"; angle: "205"; value: "23.4194"; } + ListElement{ radius: "15"; angle: "210"; value: "19.5503"; } + ListElement{ radius: "15"; angle: "215"; value: "15.8715"; } + ListElement{ radius: "15"; angle: "220"; value: "12.4109"; } + ListElement{ radius: "15"; angle: "225"; value: "9.19499"; } + ListElement{ radius: "15"; angle: "230"; value: "6.2481"; } + ListElement{ radius: "15"; angle: "235"; value: "3.59272"; } + ListElement{ radius: "15"; angle: "240"; value: "1.24906"; } + ListElement{ radius: "15"; angle: "245"; value: "-0.765063"; } + ListElement{ radius: "15"; angle: "250"; value: "-2.4343"; } + ListElement{ radius: "15"; angle: "255"; value: "-3.74597"; } + ListElement{ radius: "15"; angle: "260"; value: "-4.69006"; } + ListElement{ radius: "15"; angle: "265"; value: "-5.25941"; } + ListElement{ radius: "15"; angle: "270"; value: "-5.44967"; } + ListElement{ radius: "15"; angle: "275"; value: "-5.25941"; } + ListElement{ radius: "15"; angle: "280"; value: "-4.69006"; } + ListElement{ radius: "15"; angle: "285"; value: "-3.74597"; } + ListElement{ radius: "15"; angle: "290"; value: "-2.4343"; } + ListElement{ radius: "15"; angle: "295"; value: "-0.765063"; } + ListElement{ radius: "15"; angle: "300"; value: "1.24906"; } + ListElement{ radius: "15"; angle: "305"; value: "3.59272"; } + ListElement{ radius: "15"; angle: "310"; value: "6.2481"; } + ListElement{ radius: "15"; angle: "315"; value: "9.19499"; } + ListElement{ radius: "15"; angle: "320"; value: "12.4109"; } + ListElement{ radius: "15"; angle: "325"; value: "15.8715"; } + ListElement{ radius: "15"; angle: "330"; value: "19.5503"; } + ListElement{ radius: "15"; angle: "335"; value: "23.4194"; } + ListElement{ radius: "15"; angle: "340"; value: "27.4493"; } + ListElement{ radius: "15"; angle: "345"; value: "31.6094"; } + ListElement{ radius: "15"; angle: "350"; value: "35.8679"; } + ListElement{ radius: "15"; angle: "355"; value: "40.1925"; } + ListElement{ radius: "15"; angle: "360"; value: "44.5503"; } + ListElement{ radius: "20"; angle: "0"; value: "40.4508"; } + ListElement{ radius: "20"; angle: "5"; value: "44.8086"; } + ListElement{ radius: "20"; angle: "10"; value: "49.1333"; } + ListElement{ radius: "20"; angle: "15"; value: "53.3918"; } + ListElement{ radius: "20"; angle: "20"; value: "57.5519"; } + ListElement{ radius: "20"; angle: "25"; value: "61.5818"; } + ListElement{ radius: "20"; angle: "30"; value: "65.4508"; } + ListElement{ radius: "20"; angle: "35"; value: "69.1297"; } + ListElement{ radius: "20"; angle: "40"; value: "72.5902"; } + ListElement{ radius: "20"; angle: "45"; value: "75.8062"; } + ListElement{ radius: "20"; angle: "50"; value: "78.7531"; } + ListElement{ radius: "20"; angle: "55"; value: "81.4085"; } + ListElement{ radius: "20"; angle: "60"; value: "83.7521"; } + ListElement{ radius: "20"; angle: "65"; value: "85.7662"; } + ListElement{ radius: "20"; angle: "70"; value: "87.4355"; } + ListElement{ radius: "20"; angle: "75"; value: "88.7471"; } + ListElement{ radius: "20"; angle: "80"; value: "89.6912"; } + ListElement{ radius: "20"; angle: "85"; value: "90.2606"; } + ListElement{ radius: "20"; angle: "90"; value: "90.4508"; } + ListElement{ radius: "20"; angle: "95"; value: "90.2606"; } + ListElement{ radius: "20"; angle: "100"; value: "89.6912"; } + ListElement{ radius: "20"; angle: "105"; value: "88.7471"; } + ListElement{ radius: "20"; angle: "110"; value: "87.4355"; } + ListElement{ radius: "20"; angle: "115"; value: "85.7662"; } + ListElement{ radius: "20"; angle: "120"; value: "83.7521"; } + ListElement{ radius: "20"; angle: "125"; value: "81.4085"; } + ListElement{ radius: "20"; angle: "130"; value: "78.7531"; } + ListElement{ radius: "20"; angle: "135"; value: "75.8062"; } + ListElement{ radius: "20"; angle: "140"; value: "72.5902"; } + ListElement{ radius: "20"; angle: "145"; value: "69.1297"; } + ListElement{ radius: "20"; angle: "150"; value: "65.4508"; } + ListElement{ radius: "20"; angle: "155"; value: "61.5818"; } + ListElement{ radius: "20"; angle: "160"; value: "57.5519"; } + ListElement{ radius: "20"; angle: "165"; value: "53.3918"; } + ListElement{ radius: "20"; angle: "170"; value: "49.1333"; } + ListElement{ radius: "20"; angle: "175"; value: "44.8086"; } + ListElement{ radius: "20"; angle: "180"; value: "40.4508"; } + ListElement{ radius: "20"; angle: "185"; value: "36.0931"; } + ListElement{ radius: "20"; angle: "190"; value: "31.7684"; } + ListElement{ radius: "20"; angle: "195"; value: "27.5099"; } + ListElement{ radius: "20"; angle: "200"; value: "23.3498"; } + ListElement{ radius: "20"; angle: "205"; value: "19.3199"; } + ListElement{ radius: "20"; angle: "210"; value: "15.4508"; } + ListElement{ radius: "20"; angle: "215"; value: "11.772"; } + ListElement{ radius: "20"; angle: "220"; value: "8.31147"; } + ListElement{ radius: "20"; angle: "225"; value: "5.09551"; } + ListElement{ radius: "20"; angle: "230"; value: "2.14863"; } + ListElement{ radius: "20"; angle: "235"; value: "-0.506752"; } + ListElement{ radius: "20"; angle: "240"; value: "-2.85042"; } + ListElement{ radius: "20"; angle: "245"; value: "-4.86454"; } + ListElement{ radius: "20"; angle: "250"; value: "-6.53378"; } + ListElement{ radius: "20"; angle: "255"; value: "-7.84544"; } + ListElement{ radius: "20"; angle: "260"; value: "-8.78954"; } + ListElement{ radius: "20"; angle: "265"; value: "-9.35889"; } + ListElement{ radius: "20"; angle: "270"; value: "-9.54915"; } + ListElement{ radius: "20"; angle: "275"; value: "-9.35889"; } + ListElement{ radius: "20"; angle: "280"; value: "-8.78954"; } + ListElement{ radius: "20"; angle: "285"; value: "-7.84544"; } + ListElement{ radius: "20"; angle: "290"; value: "-6.53378"; } + ListElement{ radius: "20"; angle: "295"; value: "-4.86454"; } + ListElement{ radius: "20"; angle: "300"; value: "-2.85042"; } + ListElement{ radius: "20"; angle: "305"; value: "-0.506752"; } + ListElement{ radius: "20"; angle: "310"; value: "2.14863"; } + ListElement{ radius: "20"; angle: "315"; value: "5.09551"; } + ListElement{ radius: "20"; angle: "320"; value: "8.31147"; } + ListElement{ radius: "20"; angle: "325"; value: "11.772"; } + ListElement{ radius: "20"; angle: "330"; value: "15.4508"; } + ListElement{ radius: "20"; angle: "335"; value: "19.3199"; } + ListElement{ radius: "20"; angle: "340"; value: "23.3498"; } + ListElement{ radius: "20"; angle: "345"; value: "27.5099"; } + ListElement{ radius: "20"; angle: "350"; value: "31.7684"; } + ListElement{ radius: "20"; angle: "355"; value: "36.0931"; } + ListElement{ radius: "20"; angle: "360"; value: "40.4508"; } + ListElement{ radius: "25"; angle: "0"; value: "35.3553"; } + ListElement{ radius: "25"; angle: "5"; value: "39.7131"; } + ListElement{ radius: "25"; angle: "10"; value: "44.0377"; } + ListElement{ radius: "25"; angle: "15"; value: "48.2963"; } + ListElement{ radius: "25"; angle: "20"; value: "52.4563"; } + ListElement{ radius: "25"; angle: "25"; value: "56.4863"; } + ListElement{ radius: "25"; angle: "30"; value: "60.3553"; } + ListElement{ radius: "25"; angle: "35"; value: "64.0342"; } + ListElement{ radius: "25"; angle: "40"; value: "67.4947"; } + ListElement{ radius: "25"; angle: "45"; value: "70.7107"; } + ListElement{ radius: "25"; angle: "50"; value: "73.6576"; } + ListElement{ radius: "25"; angle: "55"; value: "76.3129"; } + ListElement{ radius: "25"; angle: "60"; value: "78.6566"; } + ListElement{ radius: "25"; angle: "65"; value: "80.6707"; } + ListElement{ radius: "25"; angle: "70"; value: "82.34"; } + ListElement{ radius: "25"; angle: "75"; value: "83.6516"; } + ListElement{ radius: "25"; angle: "80"; value: "84.5957"; } + ListElement{ radius: "25"; angle: "85"; value: "85.1651"; } + ListElement{ radius: "25"; angle: "90"; value: "85.3553"; } + ListElement{ radius: "25"; angle: "95"; value: "85.1651"; } + ListElement{ radius: "25"; angle: "100"; value: "84.5957"; } + ListElement{ radius: "25"; angle: "105"; value: "83.6516"; } + ListElement{ radius: "25"; angle: "110"; value: "82.34"; } + ListElement{ radius: "25"; angle: "115"; value: "80.6707"; } + ListElement{ radius: "25"; angle: "120"; value: "78.6566"; } + ListElement{ radius: "25"; angle: "125"; value: "76.3129"; } + ListElement{ radius: "25"; angle: "130"; value: "73.6576"; } + ListElement{ radius: "25"; angle: "135"; value: "70.7107"; } + ListElement{ radius: "25"; angle: "140"; value: "67.4947"; } + ListElement{ radius: "25"; angle: "145"; value: "64.0342"; } + ListElement{ radius: "25"; angle: "150"; value: "60.3553"; } + ListElement{ radius: "25"; angle: "155"; value: "56.4863"; } + ListElement{ radius: "25"; angle: "160"; value: "52.4563"; } + ListElement{ radius: "25"; angle: "165"; value: "48.2963"; } + ListElement{ radius: "25"; angle: "170"; value: "44.0377"; } + ListElement{ radius: "25"; angle: "175"; value: "39.7131"; } + ListElement{ radius: "25"; angle: "180"; value: "35.3553"; } + ListElement{ radius: "25"; angle: "185"; value: "30.9976"; } + ListElement{ radius: "25"; angle: "190"; value: "26.6729"; } + ListElement{ radius: "25"; angle: "195"; value: "22.4144"; } + ListElement{ radius: "25"; angle: "200"; value: "18.2543"; } + ListElement{ radius: "25"; angle: "205"; value: "14.2244"; } + ListElement{ radius: "25"; angle: "210"; value: "10.3553"; } + ListElement{ radius: "25"; angle: "215"; value: "6.67652"; } + ListElement{ radius: "25"; angle: "220"; value: "3.21596"; } + ListElement{ radius: "25"; angle: "225"; value: "5.55112e-15"; } + ListElement{ radius: "25"; angle: "230"; value: "-2.94688"; } + ListElement{ radius: "25"; angle: "235"; value: "-5.60226"; } + ListElement{ radius: "25"; angle: "240"; value: "-7.94593"; } + ListElement{ radius: "25"; angle: "245"; value: "-9.96005"; } + ListElement{ radius: "25"; angle: "250"; value: "-11.6293"; } + ListElement{ radius: "25"; angle: "255"; value: "-12.941"; } + ListElement{ radius: "25"; angle: "260"; value: "-13.885"; } + ListElement{ radius: "25"; angle: "265"; value: "-14.4544"; } + ListElement{ radius: "25"; angle: "270"; value: "-14.6447"; } + ListElement{ radius: "25"; angle: "275"; value: "-14.4544"; } + ListElement{ radius: "25"; angle: "280"; value: "-13.885"; } + ListElement{ radius: "25"; angle: "285"; value: "-12.941"; } + ListElement{ radius: "25"; angle: "290"; value: "-11.6293"; } + ListElement{ radius: "25"; angle: "295"; value: "-9.96005"; } + ListElement{ radius: "25"; angle: "300"; value: "-7.94593"; } + ListElement{ radius: "25"; angle: "305"; value: "-5.60226"; } + ListElement{ radius: "25"; angle: "310"; value: "-2.94688"; } + ListElement{ radius: "25"; angle: "315"; value: "-5.55112e-15"; } + ListElement{ radius: "25"; angle: "320"; value: "3.21596"; } + ListElement{ radius: "25"; angle: "325"; value: "6.67652"; } + ListElement{ radius: "25"; angle: "330"; value: "10.3553"; } + ListElement{ radius: "25"; angle: "335"; value: "14.2244"; } + ListElement{ radius: "25"; angle: "340"; value: "18.2543"; } + ListElement{ radius: "25"; angle: "345"; value: "22.4144"; } + ListElement{ radius: "25"; angle: "350"; value: "26.6729"; } + ListElement{ radius: "25"; angle: "355"; value: "30.9976"; } + ListElement{ radius: "25"; angle: "360"; value: "35.3553"; } + ListElement{ radius: "30"; angle: "0"; value: "29.3893"; } + ListElement{ radius: "30"; angle: "5"; value: "33.747"; } + ListElement{ radius: "30"; angle: "10"; value: "38.0717"; } + ListElement{ radius: "30"; angle: "15"; value: "42.3302"; } + ListElement{ radius: "30"; angle: "20"; value: "46.4903"; } + ListElement{ radius: "30"; angle: "25"; value: "50.5202"; } + ListElement{ radius: "30"; angle: "30"; value: "54.3893"; } + ListElement{ radius: "30"; angle: "35"; value: "58.0681"; } + ListElement{ radius: "30"; angle: "40"; value: "61.5286"; } + ListElement{ radius: "30"; angle: "45"; value: "64.7446"; } + ListElement{ radius: "30"; angle: "50"; value: "67.6915"; } + ListElement{ radius: "30"; angle: "55"; value: "70.3469"; } + ListElement{ radius: "30"; angle: "60"; value: "72.6905"; } + ListElement{ radius: "30"; angle: "65"; value: "74.7047"; } + ListElement{ radius: "30"; angle: "70"; value: "76.3739"; } + ListElement{ radius: "30"; angle: "75"; value: "77.6856"; } + ListElement{ radius: "30"; angle: "80"; value: "78.6297"; } + ListElement{ radius: "30"; angle: "85"; value: "79.199"; } + ListElement{ radius: "30"; angle: "90"; value: "79.3893"; } + ListElement{ radius: "30"; angle: "95"; value: "79.199"; } + ListElement{ radius: "30"; angle: "100"; value: "78.6297"; } + ListElement{ radius: "30"; angle: "105"; value: "77.6856"; } + ListElement{ radius: "30"; angle: "110"; value: "76.3739"; } + ListElement{ radius: "30"; angle: "115"; value: "74.7047"; } + ListElement{ radius: "30"; angle: "120"; value: "72.6905"; } + ListElement{ radius: "30"; angle: "125"; value: "70.3469"; } + ListElement{ radius: "30"; angle: "130"; value: "67.6915"; } + ListElement{ radius: "30"; angle: "135"; value: "64.7446"; } + ListElement{ radius: "30"; angle: "140"; value: "61.5286"; } + ListElement{ radius: "30"; angle: "145"; value: "58.0681"; } + ListElement{ radius: "30"; angle: "150"; value: "54.3893"; } + ListElement{ radius: "30"; angle: "155"; value: "50.5202"; } + ListElement{ radius: "30"; angle: "160"; value: "46.4903"; } + ListElement{ radius: "30"; angle: "165"; value: "42.3302"; } + ListElement{ radius: "30"; angle: "170"; value: "38.0717"; } + ListElement{ radius: "30"; angle: "175"; value: "33.747"; } + ListElement{ radius: "30"; angle: "180"; value: "29.3893"; } + ListElement{ radius: "30"; angle: "185"; value: "25.0315"; } + ListElement{ radius: "30"; angle: "190"; value: "20.7069"; } + ListElement{ radius: "30"; angle: "195"; value: "16.4483"; } + ListElement{ radius: "30"; angle: "200"; value: "12.2883"; } + ListElement{ radius: "30"; angle: "205"; value: "8.25835"; } + ListElement{ radius: "30"; angle: "210"; value: "4.38926"; } + ListElement{ radius: "30"; angle: "215"; value: "0.710441"; } + ListElement{ radius: "30"; angle: "220"; value: "-2.75012"; } + ListElement{ radius: "30"; angle: "225"; value: "-5.96608"; } + ListElement{ radius: "30"; angle: "230"; value: "-8.91296"; } + ListElement{ radius: "30"; angle: "235"; value: "-11.5683"; } + ListElement{ radius: "30"; angle: "240"; value: "-13.912"; } + ListElement{ radius: "30"; angle: "245"; value: "-15.9261"; } + ListElement{ radius: "30"; angle: "250"; value: "-17.5954"; } + ListElement{ radius: "30"; angle: "255"; value: "-18.907"; } + ListElement{ radius: "30"; angle: "260"; value: "-19.8511"; } + ListElement{ radius: "30"; angle: "265"; value: "-20.4205"; } + ListElement{ radius: "30"; angle: "270"; value: "-20.6107"; } + ListElement{ radius: "30"; angle: "275"; value: "-20.4205"; } + ListElement{ radius: "30"; angle: "280"; value: "-19.8511"; } + ListElement{ radius: "30"; angle: "285"; value: "-18.907"; } + ListElement{ radius: "30"; angle: "290"; value: "-17.5954"; } + ListElement{ radius: "30"; angle: "295"; value: "-15.9261"; } + ListElement{ radius: "30"; angle: "300"; value: "-13.912"; } + ListElement{ radius: "30"; angle: "305"; value: "-11.5683"; } + ListElement{ radius: "30"; angle: "310"; value: "-8.91296"; } + ListElement{ radius: "30"; angle: "315"; value: "-5.96608"; } + ListElement{ radius: "30"; angle: "320"; value: "-2.75012"; } + ListElement{ radius: "30"; angle: "325"; value: "0.710441"; } + ListElement{ radius: "30"; angle: "330"; value: "4.38926"; } + ListElement{ radius: "30"; angle: "335"; value: "8.25835"; } + ListElement{ radius: "30"; angle: "340"; value: "12.2883"; } + ListElement{ radius: "30"; angle: "345"; value: "16.4483"; } + ListElement{ radius: "30"; angle: "350"; value: "20.7069"; } + ListElement{ radius: "30"; angle: "355"; value: "25.0315"; } + ListElement{ radius: "30"; angle: "360"; value: "29.3893"; } + ListElement{ radius: "35"; angle: "0"; value: "22.6995"; } + ListElement{ radius: "35"; angle: "5"; value: "27.0573"; } + ListElement{ radius: "35"; angle: "10"; value: "31.3819"; } + ListElement{ radius: "35"; angle: "15"; value: "35.6405"; } + ListElement{ radius: "35"; angle: "20"; value: "39.8005"; } + ListElement{ radius: "35"; angle: "25"; value: "43.8304"; } + ListElement{ radius: "35"; angle: "30"; value: "47.6995"; } + ListElement{ radius: "35"; angle: "35"; value: "51.3783"; } + ListElement{ radius: "35"; angle: "40"; value: "54.8389"; } + ListElement{ radius: "35"; angle: "45"; value: "58.0549"; } + ListElement{ radius: "35"; angle: "50"; value: "61.0017"; } + ListElement{ radius: "35"; angle: "55"; value: "63.6571"; } + ListElement{ radius: "35"; angle: "60"; value: "66.0008"; } + ListElement{ radius: "35"; angle: "65"; value: "68.0149"; } + ListElement{ radius: "35"; angle: "70"; value: "69.6842"; } + ListElement{ radius: "35"; angle: "75"; value: "70.9958"; } + ListElement{ radius: "35"; angle: "80"; value: "71.9399"; } + ListElement{ radius: "35"; angle: "85"; value: "72.5093"; } + ListElement{ radius: "35"; angle: "90"; value: "72.6995"; } + ListElement{ radius: "35"; angle: "95"; value: "72.5093"; } + ListElement{ radius: "35"; angle: "100"; value: "71.9399"; } + ListElement{ radius: "35"; angle: "105"; value: "70.9958"; } + ListElement{ radius: "35"; angle: "110"; value: "69.6842"; } + ListElement{ radius: "35"; angle: "115"; value: "68.0149"; } + ListElement{ radius: "35"; angle: "120"; value: "66.0008"; } + ListElement{ radius: "35"; angle: "125"; value: "63.6571"; } + ListElement{ radius: "35"; angle: "130"; value: "61.0017"; } + ListElement{ radius: "35"; angle: "135"; value: "58.0549"; } + ListElement{ radius: "35"; angle: "140"; value: "54.8389"; } + ListElement{ radius: "35"; angle: "145"; value: "51.3783"; } + ListElement{ radius: "35"; angle: "150"; value: "47.6995"; } + ListElement{ radius: "35"; angle: "155"; value: "43.8304"; } + ListElement{ radius: "35"; angle: "160"; value: "39.8005"; } + ListElement{ radius: "35"; angle: "165"; value: "35.6405"; } + ListElement{ radius: "35"; angle: "170"; value: "31.3819"; } + ListElement{ radius: "35"; angle: "175"; value: "27.0573"; } + ListElement{ radius: "35"; angle: "180"; value: "22.6995"; } + ListElement{ radius: "35"; angle: "185"; value: "18.3417"; } + ListElement{ radius: "35"; angle: "190"; value: "14.0171"; } + ListElement{ radius: "35"; angle: "195"; value: "9.75857"; } + ListElement{ radius: "35"; angle: "200"; value: "5.59852"; } + ListElement{ radius: "35"; angle: "205"; value: "1.56861"; } + ListElement{ radius: "35"; angle: "210"; value: "-2.30048"; } + ListElement{ radius: "35"; angle: "215"; value: "-5.9793"; } + ListElement{ radius: "35"; angle: "220"; value: "-9.43986"; } + ListElement{ radius: "35"; angle: "225"; value: "-12.6558"; } + ListElement{ radius: "35"; angle: "230"; value: "-15.6027"; } + ListElement{ radius: "35"; angle: "235"; value: "-18.2581"; } + ListElement{ radius: "35"; angle: "240"; value: "-20.6017"; } + ListElement{ radius: "35"; angle: "245"; value: "-22.6159"; } + ListElement{ radius: "35"; angle: "250"; value: "-24.2851"; } + ListElement{ radius: "35"; angle: "255"; value: "-25.5968"; } + ListElement{ radius: "35"; angle: "260"; value: "-26.5409"; } + ListElement{ radius: "35"; angle: "265"; value: "-27.1102"; } + ListElement{ radius: "35"; angle: "270"; value: "-27.3005"; } + ListElement{ radius: "35"; angle: "275"; value: "-27.1102"; } + ListElement{ radius: "35"; angle: "280"; value: "-26.5409"; } + ListElement{ radius: "35"; angle: "285"; value: "-25.5968"; } + ListElement{ radius: "35"; angle: "290"; value: "-24.2851"; } + ListElement{ radius: "35"; angle: "295"; value: "-22.6159"; } + ListElement{ radius: "35"; angle: "300"; value: "-20.6017"; } + ListElement{ radius: "35"; angle: "305"; value: "-18.2581"; } + ListElement{ radius: "35"; angle: "310"; value: "-15.6027"; } + ListElement{ radius: "35"; angle: "315"; value: "-12.6558"; } + ListElement{ radius: "35"; angle: "320"; value: "-9.43986"; } + ListElement{ radius: "35"; angle: "325"; value: "-5.9793"; } + ListElement{ radius: "35"; angle: "330"; value: "-2.30048"; } + ListElement{ radius: "35"; angle: "335"; value: "1.56861"; } + ListElement{ radius: "35"; angle: "340"; value: "5.59852"; } + ListElement{ radius: "35"; angle: "345"; value: "9.75857"; } + ListElement{ radius: "35"; angle: "350"; value: "14.0171"; } + ListElement{ radius: "35"; angle: "355"; value: "18.3417"; } + ListElement{ radius: "35"; angle: "360"; value: "22.6995"; } + ListElement{ radius: "40"; angle: "0"; value: "15.4508"; } + ListElement{ radius: "40"; angle: "5"; value: "19.8086"; } + ListElement{ radius: "40"; angle: "10"; value: "24.1333"; } + ListElement{ radius: "40"; angle: "15"; value: "28.3918"; } + ListElement{ radius: "40"; angle: "20"; value: "32.5519"; } + ListElement{ radius: "40"; angle: "25"; value: "36.5818"; } + ListElement{ radius: "40"; angle: "30"; value: "40.4508"; } + ListElement{ radius: "40"; angle: "35"; value: "44.1297"; } + ListElement{ radius: "40"; angle: "40"; value: "47.5902"; } + ListElement{ radius: "40"; angle: "45"; value: "50.8062"; } + ListElement{ radius: "40"; angle: "50"; value: "53.7531"; } + ListElement{ radius: "40"; angle: "55"; value: "56.4085"; } + ListElement{ radius: "40"; angle: "60"; value: "58.7521"; } + ListElement{ radius: "40"; angle: "65"; value: "60.7662"; } + ListElement{ radius: "40"; angle: "70"; value: "62.4355"; } + ListElement{ radius: "40"; angle: "75"; value: "63.7471"; } + ListElement{ radius: "40"; angle: "80"; value: "64.6912"; } + ListElement{ radius: "40"; angle: "85"; value: "65.2606"; } + ListElement{ radius: "40"; angle: "90"; value: "65.4508"; } + ListElement{ radius: "40"; angle: "95"; value: "65.2606"; } + ListElement{ radius: "40"; angle: "100"; value: "64.6912"; } + ListElement{ radius: "40"; angle: "105"; value: "63.7471"; } + ListElement{ radius: "40"; angle: "110"; value: "62.4355"; } + ListElement{ radius: "40"; angle: "115"; value: "60.7662"; } + ListElement{ radius: "40"; angle: "120"; value: "58.7521"; } + ListElement{ radius: "40"; angle: "125"; value: "56.4085"; } + ListElement{ radius: "40"; angle: "130"; value: "53.7531"; } + ListElement{ radius: "40"; angle: "135"; value: "50.8062"; } + ListElement{ radius: "40"; angle: "140"; value: "47.5902"; } + ListElement{ radius: "40"; angle: "145"; value: "44.1297"; } + ListElement{ radius: "40"; angle: "150"; value: "40.4508"; } + ListElement{ radius: "40"; angle: "155"; value: "36.5818"; } + ListElement{ radius: "40"; angle: "160"; value: "32.5519"; } + ListElement{ radius: "40"; angle: "165"; value: "28.3918"; } + ListElement{ radius: "40"; angle: "170"; value: "24.1333"; } + ListElement{ radius: "40"; angle: "175"; value: "19.8086"; } + ListElement{ radius: "40"; angle: "180"; value: "15.4508"; } + ListElement{ radius: "40"; angle: "185"; value: "11.0931"; } + ListElement{ radius: "40"; angle: "190"; value: "6.76844"; } + ListElement{ radius: "40"; angle: "195"; value: "2.5099"; } + ListElement{ radius: "40"; angle: "200"; value: "-1.65016"; } + ListElement{ radius: "40"; angle: "205"; value: "-5.68006"; } + ListElement{ radius: "40"; angle: "210"; value: "-9.54915"; } + ListElement{ radius: "40"; angle: "215"; value: "-13.228"; } + ListElement{ radius: "40"; angle: "220"; value: "-16.6885"; } + ListElement{ radius: "40"; angle: "225"; value: "-19.9045"; } + ListElement{ radius: "40"; angle: "230"; value: "-22.8514"; } + ListElement{ radius: "40"; angle: "235"; value: "-25.5068"; } + ListElement{ radius: "40"; angle: "240"; value: "-27.8504"; } + ListElement{ radius: "40"; angle: "245"; value: "-29.8645"; } + ListElement{ radius: "40"; angle: "250"; value: "-31.5338"; } + ListElement{ radius: "40"; angle: "255"; value: "-32.8454"; } + ListElement{ radius: "40"; angle: "260"; value: "-33.7895"; } + ListElement{ radius: "40"; angle: "265"; value: "-34.3589"; } + ListElement{ radius: "40"; angle: "270"; value: "-34.5492"; } + ListElement{ radius: "40"; angle: "275"; value: "-34.3589"; } + ListElement{ radius: "40"; angle: "280"; value: "-33.7895"; } + ListElement{ radius: "40"; angle: "285"; value: "-32.8454"; } + ListElement{ radius: "40"; angle: "290"; value: "-31.5338"; } + ListElement{ radius: "40"; angle: "295"; value: "-29.8645"; } + ListElement{ radius: "40"; angle: "300"; value: "-27.8504"; } + ListElement{ radius: "40"; angle: "305"; value: "-25.5068"; } + ListElement{ radius: "40"; angle: "310"; value: "-22.8514"; } + ListElement{ radius: "40"; angle: "315"; value: "-19.9045"; } + ListElement{ radius: "40"; angle: "320"; value: "-16.6885"; } + ListElement{ radius: "40"; angle: "325"; value: "-13.228"; } + ListElement{ radius: "40"; angle: "330"; value: "-9.54915"; } + ListElement{ radius: "40"; angle: "335"; value: "-5.68006"; } + ListElement{ radius: "40"; angle: "340"; value: "-1.65016"; } + ListElement{ radius: "40"; angle: "345"; value: "2.5099"; } + ListElement{ radius: "40"; angle: "350"; value: "6.76844"; } + ListElement{ radius: "40"; angle: "355"; value: "11.0931"; } + ListElement{ radius: "40"; angle: "360"; value: "15.4508"; } + ListElement{ radius: "45"; angle: "0"; value: "7.82172"; } + ListElement{ radius: "45"; angle: "5"; value: "12.1795"; } + ListElement{ radius: "45"; angle: "10"; value: "16.5041"; } + ListElement{ radius: "45"; angle: "15"; value: "20.7627"; } + ListElement{ radius: "45"; angle: "20"; value: "24.9227"; } + ListElement{ radius: "45"; angle: "25"; value: "28.9526"; } + ListElement{ radius: "45"; angle: "30"; value: "32.8217"; } + ListElement{ radius: "45"; angle: "35"; value: "36.5005"; } + ListElement{ radius: "45"; angle: "40"; value: "39.9611"; } + ListElement{ radius: "45"; angle: "45"; value: "43.1771"; } + ListElement{ radius: "45"; angle: "50"; value: "46.1239"; } + ListElement{ radius: "45"; angle: "55"; value: "48.7793"; } + ListElement{ radius: "45"; angle: "60"; value: "51.123"; } + ListElement{ radius: "45"; angle: "65"; value: "53.1371"; } + ListElement{ radius: "45"; angle: "70"; value: "54.8064"; } + ListElement{ radius: "45"; angle: "75"; value: "56.118"; } + ListElement{ radius: "45"; angle: "80"; value: "57.0621"; } + ListElement{ radius: "45"; angle: "85"; value: "57.6315"; } + ListElement{ radius: "45"; angle: "90"; value: "57.8217"; } + ListElement{ radius: "45"; angle: "95"; value: "57.6315"; } + ListElement{ radius: "45"; angle: "100"; value: "57.0621"; } + ListElement{ radius: "45"; angle: "105"; value: "56.118"; } + ListElement{ radius: "45"; angle: "110"; value: "54.8064"; } + ListElement{ radius: "45"; angle: "115"; value: "53.1371"; } + ListElement{ radius: "45"; angle: "120"; value: "51.123"; } + ListElement{ radius: "45"; angle: "125"; value: "48.7793"; } + ListElement{ radius: "45"; angle: "130"; value: "46.1239"; } + ListElement{ radius: "45"; angle: "135"; value: "43.1771"; } + ListElement{ radius: "45"; angle: "140"; value: "39.9611"; } + ListElement{ radius: "45"; angle: "145"; value: "36.5005"; } + ListElement{ radius: "45"; angle: "150"; value: "32.8217"; } + ListElement{ radius: "45"; angle: "155"; value: "28.9526"; } + ListElement{ radius: "45"; angle: "160"; value: "24.9227"; } + ListElement{ radius: "45"; angle: "165"; value: "20.7627"; } + ListElement{ radius: "45"; angle: "170"; value: "16.5041"; } + ListElement{ radius: "45"; angle: "175"; value: "12.1795"; } + ListElement{ radius: "45"; angle: "180"; value: "7.82172"; } + ListElement{ radius: "45"; angle: "185"; value: "3.46394"; } + ListElement{ radius: "45"; angle: "190"; value: "-0.860686"; } + ListElement{ radius: "45"; angle: "195"; value: "-5.11923"; } + ListElement{ radius: "45"; angle: "200"; value: "-9.27928"; } + ListElement{ radius: "45"; angle: "205"; value: "-13.3092"; } + ListElement{ radius: "45"; angle: "210"; value: "-17.1783"; } + ListElement{ radius: "45"; angle: "215"; value: "-20.8571"; } + ListElement{ radius: "45"; angle: "220"; value: "-24.3177"; } + ListElement{ radius: "45"; angle: "225"; value: "-27.5336"; } + ListElement{ radius: "45"; angle: "230"; value: "-30.4805"; } + ListElement{ radius: "45"; angle: "235"; value: "-33.1359"; } + ListElement{ radius: "45"; angle: "240"; value: "-35.4795"; } + ListElement{ radius: "45"; angle: "245"; value: "-37.4937"; } + ListElement{ radius: "45"; angle: "250"; value: "-39.1629"; } + ListElement{ radius: "45"; angle: "255"; value: "-40.4746"; } + ListElement{ radius: "45"; angle: "260"; value: "-41.4187"; } + ListElement{ radius: "45"; angle: "265"; value: "-41.988"; } + ListElement{ radius: "45"; angle: "270"; value: "-42.1783"; } + ListElement{ radius: "45"; angle: "275"; value: "-41.988"; } + ListElement{ radius: "45"; angle: "280"; value: "-41.4187"; } + ListElement{ radius: "45"; angle: "285"; value: "-40.4746"; } + ListElement{ radius: "45"; angle: "290"; value: "-39.1629"; } + ListElement{ radius: "45"; angle: "295"; value: "-37.4937"; } + ListElement{ radius: "45"; angle: "300"; value: "-35.4795"; } + ListElement{ radius: "45"; angle: "305"; value: "-33.1359"; } + ListElement{ radius: "45"; angle: "310"; value: "-30.4805"; } + ListElement{ radius: "45"; angle: "315"; value: "-27.5336"; } + ListElement{ radius: "45"; angle: "320"; value: "-24.3177"; } + ListElement{ radius: "45"; angle: "325"; value: "-20.8571"; } + ListElement{ radius: "45"; angle: "330"; value: "-17.1783"; } + ListElement{ radius: "45"; angle: "335"; value: "-13.3092"; } + ListElement{ radius: "45"; angle: "340"; value: "-9.27928"; } + ListElement{ radius: "45"; angle: "345"; value: "-5.11923"; } + ListElement{ radius: "45"; angle: "350"; value: "-0.860686"; } + ListElement{ radius: "45"; angle: "355"; value: "3.46394"; } + ListElement{ radius: "45"; angle: "360"; value: "7.82172"; } + ListElement{ radius: "50"; angle: "0"; value: "3.06162e-15"; } + ListElement{ radius: "50"; angle: "5"; value: "4.35779"; } + ListElement{ radius: "50"; angle: "10"; value: "8.68241"; } + ListElement{ radius: "50"; angle: "15"; value: "12.941"; } + ListElement{ radius: "50"; angle: "20"; value: "17.101"; } + ListElement{ radius: "50"; angle: "25"; value: "21.1309"; } + ListElement{ radius: "50"; angle: "30"; value: "25"; } + ListElement{ radius: "50"; angle: "35"; value: "28.6788"; } + ListElement{ radius: "50"; angle: "40"; value: "32.1394"; } + ListElement{ radius: "50"; angle: "45"; value: "35.3553"; } + ListElement{ radius: "50"; angle: "50"; value: "38.3022"; } + ListElement{ radius: "50"; angle: "55"; value: "40.9576"; } + ListElement{ radius: "50"; angle: "60"; value: "43.3013"; } + ListElement{ radius: "50"; angle: "65"; value: "45.3154"; } + ListElement{ radius: "50"; angle: "70"; value: "46.9846"; } + ListElement{ radius: "50"; angle: "75"; value: "48.2963"; } + ListElement{ radius: "50"; angle: "80"; value: "49.2404"; } + ListElement{ radius: "50"; angle: "85"; value: "49.8097"; } + ListElement{ radius: "50"; angle: "90"; value: "50"; } + ListElement{ radius: "50"; angle: "95"; value: "49.8097"; } + ListElement{ radius: "50"; angle: "100"; value: "49.2404"; } + ListElement{ radius: "50"; angle: "105"; value: "48.2963"; } + ListElement{ radius: "50"; angle: "110"; value: "46.9846"; } + ListElement{ radius: "50"; angle: "115"; value: "45.3154"; } + ListElement{ radius: "50"; angle: "120"; value: "43.3013"; } + ListElement{ radius: "50"; angle: "125"; value: "40.9576"; } + ListElement{ radius: "50"; angle: "130"; value: "38.3022"; } + ListElement{ radius: "50"; angle: "135"; value: "35.3553"; } + ListElement{ radius: "50"; angle: "140"; value: "32.1394"; } + ListElement{ radius: "50"; angle: "145"; value: "28.6788"; } + ListElement{ radius: "50"; angle: "150"; value: "25"; } + ListElement{ radius: "50"; angle: "155"; value: "21.1309"; } + ListElement{ radius: "50"; angle: "160"; value: "17.101"; } + ListElement{ radius: "50"; angle: "165"; value: "12.941"; } + ListElement{ radius: "50"; angle: "170"; value: "8.68241"; } + ListElement{ radius: "50"; angle: "175"; value: "4.35779"; } + ListElement{ radius: "50"; angle: "180"; value: "9.18485e-15"; } + ListElement{ radius: "50"; angle: "185"; value: "-4.35779"; } + ListElement{ radius: "50"; angle: "190"; value: "-8.68241"; } + ListElement{ radius: "50"; angle: "195"; value: "-12.941"; } + ListElement{ radius: "50"; angle: "200"; value: "-17.101"; } + ListElement{ radius: "50"; angle: "205"; value: "-21.1309"; } + ListElement{ radius: "50"; angle: "210"; value: "-25"; } + ListElement{ radius: "50"; angle: "215"; value: "-28.6788"; } + ListElement{ radius: "50"; angle: "220"; value: "-32.1394"; } + ListElement{ radius: "50"; angle: "225"; value: "-35.3553"; } + ListElement{ radius: "50"; angle: "230"; value: "-38.3022"; } + ListElement{ radius: "50"; angle: "235"; value: "-40.9576"; } + ListElement{ radius: "50"; angle: "240"; value: "-43.3013"; } + ListElement{ radius: "50"; angle: "245"; value: "-45.3154"; } + ListElement{ radius: "50"; angle: "250"; value: "-46.9846"; } + ListElement{ radius: "50"; angle: "255"; value: "-48.2963"; } + ListElement{ radius: "50"; angle: "260"; value: "-49.2404"; } + ListElement{ radius: "50"; angle: "265"; value: "-49.8097"; } + ListElement{ radius: "50"; angle: "270"; value: "-50"; } + ListElement{ radius: "50"; angle: "275"; value: "-49.8097"; } + ListElement{ radius: "50"; angle: "280"; value: "-49.2404"; } + ListElement{ radius: "50"; angle: "285"; value: "-48.2963"; } + ListElement{ radius: "50"; angle: "290"; value: "-46.9846"; } + ListElement{ radius: "50"; angle: "295"; value: "-45.3154"; } + ListElement{ radius: "50"; angle: "300"; value: "-43.3013"; } + ListElement{ radius: "50"; angle: "305"; value: "-40.9576"; } + ListElement{ radius: "50"; angle: "310"; value: "-38.3022"; } + ListElement{ radius: "50"; angle: "315"; value: "-35.3553"; } + ListElement{ radius: "50"; angle: "320"; value: "-32.1394"; } + ListElement{ radius: "50"; angle: "325"; value: "-28.6788"; } + ListElement{ radius: "50"; angle: "330"; value: "-25"; } + ListElement{ radius: "50"; angle: "335"; value: "-21.1309"; } + ListElement{ radius: "50"; angle: "340"; value: "-17.101"; } + ListElement{ radius: "50"; angle: "345"; value: "-12.941"; } + ListElement{ radius: "50"; angle: "350"; value: "-8.68241"; } + ListElement{ radius: "50"; angle: "355"; value: "-4.35779"; } + ListElement{ radius: "50"; angle: "360"; value: "-9.18485e-15"; } + ListElement{ radius: "55"; angle: "0"; value: "-7.82172"; } + ListElement{ radius: "55"; angle: "5"; value: "-3.46394"; } + ListElement{ radius: "55"; angle: "10"; value: "0.860686"; } + ListElement{ radius: "55"; angle: "15"; value: "5.11923"; } + ListElement{ radius: "55"; angle: "20"; value: "9.27928"; } + ListElement{ radius: "55"; angle: "25"; value: "13.3092"; } + ListElement{ radius: "55"; angle: "30"; value: "17.1783"; } + ListElement{ radius: "55"; angle: "35"; value: "20.8571"; } + ListElement{ radius: "55"; angle: "40"; value: "24.3177"; } + ListElement{ radius: "55"; angle: "45"; value: "27.5336"; } + ListElement{ radius: "55"; angle: "50"; value: "30.4805"; } + ListElement{ radius: "55"; angle: "55"; value: "33.1359"; } + ListElement{ radius: "55"; angle: "60"; value: "35.4795"; } + ListElement{ radius: "55"; angle: "65"; value: "37.4937"; } + ListElement{ radius: "55"; angle: "70"; value: "39.1629"; } + ListElement{ radius: "55"; angle: "75"; value: "40.4746"; } + ListElement{ radius: "55"; angle: "80"; value: "41.4187"; } + ListElement{ radius: "55"; angle: "85"; value: "41.988"; } + ListElement{ radius: "55"; angle: "90"; value: "42.1783"; } + ListElement{ radius: "55"; angle: "95"; value: "41.988"; } + ListElement{ radius: "55"; angle: "100"; value: "41.4187"; } + ListElement{ radius: "55"; angle: "105"; value: "40.4746"; } + ListElement{ radius: "55"; angle: "110"; value: "39.1629"; } + ListElement{ radius: "55"; angle: "115"; value: "37.4937"; } + ListElement{ radius: "55"; angle: "120"; value: "35.4795"; } + ListElement{ radius: "55"; angle: "125"; value: "33.1359"; } + ListElement{ radius: "55"; angle: "130"; value: "30.4805"; } + ListElement{ radius: "55"; angle: "135"; value: "27.5336"; } + ListElement{ radius: "55"; angle: "140"; value: "24.3177"; } + ListElement{ radius: "55"; angle: "145"; value: "20.8571"; } + ListElement{ radius: "55"; angle: "150"; value: "17.1783"; } + ListElement{ radius: "55"; angle: "155"; value: "13.3092"; } + ListElement{ radius: "55"; angle: "160"; value: "9.27928"; } + ListElement{ radius: "55"; angle: "165"; value: "5.11923"; } + ListElement{ radius: "55"; angle: "170"; value: "0.860686"; } + ListElement{ radius: "55"; angle: "175"; value: "-3.46394"; } + ListElement{ radius: "55"; angle: "180"; value: "-7.82172"; } + ListElement{ radius: "55"; angle: "185"; value: "-12.1795"; } + ListElement{ radius: "55"; angle: "190"; value: "-16.5041"; } + ListElement{ radius: "55"; angle: "195"; value: "-20.7627"; } + ListElement{ radius: "55"; angle: "200"; value: "-24.9227"; } + ListElement{ radius: "55"; angle: "205"; value: "-28.9526"; } + ListElement{ radius: "55"; angle: "210"; value: "-32.8217"; } + ListElement{ radius: "55"; angle: "215"; value: "-36.5005"; } + ListElement{ radius: "55"; angle: "220"; value: "-39.9611"; } + ListElement{ radius: "55"; angle: "225"; value: "-43.1771"; } + ListElement{ radius: "55"; angle: "230"; value: "-46.1239"; } + ListElement{ radius: "55"; angle: "235"; value: "-48.7793"; } + ListElement{ radius: "55"; angle: "240"; value: "-51.123"; } + ListElement{ radius: "55"; angle: "245"; value: "-53.1371"; } + ListElement{ radius: "55"; angle: "250"; value: "-54.8064"; } + ListElement{ radius: "55"; angle: "255"; value: "-56.118"; } + ListElement{ radius: "55"; angle: "260"; value: "-57.0621"; } + ListElement{ radius: "55"; angle: "265"; value: "-57.6315"; } + ListElement{ radius: "55"; angle: "270"; value: "-57.8217"; } + ListElement{ radius: "55"; angle: "275"; value: "-57.6315"; } + ListElement{ radius: "55"; angle: "280"; value: "-57.0621"; } + ListElement{ radius: "55"; angle: "285"; value: "-56.118"; } + ListElement{ radius: "55"; angle: "290"; value: "-54.8064"; } + ListElement{ radius: "55"; angle: "295"; value: "-53.1371"; } + ListElement{ radius: "55"; angle: "300"; value: "-51.123"; } + ListElement{ radius: "55"; angle: "305"; value: "-48.7793"; } + ListElement{ radius: "55"; angle: "310"; value: "-46.1239"; } + ListElement{ radius: "55"; angle: "315"; value: "-43.1771"; } + ListElement{ radius: "55"; angle: "320"; value: "-39.9611"; } + ListElement{ radius: "55"; angle: "325"; value: "-36.5005"; } + ListElement{ radius: "55"; angle: "330"; value: "-32.8217"; } + ListElement{ radius: "55"; angle: "335"; value: "-28.9526"; } + ListElement{ radius: "55"; angle: "340"; value: "-24.9227"; } + ListElement{ radius: "55"; angle: "345"; value: "-20.7627"; } + ListElement{ radius: "55"; angle: "350"; value: "-16.5041"; } + ListElement{ radius: "55"; angle: "355"; value: "-12.1795"; } + ListElement{ radius: "55"; angle: "360"; value: "-7.82172"; } + ListElement{ radius: "60"; angle: "0"; value: "-15.4508"; } + ListElement{ radius: "60"; angle: "5"; value: "-11.0931"; } + ListElement{ radius: "60"; angle: "10"; value: "-6.76844"; } + ListElement{ radius: "60"; angle: "15"; value: "-2.5099"; } + ListElement{ radius: "60"; angle: "20"; value: "1.65016"; } + ListElement{ radius: "60"; angle: "25"; value: "5.68006"; } + ListElement{ radius: "60"; angle: "30"; value: "9.54915"; } + ListElement{ radius: "60"; angle: "35"; value: "13.228"; } + ListElement{ radius: "60"; angle: "40"; value: "16.6885"; } + ListElement{ radius: "60"; angle: "45"; value: "19.9045"; } + ListElement{ radius: "60"; angle: "50"; value: "22.8514"; } + ListElement{ radius: "60"; angle: "55"; value: "25.5068"; } + ListElement{ radius: "60"; angle: "60"; value: "27.8504"; } + ListElement{ radius: "60"; angle: "65"; value: "29.8645"; } + ListElement{ radius: "60"; angle: "70"; value: "31.5338"; } + ListElement{ radius: "60"; angle: "75"; value: "32.8454"; } + ListElement{ radius: "60"; angle: "80"; value: "33.7895"; } + ListElement{ radius: "60"; angle: "85"; value: "34.3589"; } + ListElement{ radius: "60"; angle: "90"; value: "34.5492"; } + ListElement{ radius: "60"; angle: "95"; value: "34.3589"; } + ListElement{ radius: "60"; angle: "100"; value: "33.7895"; } + ListElement{ radius: "60"; angle: "105"; value: "32.8454"; } + ListElement{ radius: "60"; angle: "110"; value: "31.5338"; } + ListElement{ radius: "60"; angle: "115"; value: "29.8645"; } + ListElement{ radius: "60"; angle: "120"; value: "27.8504"; } + ListElement{ radius: "60"; angle: "125"; value: "25.5068"; } + ListElement{ radius: "60"; angle: "130"; value: "22.8514"; } + ListElement{ radius: "60"; angle: "135"; value: "19.9045"; } + ListElement{ radius: "60"; angle: "140"; value: "16.6885"; } + ListElement{ radius: "60"; angle: "145"; value: "13.228"; } + ListElement{ radius: "60"; angle: "150"; value: "9.54915"; } + ListElement{ radius: "60"; angle: "155"; value: "5.68006"; } + ListElement{ radius: "60"; angle: "160"; value: "1.65016"; } + ListElement{ radius: "60"; angle: "165"; value: "-2.5099"; } + ListElement{ radius: "60"; angle: "170"; value: "-6.76844"; } + ListElement{ radius: "60"; angle: "175"; value: "-11.0931"; } + ListElement{ radius: "60"; angle: "180"; value: "-15.4508"; } + ListElement{ radius: "60"; angle: "185"; value: "-19.8086"; } + ListElement{ radius: "60"; angle: "190"; value: "-24.1333"; } + ListElement{ radius: "60"; angle: "195"; value: "-28.3918"; } + ListElement{ radius: "60"; angle: "200"; value: "-32.5519"; } + ListElement{ radius: "60"; angle: "205"; value: "-36.5818"; } + ListElement{ radius: "60"; angle: "210"; value: "-40.4508"; } + ListElement{ radius: "60"; angle: "215"; value: "-44.1297"; } + ListElement{ radius: "60"; angle: "220"; value: "-47.5902"; } + ListElement{ radius: "60"; angle: "225"; value: "-50.8062"; } + ListElement{ radius: "60"; angle: "230"; value: "-53.7531"; } + ListElement{ radius: "60"; angle: "235"; value: "-56.4085"; } + ListElement{ radius: "60"; angle: "240"; value: "-58.7521"; } + ListElement{ radius: "60"; angle: "245"; value: "-60.7662"; } + ListElement{ radius: "60"; angle: "250"; value: "-62.4355"; } + ListElement{ radius: "60"; angle: "255"; value: "-63.7471"; } + ListElement{ radius: "60"; angle: "260"; value: "-64.6912"; } + ListElement{ radius: "60"; angle: "265"; value: "-65.2606"; } + ListElement{ radius: "60"; angle: "270"; value: "-65.4508"; } + ListElement{ radius: "60"; angle: "275"; value: "-65.2606"; } + ListElement{ radius: "60"; angle: "280"; value: "-64.6912"; } + ListElement{ radius: "60"; angle: "285"; value: "-63.7471"; } + ListElement{ radius: "60"; angle: "290"; value: "-62.4355"; } + ListElement{ radius: "60"; angle: "295"; value: "-60.7662"; } + ListElement{ radius: "60"; angle: "300"; value: "-58.7521"; } + ListElement{ radius: "60"; angle: "305"; value: "-56.4085"; } + ListElement{ radius: "60"; angle: "310"; value: "-53.7531"; } + ListElement{ radius: "60"; angle: "315"; value: "-50.8062"; } + ListElement{ radius: "60"; angle: "320"; value: "-47.5902"; } + ListElement{ radius: "60"; angle: "325"; value: "-44.1297"; } + ListElement{ radius: "60"; angle: "330"; value: "-40.4508"; } + ListElement{ radius: "60"; angle: "335"; value: "-36.5818"; } + ListElement{ radius: "60"; angle: "340"; value: "-32.5519"; } + ListElement{ radius: "60"; angle: "345"; value: "-28.3918"; } + ListElement{ radius: "60"; angle: "350"; value: "-24.1333"; } + ListElement{ radius: "60"; angle: "355"; value: "-19.8086"; } + ListElement{ radius: "60"; angle: "360"; value: "-15.4508"; } + ListElement{ radius: "65"; angle: "0"; value: "-22.6995"; } + ListElement{ radius: "65"; angle: "5"; value: "-18.3417"; } + ListElement{ radius: "65"; angle: "10"; value: "-14.0171"; } + ListElement{ radius: "65"; angle: "15"; value: "-9.75857"; } + ListElement{ radius: "65"; angle: "20"; value: "-5.59852"; } + ListElement{ radius: "65"; angle: "25"; value: "-1.56861"; } + ListElement{ radius: "65"; angle: "30"; value: "2.30048"; } + ListElement{ radius: "65"; angle: "35"; value: "5.9793"; } + ListElement{ radius: "65"; angle: "40"; value: "9.43986"; } + ListElement{ radius: "65"; angle: "45"; value: "12.6558"; } + ListElement{ radius: "65"; angle: "50"; value: "15.6027"; } + ListElement{ radius: "65"; angle: "55"; value: "18.2581"; } + ListElement{ radius: "65"; angle: "60"; value: "20.6017"; } + ListElement{ radius: "65"; angle: "65"; value: "22.6159"; } + ListElement{ radius: "65"; angle: "70"; value: "24.2851"; } + ListElement{ radius: "65"; angle: "75"; value: "25.5968"; } + ListElement{ radius: "65"; angle: "80"; value: "26.5409"; } + ListElement{ radius: "65"; angle: "85"; value: "27.1102"; } + ListElement{ radius: "65"; angle: "90"; value: "27.3005"; } + ListElement{ radius: "65"; angle: "95"; value: "27.1102"; } + ListElement{ radius: "65"; angle: "100"; value: "26.5409"; } + ListElement{ radius: "65"; angle: "105"; value: "25.5968"; } + ListElement{ radius: "65"; angle: "110"; value: "24.2851"; } + ListElement{ radius: "65"; angle: "115"; value: "22.6159"; } + ListElement{ radius: "65"; angle: "120"; value: "20.6017"; } + ListElement{ radius: "65"; angle: "125"; value: "18.2581"; } + ListElement{ radius: "65"; angle: "130"; value: "15.6027"; } + ListElement{ radius: "65"; angle: "135"; value: "12.6558"; } + ListElement{ radius: "65"; angle: "140"; value: "9.43986"; } + ListElement{ radius: "65"; angle: "145"; value: "5.9793"; } + ListElement{ radius: "65"; angle: "150"; value: "2.30048"; } + ListElement{ radius: "65"; angle: "155"; value: "-1.56861"; } + ListElement{ radius: "65"; angle: "160"; value: "-5.59852"; } + ListElement{ radius: "65"; angle: "165"; value: "-9.75857"; } + ListElement{ radius: "65"; angle: "170"; value: "-14.0171"; } + ListElement{ radius: "65"; angle: "175"; value: "-18.3417"; } + ListElement{ radius: "65"; angle: "180"; value: "-22.6995"; } + ListElement{ radius: "65"; angle: "185"; value: "-27.0573"; } + ListElement{ radius: "65"; angle: "190"; value: "-31.3819"; } + ListElement{ radius: "65"; angle: "195"; value: "-35.6405"; } + ListElement{ radius: "65"; angle: "200"; value: "-39.8005"; } + ListElement{ radius: "65"; angle: "205"; value: "-43.8304"; } + ListElement{ radius: "65"; angle: "210"; value: "-47.6995"; } + ListElement{ radius: "65"; angle: "215"; value: "-51.3783"; } + ListElement{ radius: "65"; angle: "220"; value: "-54.8389"; } + ListElement{ radius: "65"; angle: "225"; value: "-58.0549"; } + ListElement{ radius: "65"; angle: "230"; value: "-61.0017"; } + ListElement{ radius: "65"; angle: "235"; value: "-63.6571"; } + ListElement{ radius: "65"; angle: "240"; value: "-66.0008"; } + ListElement{ radius: "65"; angle: "245"; value: "-68.0149"; } + ListElement{ radius: "65"; angle: "250"; value: "-69.6842"; } + ListElement{ radius: "65"; angle: "255"; value: "-70.9958"; } + ListElement{ radius: "65"; angle: "260"; value: "-71.9399"; } + ListElement{ radius: "65"; angle: "265"; value: "-72.5093"; } + ListElement{ radius: "65"; angle: "270"; value: "-72.6995"; } + ListElement{ radius: "65"; angle: "275"; value: "-72.5093"; } + ListElement{ radius: "65"; angle: "280"; value: "-71.9399"; } + ListElement{ radius: "65"; angle: "285"; value: "-70.9958"; } + ListElement{ radius: "65"; angle: "290"; value: "-69.6842"; } + ListElement{ radius: "65"; angle: "295"; value: "-68.0149"; } + ListElement{ radius: "65"; angle: "300"; value: "-66.0008"; } + ListElement{ radius: "65"; angle: "305"; value: "-63.6571"; } + ListElement{ radius: "65"; angle: "310"; value: "-61.0017"; } + ListElement{ radius: "65"; angle: "315"; value: "-58.0549"; } + ListElement{ radius: "65"; angle: "320"; value: "-54.8389"; } + ListElement{ radius: "65"; angle: "325"; value: "-51.3783"; } + ListElement{ radius: "65"; angle: "330"; value: "-47.6995"; } + ListElement{ radius: "65"; angle: "335"; value: "-43.8304"; } + ListElement{ radius: "65"; angle: "340"; value: "-39.8005"; } + ListElement{ radius: "65"; angle: "345"; value: "-35.6405"; } + ListElement{ radius: "65"; angle: "350"; value: "-31.3819"; } + ListElement{ radius: "65"; angle: "355"; value: "-27.0573"; } + ListElement{ radius: "65"; angle: "360"; value: "-22.6995"; } + ListElement{ radius: "70"; angle: "0"; value: "-29.3893"; } + ListElement{ radius: "70"; angle: "5"; value: "-25.0315"; } + ListElement{ radius: "70"; angle: "10"; value: "-20.7069"; } + ListElement{ radius: "70"; angle: "15"; value: "-16.4483"; } + ListElement{ radius: "70"; angle: "20"; value: "-12.2883"; } + ListElement{ radius: "70"; angle: "25"; value: "-8.25835"; } + ListElement{ radius: "70"; angle: "30"; value: "-4.38926"; } + ListElement{ radius: "70"; angle: "35"; value: "-0.710441"; } + ListElement{ radius: "70"; angle: "40"; value: "2.75012"; } + ListElement{ radius: "70"; angle: "45"; value: "5.96608"; } + ListElement{ radius: "70"; angle: "50"; value: "8.91296"; } + ListElement{ radius: "70"; angle: "55"; value: "11.5683"; } + ListElement{ radius: "70"; angle: "60"; value: "13.912"; } + ListElement{ radius: "70"; angle: "65"; value: "15.9261"; } + ListElement{ radius: "70"; angle: "70"; value: "17.5954"; } + ListElement{ radius: "70"; angle: "75"; value: "18.907"; } + ListElement{ radius: "70"; angle: "80"; value: "19.8511"; } + ListElement{ radius: "70"; angle: "85"; value: "20.4205"; } + ListElement{ radius: "70"; angle: "90"; value: "20.6107"; } + ListElement{ radius: "70"; angle: "95"; value: "20.4205"; } + ListElement{ radius: "70"; angle: "100"; value: "19.8511"; } + ListElement{ radius: "70"; angle: "105"; value: "18.907"; } + ListElement{ radius: "70"; angle: "110"; value: "17.5954"; } + ListElement{ radius: "70"; angle: "115"; value: "15.9261"; } + ListElement{ radius: "70"; angle: "120"; value: "13.912"; } + ListElement{ radius: "70"; angle: "125"; value: "11.5683"; } + ListElement{ radius: "70"; angle: "130"; value: "8.91296"; } + ListElement{ radius: "70"; angle: "135"; value: "5.96608"; } + ListElement{ radius: "70"; angle: "140"; value: "2.75012"; } + ListElement{ radius: "70"; angle: "145"; value: "-0.710441"; } + ListElement{ radius: "70"; angle: "150"; value: "-4.38926"; } + ListElement{ radius: "70"; angle: "155"; value: "-8.25835"; } + ListElement{ radius: "70"; angle: "160"; value: "-12.2883"; } + ListElement{ radius: "70"; angle: "165"; value: "-16.4483"; } + ListElement{ radius: "70"; angle: "170"; value: "-20.7069"; } + ListElement{ radius: "70"; angle: "175"; value: "-25.0315"; } + ListElement{ radius: "70"; angle: "180"; value: "-29.3893"; } + ListElement{ radius: "70"; angle: "185"; value: "-33.747"; } + ListElement{ radius: "70"; angle: "190"; value: "-38.0717"; } + ListElement{ radius: "70"; angle: "195"; value: "-42.3302"; } + ListElement{ radius: "70"; angle: "200"; value: "-46.4903"; } + ListElement{ radius: "70"; angle: "205"; value: "-50.5202"; } + ListElement{ radius: "70"; angle: "210"; value: "-54.3893"; } + ListElement{ radius: "70"; angle: "215"; value: "-58.0681"; } + ListElement{ radius: "70"; angle: "220"; value: "-61.5286"; } + ListElement{ radius: "70"; angle: "225"; value: "-64.7446"; } + ListElement{ radius: "70"; angle: "230"; value: "-67.6915"; } + ListElement{ radius: "70"; angle: "235"; value: "-70.3469"; } + ListElement{ radius: "70"; angle: "240"; value: "-72.6905"; } + ListElement{ radius: "70"; angle: "245"; value: "-74.7047"; } + ListElement{ radius: "70"; angle: "250"; value: "-76.3739"; } + ListElement{ radius: "70"; angle: "255"; value: "-77.6856"; } + ListElement{ radius: "70"; angle: "260"; value: "-78.6297"; } + ListElement{ radius: "70"; angle: "265"; value: "-79.199"; } + ListElement{ radius: "70"; angle: "270"; value: "-79.3893"; } + ListElement{ radius: "70"; angle: "275"; value: "-79.199"; } + ListElement{ radius: "70"; angle: "280"; value: "-78.6297"; } + ListElement{ radius: "70"; angle: "285"; value: "-77.6856"; } + ListElement{ radius: "70"; angle: "290"; value: "-76.3739"; } + ListElement{ radius: "70"; angle: "295"; value: "-74.7047"; } + ListElement{ radius: "70"; angle: "300"; value: "-72.6905"; } + ListElement{ radius: "70"; angle: "305"; value: "-70.3469"; } + ListElement{ radius: "70"; angle: "310"; value: "-67.6915"; } + ListElement{ radius: "70"; angle: "315"; value: "-64.7446"; } + ListElement{ radius: "70"; angle: "320"; value: "-61.5286"; } + ListElement{ radius: "70"; angle: "325"; value: "-58.0681"; } + ListElement{ radius: "70"; angle: "330"; value: "-54.3893"; } + ListElement{ radius: "70"; angle: "335"; value: "-50.5202"; } + ListElement{ radius: "70"; angle: "340"; value: "-46.4903"; } + ListElement{ radius: "70"; angle: "345"; value: "-42.3302"; } + ListElement{ radius: "70"; angle: "350"; value: "-38.0717"; } + ListElement{ radius: "70"; angle: "355"; value: "-33.747"; } + ListElement{ radius: "70"; angle: "360"; value: "-29.3893"; } + ListElement{ radius: "75"; angle: "0"; value: "-35.3553"; } + ListElement{ radius: "75"; angle: "5"; value: "-30.9976"; } + ListElement{ radius: "75"; angle: "10"; value: "-26.6729"; } + ListElement{ radius: "75"; angle: "15"; value: "-22.4144"; } + ListElement{ radius: "75"; angle: "20"; value: "-18.2543"; } + ListElement{ radius: "75"; angle: "25"; value: "-14.2244"; } + ListElement{ radius: "75"; angle: "30"; value: "-10.3553"; } + ListElement{ radius: "75"; angle: "35"; value: "-6.67652"; } + ListElement{ radius: "75"; angle: "40"; value: "-3.21596"; } + ListElement{ radius: "75"; angle: "45"; value: "5.55112e-15"; } + ListElement{ radius: "75"; angle: "50"; value: "2.94688"; } + ListElement{ radius: "75"; angle: "55"; value: "5.60226"; } + ListElement{ radius: "75"; angle: "60"; value: "7.94593"; } + ListElement{ radius: "75"; angle: "65"; value: "9.96005"; } + ListElement{ radius: "75"; angle: "70"; value: "11.6293"; } + ListElement{ radius: "75"; angle: "75"; value: "12.941"; } + ListElement{ radius: "75"; angle: "80"; value: "13.885"; } + ListElement{ radius: "75"; angle: "85"; value: "14.4544"; } + ListElement{ radius: "75"; angle: "90"; value: "14.6447"; } + ListElement{ radius: "75"; angle: "95"; value: "14.4544"; } + ListElement{ radius: "75"; angle: "100"; value: "13.885"; } + ListElement{ radius: "75"; angle: "105"; value: "12.941"; } + ListElement{ radius: "75"; angle: "110"; value: "11.6293"; } + ListElement{ radius: "75"; angle: "115"; value: "9.96005"; } + ListElement{ radius: "75"; angle: "120"; value: "7.94593"; } + ListElement{ radius: "75"; angle: "125"; value: "5.60226"; } + ListElement{ radius: "75"; angle: "130"; value: "2.94688"; } + ListElement{ radius: "75"; angle: "135"; value: "5.55112e-15"; } + ListElement{ radius: "75"; angle: "140"; value: "-3.21596"; } + ListElement{ radius: "75"; angle: "145"; value: "-6.67652"; } + ListElement{ radius: "75"; angle: "150"; value: "-10.3553"; } + ListElement{ radius: "75"; angle: "155"; value: "-14.2244"; } + ListElement{ radius: "75"; angle: "160"; value: "-18.2543"; } + ListElement{ radius: "75"; angle: "165"; value: "-22.4144"; } + ListElement{ radius: "75"; angle: "170"; value: "-26.6729"; } + ListElement{ radius: "75"; angle: "175"; value: "-30.9976"; } + ListElement{ radius: "75"; angle: "180"; value: "-35.3553"; } + ListElement{ radius: "75"; angle: "185"; value: "-39.7131"; } + ListElement{ radius: "75"; angle: "190"; value: "-44.0377"; } + ListElement{ radius: "75"; angle: "195"; value: "-48.2963"; } + ListElement{ radius: "75"; angle: "200"; value: "-52.4563"; } + ListElement{ radius: "75"; angle: "205"; value: "-56.4863"; } + ListElement{ radius: "75"; angle: "210"; value: "-60.3553"; } + ListElement{ radius: "75"; angle: "215"; value: "-64.0342"; } + ListElement{ radius: "75"; angle: "220"; value: "-67.4947"; } + ListElement{ radius: "75"; angle: "225"; value: "-70.7107"; } + ListElement{ radius: "75"; angle: "230"; value: "-73.6576"; } + ListElement{ radius: "75"; angle: "235"; value: "-76.3129"; } + ListElement{ radius: "75"; angle: "240"; value: "-78.6566"; } + ListElement{ radius: "75"; angle: "245"; value: "-80.6707"; } + ListElement{ radius: "75"; angle: "250"; value: "-82.34"; } + ListElement{ radius: "75"; angle: "255"; value: "-83.6516"; } + ListElement{ radius: "75"; angle: "260"; value: "-84.5957"; } + ListElement{ radius: "75"; angle: "265"; value: "-85.1651"; } + ListElement{ radius: "75"; angle: "270"; value: "-85.3553"; } + ListElement{ radius: "75"; angle: "275"; value: "-85.1651"; } + ListElement{ radius: "75"; angle: "280"; value: "-84.5957"; } + ListElement{ radius: "75"; angle: "285"; value: "-83.6516"; } + ListElement{ radius: "75"; angle: "290"; value: "-82.34"; } + ListElement{ radius: "75"; angle: "295"; value: "-80.6707"; } + ListElement{ radius: "75"; angle: "300"; value: "-78.6566"; } + ListElement{ radius: "75"; angle: "305"; value: "-76.3129"; } + ListElement{ radius: "75"; angle: "310"; value: "-73.6576"; } + ListElement{ radius: "75"; angle: "315"; value: "-70.7107"; } + ListElement{ radius: "75"; angle: "320"; value: "-67.4947"; } + ListElement{ radius: "75"; angle: "325"; value: "-64.0342"; } + ListElement{ radius: "75"; angle: "330"; value: "-60.3553"; } + ListElement{ radius: "75"; angle: "335"; value: "-56.4863"; } + ListElement{ radius: "75"; angle: "340"; value: "-52.4563"; } + ListElement{ radius: "75"; angle: "345"; value: "-48.2963"; } + ListElement{ radius: "75"; angle: "350"; value: "-44.0377"; } + ListElement{ radius: "75"; angle: "355"; value: "-39.7131"; } + ListElement{ radius: "75"; angle: "360"; value: "-35.3553"; } + ListElement{ radius: "80"; angle: "0"; value: "-40.4508"; } + ListElement{ radius: "80"; angle: "5"; value: "-36.0931"; } + ListElement{ radius: "80"; angle: "10"; value: "-31.7684"; } + ListElement{ radius: "80"; angle: "15"; value: "-27.5099"; } + ListElement{ radius: "80"; angle: "20"; value: "-23.3498"; } + ListElement{ radius: "80"; angle: "25"; value: "-19.3199"; } + ListElement{ radius: "80"; angle: "30"; value: "-15.4508"; } + ListElement{ radius: "80"; angle: "35"; value: "-11.772"; } + ListElement{ radius: "80"; angle: "40"; value: "-8.31147"; } + ListElement{ radius: "80"; angle: "45"; value: "-5.09551"; } + ListElement{ radius: "80"; angle: "50"; value: "-2.14863"; } + ListElement{ radius: "80"; angle: "55"; value: "0.506752"; } + ListElement{ radius: "80"; angle: "60"; value: "2.85042"; } + ListElement{ radius: "80"; angle: "65"; value: "4.86454"; } + ListElement{ radius: "80"; angle: "70"; value: "6.53378"; } + ListElement{ radius: "80"; angle: "75"; value: "7.84544"; } + ListElement{ radius: "80"; angle: "80"; value: "8.78954"; } + ListElement{ radius: "80"; angle: "85"; value: "9.35889"; } + ListElement{ radius: "80"; angle: "90"; value: "9.54915"; } + ListElement{ radius: "80"; angle: "95"; value: "9.35889"; } + ListElement{ radius: "80"; angle: "100"; value: "8.78954"; } + ListElement{ radius: "80"; angle: "105"; value: "7.84544"; } + ListElement{ radius: "80"; angle: "110"; value: "6.53378"; } + ListElement{ radius: "80"; angle: "115"; value: "4.86454"; } + ListElement{ radius: "80"; angle: "120"; value: "2.85042"; } + ListElement{ radius: "80"; angle: "125"; value: "0.506752"; } + ListElement{ radius: "80"; angle: "130"; value: "-2.14863"; } + ListElement{ radius: "80"; angle: "135"; value: "-5.09551"; } + ListElement{ radius: "80"; angle: "140"; value: "-8.31147"; } + ListElement{ radius: "80"; angle: "145"; value: "-11.772"; } + ListElement{ radius: "80"; angle: "150"; value: "-15.4508"; } + ListElement{ radius: "80"; angle: "155"; value: "-19.3199"; } + ListElement{ radius: "80"; angle: "160"; value: "-23.3498"; } + ListElement{ radius: "80"; angle: "165"; value: "-27.5099"; } + ListElement{ radius: "80"; angle: "170"; value: "-31.7684"; } + ListElement{ radius: "80"; angle: "175"; value: "-36.0931"; } + ListElement{ radius: "80"; angle: "180"; value: "-40.4508"; } + ListElement{ radius: "80"; angle: "185"; value: "-44.8086"; } + ListElement{ radius: "80"; angle: "190"; value: "-49.1333"; } + ListElement{ radius: "80"; angle: "195"; value: "-53.3918"; } + ListElement{ radius: "80"; angle: "200"; value: "-57.5519"; } + ListElement{ radius: "80"; angle: "205"; value: "-61.5818"; } + ListElement{ radius: "80"; angle: "210"; value: "-65.4508"; } + ListElement{ radius: "80"; angle: "215"; value: "-69.1297"; } + ListElement{ radius: "80"; angle: "220"; value: "-72.5902"; } + ListElement{ radius: "80"; angle: "225"; value: "-75.8062"; } + ListElement{ radius: "80"; angle: "230"; value: "-78.7531"; } + ListElement{ radius: "80"; angle: "235"; value: "-81.4085"; } + ListElement{ radius: "80"; angle: "240"; value: "-83.7521"; } + ListElement{ radius: "80"; angle: "245"; value: "-85.7662"; } + ListElement{ radius: "80"; angle: "250"; value: "-87.4355"; } + ListElement{ radius: "80"; angle: "255"; value: "-88.7471"; } + ListElement{ radius: "80"; angle: "260"; value: "-89.6912"; } + ListElement{ radius: "80"; angle: "265"; value: "-90.2606"; } + ListElement{ radius: "80"; angle: "270"; value: "-90.4508"; } + ListElement{ radius: "80"; angle: "275"; value: "-90.2606"; } + ListElement{ radius: "80"; angle: "280"; value: "-89.6912"; } + ListElement{ radius: "80"; angle: "285"; value: "-88.7471"; } + ListElement{ radius: "80"; angle: "290"; value: "-87.4355"; } + ListElement{ radius: "80"; angle: "295"; value: "-85.7662"; } + ListElement{ radius: "80"; angle: "300"; value: "-83.7521"; } + ListElement{ radius: "80"; angle: "305"; value: "-81.4085"; } + ListElement{ radius: "80"; angle: "310"; value: "-78.7531"; } + ListElement{ radius: "80"; angle: "315"; value: "-75.8062"; } + ListElement{ radius: "80"; angle: "320"; value: "-72.5902"; } + ListElement{ radius: "80"; angle: "325"; value: "-69.1297"; } + ListElement{ radius: "80"; angle: "330"; value: "-65.4508"; } + ListElement{ radius: "80"; angle: "335"; value: "-61.5818"; } + ListElement{ radius: "80"; angle: "340"; value: "-57.5519"; } + ListElement{ radius: "80"; angle: "345"; value: "-53.3918"; } + ListElement{ radius: "80"; angle: "350"; value: "-49.1333"; } + ListElement{ radius: "80"; angle: "355"; value: "-44.8086"; } + ListElement{ radius: "80"; angle: "360"; value: "-40.4508"; } + ListElement{ radius: "85"; angle: "0"; value: "-44.5503"; } + ListElement{ radius: "85"; angle: "5"; value: "-40.1925"; } + ListElement{ radius: "85"; angle: "10"; value: "-35.8679"; } + ListElement{ radius: "85"; angle: "15"; value: "-31.6094"; } + ListElement{ radius: "85"; angle: "20"; value: "-27.4493"; } + ListElement{ radius: "85"; angle: "25"; value: "-23.4194"; } + ListElement{ radius: "85"; angle: "30"; value: "-19.5503"; } + ListElement{ radius: "85"; angle: "35"; value: "-15.8715"; } + ListElement{ radius: "85"; angle: "40"; value: "-12.4109"; } + ListElement{ radius: "85"; angle: "45"; value: "-9.19499"; } + ListElement{ radius: "85"; angle: "50"; value: "-6.2481"; } + ListElement{ radius: "85"; angle: "55"; value: "-3.59272"; } + ListElement{ radius: "85"; angle: "60"; value: "-1.24906"; } + ListElement{ radius: "85"; angle: "65"; value: "0.765063"; } + ListElement{ radius: "85"; angle: "70"; value: "2.4343"; } + ListElement{ radius: "85"; angle: "75"; value: "3.74597"; } + ListElement{ radius: "85"; angle: "80"; value: "4.69006"; } + ListElement{ radius: "85"; angle: "85"; value: "5.25941"; } + ListElement{ radius: "85"; angle: "90"; value: "5.44967"; } + ListElement{ radius: "85"; angle: "95"; value: "5.25941"; } + ListElement{ radius: "85"; angle: "100"; value: "4.69006"; } + ListElement{ radius: "85"; angle: "105"; value: "3.74597"; } + ListElement{ radius: "85"; angle: "110"; value: "2.4343"; } + ListElement{ radius: "85"; angle: "115"; value: "0.765063"; } + ListElement{ radius: "85"; angle: "120"; value: "-1.24906"; } + ListElement{ radius: "85"; angle: "125"; value: "-3.59272"; } + ListElement{ radius: "85"; angle: "130"; value: "-6.2481"; } + ListElement{ radius: "85"; angle: "135"; value: "-9.19499"; } + ListElement{ radius: "85"; angle: "140"; value: "-12.4109"; } + ListElement{ radius: "85"; angle: "145"; value: "-15.8715"; } + ListElement{ radius: "85"; angle: "150"; value: "-19.5503"; } + ListElement{ radius: "85"; angle: "155"; value: "-23.4194"; } + ListElement{ radius: "85"; angle: "160"; value: "-27.4493"; } + ListElement{ radius: "85"; angle: "165"; value: "-31.6094"; } + ListElement{ radius: "85"; angle: "170"; value: "-35.8679"; } + ListElement{ radius: "85"; angle: "175"; value: "-40.1925"; } + ListElement{ radius: "85"; angle: "180"; value: "-44.5503"; } + ListElement{ radius: "85"; angle: "185"; value: "-48.9081"; } + ListElement{ radius: "85"; angle: "190"; value: "-53.2327"; } + ListElement{ radius: "85"; angle: "195"; value: "-57.4913"; } + ListElement{ radius: "85"; angle: "200"; value: "-61.6513"; } + ListElement{ radius: "85"; angle: "205"; value: "-65.6812"; } + ListElement{ radius: "85"; angle: "210"; value: "-69.5503"; } + ListElement{ radius: "85"; angle: "215"; value: "-73.2291"; } + ListElement{ radius: "85"; angle: "220"; value: "-76.6897"; } + ListElement{ radius: "85"; angle: "225"; value: "-79.9057"; } + ListElement{ radius: "85"; angle: "230"; value: "-82.8525"; } + ListElement{ radius: "85"; angle: "235"; value: "-85.5079"; } + ListElement{ radius: "85"; angle: "240"; value: "-87.8516"; } + ListElement{ radius: "85"; angle: "245"; value: "-89.8657"; } + ListElement{ radius: "85"; angle: "250"; value: "-91.535"; } + ListElement{ radius: "85"; angle: "255"; value: "-92.8466"; } + ListElement{ radius: "85"; angle: "260"; value: "-93.7907"; } + ListElement{ radius: "85"; angle: "265"; value: "-94.3601"; } + ListElement{ radius: "85"; angle: "270"; value: "-94.5503"; } + ListElement{ radius: "85"; angle: "275"; value: "-94.3601"; } + ListElement{ radius: "85"; angle: "280"; value: "-93.7907"; } + ListElement{ radius: "85"; angle: "285"; value: "-92.8466"; } + ListElement{ radius: "85"; angle: "290"; value: "-91.535"; } + ListElement{ radius: "85"; angle: "295"; value: "-89.8657"; } + ListElement{ radius: "85"; angle: "300"; value: "-87.8516"; } + ListElement{ radius: "85"; angle: "305"; value: "-85.5079"; } + ListElement{ radius: "85"; angle: "310"; value: "-82.8525"; } + ListElement{ radius: "85"; angle: "315"; value: "-79.9057"; } + ListElement{ radius: "85"; angle: "320"; value: "-76.6897"; } + ListElement{ radius: "85"; angle: "325"; value: "-73.2291"; } + ListElement{ radius: "85"; angle: "330"; value: "-69.5503"; } + ListElement{ radius: "85"; angle: "335"; value: "-65.6812"; } + ListElement{ radius: "85"; angle: "340"; value: "-61.6513"; } + ListElement{ radius: "85"; angle: "345"; value: "-57.4913"; } + ListElement{ radius: "85"; angle: "350"; value: "-53.2327"; } + ListElement{ radius: "85"; angle: "355"; value: "-48.9081"; } + ListElement{ radius: "85"; angle: "360"; value: "-44.5503"; } + ListElement{ radius: "90"; angle: "0"; value: "-47.5528"; } + ListElement{ radius: "90"; angle: "5"; value: "-43.195"; } + ListElement{ radius: "90"; angle: "10"; value: "-38.8704"; } + ListElement{ radius: "90"; angle: "15"; value: "-34.6119"; } + ListElement{ radius: "90"; angle: "20"; value: "-30.4518"; } + ListElement{ radius: "90"; angle: "25"; value: "-26.4219"; } + ListElement{ radius: "90"; angle: "30"; value: "-22.5528"; } + ListElement{ radius: "90"; angle: "35"; value: "-18.874"; } + ListElement{ radius: "90"; angle: "40"; value: "-15.4134"; } + ListElement{ radius: "90"; angle: "45"; value: "-12.1975"; } + ListElement{ radius: "90"; angle: "50"; value: "-9.2506"; } + ListElement{ radius: "90"; angle: "55"; value: "-6.59522"; } + ListElement{ radius: "90"; angle: "60"; value: "-4.25156"; } + ListElement{ radius: "90"; angle: "65"; value: "-2.23744"; } + ListElement{ radius: "90"; angle: "70"; value: "-0.568195"; } + ListElement{ radius: "90"; angle: "75"; value: "0.743465"; } + ListElement{ radius: "90"; angle: "80"; value: "1.68756"; } + ListElement{ radius: "90"; angle: "85"; value: "2.25691"; } + ListElement{ radius: "90"; angle: "90"; value: "2.44717"; } + ListElement{ radius: "90"; angle: "95"; value: "2.25691"; } + ListElement{ radius: "90"; angle: "100"; value: "1.68756"; } + ListElement{ radius: "90"; angle: "105"; value: "0.743465"; } + ListElement{ radius: "90"; angle: "110"; value: "-0.568195"; } + ListElement{ radius: "90"; angle: "115"; value: "-2.23744"; } + ListElement{ radius: "90"; angle: "120"; value: "-4.25156"; } + ListElement{ radius: "90"; angle: "125"; value: "-6.59522"; } + ListElement{ radius: "90"; angle: "130"; value: "-9.2506"; } + ListElement{ radius: "90"; angle: "135"; value: "-12.1975"; } + ListElement{ radius: "90"; angle: "140"; value: "-15.4134"; } + ListElement{ radius: "90"; angle: "145"; value: "-18.874"; } + ListElement{ radius: "90"; angle: "150"; value: "-22.5528"; } + ListElement{ radius: "90"; angle: "155"; value: "-26.4219"; } + ListElement{ radius: "90"; angle: "160"; value: "-30.4518"; } + ListElement{ radius: "90"; angle: "165"; value: "-34.6119"; } + ListElement{ radius: "90"; angle: "170"; value: "-38.8704"; } + ListElement{ radius: "90"; angle: "175"; value: "-43.195"; } + ListElement{ radius: "90"; angle: "180"; value: "-47.5528"; } + ListElement{ radius: "90"; angle: "185"; value: "-51.9106"; } + ListElement{ radius: "90"; angle: "190"; value: "-56.2352"; } + ListElement{ radius: "90"; angle: "195"; value: "-60.4938"; } + ListElement{ radius: "90"; angle: "200"; value: "-64.6538"; } + ListElement{ radius: "90"; angle: "205"; value: "-68.6837"; } + ListElement{ radius: "90"; angle: "210"; value: "-72.5528"; } + ListElement{ radius: "90"; angle: "215"; value: "-76.2316"; } + ListElement{ radius: "90"; angle: "220"; value: "-79.6922"; } + ListElement{ radius: "90"; angle: "225"; value: "-82.9082"; } + ListElement{ radius: "90"; angle: "230"; value: "-85.855"; } + ListElement{ radius: "90"; angle: "235"; value: "-88.5104"; } + ListElement{ radius: "90"; angle: "240"; value: "-90.8541"; } + ListElement{ radius: "90"; angle: "245"; value: "-92.8682"; } + ListElement{ radius: "90"; angle: "250"; value: "-94.5375"; } + ListElement{ radius: "90"; angle: "255"; value: "-95.8491"; } + ListElement{ radius: "90"; angle: "260"; value: "-96.7932"; } + ListElement{ radius: "90"; angle: "265"; value: "-97.3626"; } + ListElement{ radius: "90"; angle: "270"; value: "-97.5528"; } + ListElement{ radius: "90"; angle: "275"; value: "-97.3626"; } + ListElement{ radius: "90"; angle: "280"; value: "-96.7932"; } + ListElement{ radius: "90"; angle: "285"; value: "-95.8491"; } + ListElement{ radius: "90"; angle: "290"; value: "-94.5375"; } + ListElement{ radius: "90"; angle: "295"; value: "-92.8682"; } + ListElement{ radius: "90"; angle: "300"; value: "-90.8541"; } + ListElement{ radius: "90"; angle: "305"; value: "-88.5104"; } + ListElement{ radius: "90"; angle: "310"; value: "-85.855"; } + ListElement{ radius: "90"; angle: "315"; value: "-82.9082"; } + ListElement{ radius: "90"; angle: "320"; value: "-79.6922"; } + ListElement{ radius: "90"; angle: "325"; value: "-76.2316"; } + ListElement{ radius: "90"; angle: "330"; value: "-72.5528"; } + ListElement{ radius: "90"; angle: "335"; value: "-68.6837"; } + ListElement{ radius: "90"; angle: "340"; value: "-64.6538"; } + ListElement{ radius: "90"; angle: "345"; value: "-60.4938"; } + ListElement{ radius: "90"; angle: "350"; value: "-56.2352"; } + ListElement{ radius: "90"; angle: "355"; value: "-51.9106"; } + ListElement{ radius: "90"; angle: "360"; value: "-47.5528"; } + ListElement{ radius: "95"; angle: "0"; value: "-49.3844"; } + ListElement{ radius: "95"; angle: "5"; value: "-45.0266"; } + ListElement{ radius: "95"; angle: "10"; value: "-40.702"; } + ListElement{ radius: "95"; angle: "15"; value: "-36.4435"; } + ListElement{ radius: "95"; angle: "20"; value: "-32.2834"; } + ListElement{ radius: "95"; angle: "25"; value: "-28.2535"; } + ListElement{ radius: "95"; angle: "30"; value: "-24.3844"; } + ListElement{ radius: "95"; angle: "35"; value: "-20.7056"; } + ListElement{ radius: "95"; angle: "40"; value: "-17.245"; } + ListElement{ radius: "95"; angle: "45"; value: "-14.0291"; } + ListElement{ radius: "95"; angle: "50"; value: "-11.0822"; } + ListElement{ radius: "95"; angle: "55"; value: "-8.42681"; } + ListElement{ radius: "95"; angle: "60"; value: "-6.08315"; } + ListElement{ radius: "95"; angle: "65"; value: "-4.06903"; } + ListElement{ radius: "95"; angle: "70"; value: "-2.39979"; } + ListElement{ radius: "95"; angle: "75"; value: "-1.08813"; } + ListElement{ radius: "95"; angle: "80"; value: "-0.144029"; } + ListElement{ radius: "95"; angle: "85"; value: "0.425318"; } + ListElement{ radius: "95"; angle: "90"; value: "0.615583"; } + ListElement{ radius: "95"; angle: "95"; value: "0.425318"; } + ListElement{ radius: "95"; angle: "100"; value: "-0.144029"; } + ListElement{ radius: "95"; angle: "105"; value: "-1.08813"; } + ListElement{ radius: "95"; angle: "110"; value: "-2.39979"; } + ListElement{ radius: "95"; angle: "115"; value: "-4.06903"; } + ListElement{ radius: "95"; angle: "120"; value: "-6.08315"; } + ListElement{ radius: "95"; angle: "125"; value: "-8.42681"; } + ListElement{ radius: "95"; angle: "130"; value: "-11.0822"; } + ListElement{ radius: "95"; angle: "135"; value: "-14.0291"; } + ListElement{ radius: "95"; angle: "140"; value: "-17.245"; } + ListElement{ radius: "95"; angle: "145"; value: "-20.7056"; } + ListElement{ radius: "95"; angle: "150"; value: "-24.3844"; } + ListElement{ radius: "95"; angle: "155"; value: "-28.2535"; } + ListElement{ radius: "95"; angle: "160"; value: "-32.2834"; } + ListElement{ radius: "95"; angle: "165"; value: "-36.4435"; } + ListElement{ radius: "95"; angle: "170"; value: "-40.702"; } + ListElement{ radius: "95"; angle: "175"; value: "-45.0266"; } + ListElement{ radius: "95"; angle: "180"; value: "-49.3844"; } + ListElement{ radius: "95"; angle: "185"; value: "-53.7422"; } + ListElement{ radius: "95"; angle: "190"; value: "-58.0668"; } + ListElement{ radius: "95"; angle: "195"; value: "-62.3254"; } + ListElement{ radius: "95"; angle: "200"; value: "-66.4854"; } + ListElement{ radius: "95"; angle: "205"; value: "-70.5153"; } + ListElement{ radius: "95"; angle: "210"; value: "-74.3844"; } + ListElement{ radius: "95"; angle: "215"; value: "-78.0632"; } + ListElement{ radius: "95"; angle: "220"; value: "-81.5238"; } + ListElement{ radius: "95"; angle: "225"; value: "-84.7398"; } + ListElement{ radius: "95"; angle: "230"; value: "-87.6866"; } + ListElement{ radius: "95"; angle: "235"; value: "-90.342"; } + ListElement{ radius: "95"; angle: "240"; value: "-92.6857"; } + ListElement{ radius: "95"; angle: "245"; value: "-94.6998"; } + ListElement{ radius: "95"; angle: "250"; value: "-96.369"; } + ListElement{ radius: "95"; angle: "255"; value: "-97.6807"; } + ListElement{ radius: "95"; angle: "260"; value: "-98.6248"; } + ListElement{ radius: "95"; angle: "265"; value: "-99.1942"; } + ListElement{ radius: "95"; angle: "270"; value: "-99.3844"; } + ListElement{ radius: "95"; angle: "275"; value: "-99.1942"; } + ListElement{ radius: "95"; angle: "280"; value: "-98.6248"; } + ListElement{ radius: "95"; angle: "285"; value: "-97.6807"; } + ListElement{ radius: "95"; angle: "290"; value: "-96.369"; } + ListElement{ radius: "95"; angle: "295"; value: "-94.6998"; } + ListElement{ radius: "95"; angle: "300"; value: "-92.6857"; } + ListElement{ radius: "95"; angle: "305"; value: "-90.342"; } + ListElement{ radius: "95"; angle: "310"; value: "-87.6866"; } + ListElement{ radius: "95"; angle: "315"; value: "-84.7398"; } + ListElement{ radius: "95"; angle: "320"; value: "-81.5238"; } + ListElement{ radius: "95"; angle: "325"; value: "-78.0632"; } + ListElement{ radius: "95"; angle: "330"; value: "-74.3844"; } + ListElement{ radius: "95"; angle: "335"; value: "-70.5153"; } + ListElement{ radius: "95"; angle: "340"; value: "-66.4854"; } + ListElement{ radius: "95"; angle: "345"; value: "-62.3254"; } + ListElement{ radius: "95"; angle: "350"; value: "-58.0668"; } + ListElement{ radius: "95"; angle: "355"; value: "-53.7422"; } + ListElement{ radius: "95"; angle: "360"; value: "-49.3844"; } + ListElement{ radius: "100"; angle: "0"; value: "-50"; } + ListElement{ radius: "100"; angle: "5"; value: "-45.6422"; } + ListElement{ radius: "100"; angle: "10"; value: "-41.3176"; } + ListElement{ radius: "100"; angle: "15"; value: "-37.059"; } + ListElement{ radius: "100"; angle: "20"; value: "-32.899"; } + ListElement{ radius: "100"; angle: "25"; value: "-28.8691"; } + ListElement{ radius: "100"; angle: "30"; value: "-25"; } + ListElement{ radius: "100"; angle: "35"; value: "-21.3212"; } + ListElement{ radius: "100"; angle: "40"; value: "-17.8606"; } + ListElement{ radius: "100"; angle: "45"; value: "-14.6447"; } + ListElement{ radius: "100"; angle: "50"; value: "-11.6978"; } + ListElement{ radius: "100"; angle: "55"; value: "-9.0424"; } + ListElement{ radius: "100"; angle: "60"; value: "-6.69873"; } + ListElement{ radius: "100"; angle: "65"; value: "-4.68461"; } + ListElement{ radius: "100"; angle: "70"; value: "-3.01537"; } + ListElement{ radius: "100"; angle: "75"; value: "-1.70371"; } + ListElement{ radius: "100"; angle: "80"; value: "-0.759612"; } + ListElement{ radius: "100"; angle: "85"; value: "-0.190265"; } + ListElement{ radius: "100"; angle: "90"; value: "0"; } + ListElement{ radius: "100"; angle: "95"; value: "-0.190265"; } + ListElement{ radius: "100"; angle: "100"; value: "-0.759612"; } + ListElement{ radius: "100"; angle: "105"; value: "-1.70371"; } + ListElement{ radius: "100"; angle: "110"; value: "-3.01537"; } + ListElement{ radius: "100"; angle: "115"; value: "-4.68461"; } + ListElement{ radius: "100"; angle: "120"; value: "-6.69873"; } + ListElement{ radius: "100"; angle: "125"; value: "-9.0424"; } + ListElement{ radius: "100"; angle: "130"; value: "-11.6978"; } + ListElement{ radius: "100"; angle: "135"; value: "-14.6447"; } + ListElement{ radius: "100"; angle: "140"; value: "-17.8606"; } + ListElement{ radius: "100"; angle: "145"; value: "-21.3212"; } + ListElement{ radius: "100"; angle: "150"; value: "-25"; } + ListElement{ radius: "100"; angle: "155"; value: "-28.8691"; } + ListElement{ radius: "100"; angle: "160"; value: "-32.899"; } + ListElement{ radius: "100"; angle: "165"; value: "-37.059"; } + ListElement{ radius: "100"; angle: "170"; value: "-41.3176"; } + ListElement{ radius: "100"; angle: "175"; value: "-45.6422"; } + ListElement{ radius: "100"; angle: "180"; value: "-50"; } + ListElement{ radius: "100"; angle: "185"; value: "-54.3578"; } + ListElement{ radius: "100"; angle: "190"; value: "-58.6824"; } + ListElement{ radius: "100"; angle: "195"; value: "-62.941"; } + ListElement{ radius: "100"; angle: "200"; value: "-67.101"; } + ListElement{ radius: "100"; angle: "205"; value: "-71.1309"; } + ListElement{ radius: "100"; angle: "210"; value: "-75"; } + ListElement{ radius: "100"; angle: "215"; value: "-78.6788"; } + ListElement{ radius: "100"; angle: "220"; value: "-82.1394"; } + ListElement{ radius: "100"; angle: "225"; value: "-85.3553"; } + ListElement{ radius: "100"; angle: "230"; value: "-88.3022"; } + ListElement{ radius: "100"; angle: "235"; value: "-90.9576"; } + ListElement{ radius: "100"; angle: "240"; value: "-93.3013"; } + ListElement{ radius: "100"; angle: "245"; value: "-95.3154"; } + ListElement{ radius: "100"; angle: "250"; value: "-96.9846"; } + ListElement{ radius: "100"; angle: "255"; value: "-98.2963"; } + ListElement{ radius: "100"; angle: "260"; value: "-99.2404"; } + ListElement{ radius: "100"; angle: "265"; value: "-99.8097"; } + ListElement{ radius: "100"; angle: "270"; value: "-100"; } + ListElement{ radius: "100"; angle: "275"; value: "-99.8097"; } + ListElement{ radius: "100"; angle: "280"; value: "-99.2404"; } + ListElement{ radius: "100"; angle: "285"; value: "-98.2963"; } + ListElement{ radius: "100"; angle: "290"; value: "-96.9846"; } + ListElement{ radius: "100"; angle: "295"; value: "-95.3154"; } + ListElement{ radius: "100"; angle: "300"; value: "-93.3013"; } + ListElement{ radius: "100"; angle: "305"; value: "-90.9576"; } + ListElement{ radius: "100"; angle: "310"; value: "-88.3022"; } + ListElement{ radius: "100"; angle: "315"; value: "-85.3553"; } + ListElement{ radius: "100"; angle: "320"; value: "-82.1394"; } + ListElement{ radius: "100"; angle: "325"; value: "-78.6788"; } + ListElement{ radius: "100"; angle: "330"; value: "-75"; } + ListElement{ radius: "100"; angle: "335"; value: "-71.1309"; } + ListElement{ radius: "100"; angle: "340"; value: "-67.101"; } + ListElement{ radius: "100"; angle: "345"; value: "-62.941"; } + ListElement{ radius: "100"; angle: "350"; value: "-58.6824"; } + ListElement{ radius: "100"; angle: "355"; value: "-54.3578"; } + ListElement{ radius: "100"; angle: "360"; value: "-50"; } + } +} diff --git a/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/NewButton.qml b/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/NewButton.qml new file mode 100644 index 00000000..e4fb99d2 --- /dev/null +++ b/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/NewButton.qml @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise 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.digia.com +** +****************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Controls 1.0 +import QtQuick.Controls.Styles 1.0 + +Item { + id: newbutton + + property alias text: buttonText.text + + signal clicked + + implicitWidth: buttonText.implicitWidth + 5 + implicitHeight: buttonText.implicitHeight + 10 + + Button { + id: buttonText + width: parent.width + height: parent.height + + style: ButtonStyle { + label: Component { + Text { + text: buttonText.text + clip: true + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + anchors.fill: parent + } + } + } + onClicked: newbutton.clicked() + } +} diff --git a/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/main.qml b/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/main.qml new file mode 100644 index 00000000..0b02c058 --- /dev/null +++ b/examples/datavisualization/qmlspectrogram/qml/qmlspectrogram/main.qml @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com +** +** This file is part of the QtDataVisualization module. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise 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.digia.com +** +****************************************************************************/ + +import QtQuick 2.1 +import QtQuick.Layouts 1.0 +import QtQuick.Window 2.1 +import QtDataVisualization 1.2 +import "." + +Window { + id: mainview + title: "Qt Quick 2 Spectrogram Example" + visible: true + width: 1024 + height: 768 + color: surfaceGraph.theme.windowColor + + Data { + id: surfaceData + } + + Item { + id: surfaceView + width: mainview.width + height: mainview.height + anchors.top: mainview.top + anchors.left: mainview.left + + //! [0] + ColorGradient { + id: surfaceGradient + ColorGradientStop { position: 0.0; color: "black" } + ColorGradientStop { position: 0.2; color: "red" } + ColorGradientStop { position: 0.5; color: "blue" } + ColorGradientStop { position: 0.8; color: "yellow" } + ColorGradientStop { position: 1.0; color: "white" } + } + //! [0] + + Surface3D { + id: surfaceGraph + width: surfaceView.width + height: surfaceView.height + + shadowQuality: AbstractGraph3D.ShadowQualityNone + selectionMode: AbstractGraph3D.SelectionSlice | AbstractGraph3D.SelectionItemAndRow + scene.activeCamera.cameraPreset: Camera3D.CameraPresetDirectlyAbove + axisX.segmentCount: 8 + axisX.subSegmentCount: 2 + axisX.labelFormat: "%i" + axisZ.segmentCount: 5 + axisZ.subSegmentCount: 2 + axisZ.labelFormat: "%i" + axisY.segmentCount: 8 + axisY.subSegmentCount: 1 + axisY.labelFormat: "%i \%" + axisY.title: "Value" + axisX.title: "Angle" + axisZ.title: "Radius" + + // Don't show specular spotlight as we don't want it to distort the colors + theme.lightStrength: 0.0 + theme.ambientLightStrength: 0.9 + theme.backgroundEnabled: false + + orthoProjection: true + + Surface3DSeries { + id: surfaceSeries + flatShadingEnabled: false + drawMode: Surface3DSeries.DrawSurface + baseGradient: surfaceGradient + colorStyle: Theme3D.ColorStyleRangeGradient + + ItemModelSurfaceDataProxy { + itemModel: surfaceData.model + rowRole: "radius" + columnRole: "angle" + yPosRole: "value" + } + } + } + } + + RowLayout { + id: buttonLayout + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + opacity: 0.5 + + NewButton { + id: polarToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Switch to Polar" + //! [1] + onClicked: { + if (surfaceGraph.polar === false) { + surfaceGraph.polar = true + text = "Switch to Cartesian" + } else { + surfaceGraph.polar = false + text = "Switch to Polar" + } + } + //! [1] + } + + NewButton { + id: orthoToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Switch to perspective" + onClicked: { + if (surfaceGraph.orthoProjection === true) { + surfaceGraph.orthoProjection = false; + text = "Switch to orthogonal" + } else { + surfaceGraph.orthoProjection = true; + surfaceGraph.scene.activeCamera.cameraPreset = Camera3D.CameraPresetDirectlyAbove + text = "Switch to perspective" + } + } + } + + NewButton { + id: surfaceGridToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Toggle surface grid" + onClicked: { + if (surfaceSeries.drawMode & Surface3DSeries.DrawWireframe) { + surfaceSeries.drawMode &= ~Surface3DSeries.DrawWireframe; + } else { + surfaceSeries.drawMode |= Surface3DSeries.DrawWireframe; + } + } + } + + NewButton { + id: gridToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Toggle axis grid" + onClicked: { + if (surfaceGraph.theme.gridEnabled === true) { + surfaceGraph.theme.gridEnabled = false; + } else { + surfaceGraph.theme.gridEnabled = true; + } + } + } + + NewButton { + id: gridOffsetToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Toggle grid position" + onClicked: { + // TODO + if (surfaceGraph.theme.backgroundEnabled === true) { + } else { + surfaceGraph.theme.backgroundEnabled = true; + } + } + } + + NewButton { + id: labelOffsetToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Toggle radial label position" + //visible: surfaceGraph.polar + onClicked: { + // TODO + if (surfaceGraph.theme.backgroundEnabled === true) { + } else { + surfaceGraph.theme.backgroundEnabled = true; + } + } + } + } + + Rectangle { + id: legend + anchors.margins: 20 + anchors.bottom: parent.bottom + anchors.top: buttonLayout.bottom + anchors.left: parent.left + border.color: "black" + border.width: 1 + width: 50 + rotation: 180 + gradient: Gradient { + GradientStop { position: 0.0; color: "black" } + GradientStop { position: 0.2; color: "red" } + GradientStop { position: 0.5; color: "blue" } + GradientStop { position: 0.8; color: "yellow" } + GradientStop { position: 1.0; color: "white" } + } + } + + Text { + anchors.verticalCenter: legend.bottom + anchors.left: legend.right + anchors.margins: 2 + text: surfaceGraph.axisY.min + "%" + } + + Text { + anchors.verticalCenter: legend.verticalCenter + anchors.left: legend.right + anchors.margins: 2 + text: (surfaceGraph.axisY.max + surfaceGraph.axisY.min) / 2 + "%" + } + + Text { + anchors.verticalCenter: legend.top + anchors.left: legend.right + anchors.margins: 2 + text: surfaceGraph.axisY.max + "%" + } +} diff --git a/examples/datavisualization/qmlspectrogram/qmlspectrogram.pro b/examples/datavisualization/qmlspectrogram/qmlspectrogram.pro new file mode 100644 index 00000000..655fb0b8 --- /dev/null +++ b/examples/datavisualization/qmlspectrogram/qmlspectrogram.pro @@ -0,0 +1,12 @@ +!include( ../examples.pri ) { + error( "Couldn't find the examples.pri file!" ) +} + +# The .cpp file which was generated for your project. Feel free to hack it. +SOURCES += main.cpp + +RESOURCES += qmlspectrogram.qrc + +OTHER_FILES += doc/src/* \ + doc/images/* \ + qml/qmlspectrogram/* diff --git a/examples/datavisualization/qmlspectrogram/qmlspectrogram.qrc b/examples/datavisualization/qmlspectrogram/qmlspectrogram.qrc new file mode 100644 index 00000000..9f024404 --- /dev/null +++ b/examples/datavisualization/qmlspectrogram/qmlspectrogram.qrc @@ -0,0 +1,7 @@ +<RCC> + <qresource prefix="/qml"> + <file>qml/qmlspectrogram/Data.qml</file> + <file>qml/qmlspectrogram/main.qml</file> + <file>qml/qmlspectrogram/NewButton.qml</file> + </qresource> +</RCC> diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc index 2cc3eece..5afbc8c7 100644 --- a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc +++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc @@ -153,6 +153,19 @@ */ /*! + * \qmlproperty bool AbstractGraph3D::polar + * \since QtDataVisualization 1.2 + * + * If \c {true}, the horizontal axes are changed into polar axes. The X axis becomes the + * angular axis and the Z axis becomes the radial axis. + * Polar mode is not available for bar graphs. + * + * Defaults to \c{false}. + * + * \sa orthoProjection, AbstractAxis3D::gridOffset, radialLabelOffset + */ + +/*! * \qmlmethod void AbstractGraph3D::clearSelection() * Clears selection from all attached series. */ diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp index 30434dca..e4fd0003 100644 --- a/src/datavisualization/engine/abstract3dcontroller.cpp +++ b/src/datavisualization/engine/abstract3dcontroller.cpp @@ -50,6 +50,7 @@ Abstract3DController::Abstract3DController(QRect initialViewport, Q3DScene *scen m_isCustomItemDirty(true), m_isSeriesVisualsDirty(true), m_renderPending(false), + m_isPolar(false), m_measureFps(false), m_numFrames(0), m_currentFps(0.0) @@ -176,6 +177,11 @@ void Abstract3DController::synchDataToRenderer() m_renderer->updateTheme(m_themeManager->activeTheme()); + if (m_changeTracker.polarChanged) { + m_renderer->updatePolar(m_isPolar); + m_changeTracker.polarChanged = false; + } + if (m_changeTracker.shadowQualityChanged) { m_renderer->updateShadowQuality(m_shadowQuality); m_changeTracker.shadowQualityChanged = false; @@ -1521,4 +1527,20 @@ float Abstract3DController::aspectRatio() return m_aspectRatio; } +void Abstract3DController::setPolar(bool enable) +{ + if (enable != m_isPolar) { + m_isPolar = enable; + m_changeTracker.polarChanged = true; + m_isDataDirty = true; + emit polarChanged(m_isPolar); + emitNeedRender(); + } +} + +bool Abstract3DController::isPolar() const +{ + return m_isPolar; +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h index 0e4d1add..7d721b0c 100644 --- a/src/datavisualization/engine/abstract3dcontroller_p.h +++ b/src/datavisualization/engine/abstract3dcontroller_p.h @@ -90,6 +90,7 @@ struct Abstract3DChangeBitField { bool axisXTitleFixedChanged : 1; bool axisYTitleFixedChanged : 1; bool axisZTitleFixedChanged : 1; + bool polarChanged : 1; Abstract3DChangeBitField() : themeChanged(true), @@ -133,7 +134,8 @@ struct Abstract3DChangeBitField { axisZTitleVisibilityChanged(true), axisXTitleFixedChanged(true), axisYTitleFixedChanged(true), - axisZTitleFixedChanged(true) + axisZTitleFixedChanged(true), + polarChanged(true) { } }; @@ -175,6 +177,7 @@ protected: bool m_isCustomItemDirty; bool m_isSeriesVisualsDirty; bool m_renderPending; + bool m_isPolar; QList<QAbstract3DSeries *> m_seriesList; @@ -261,6 +264,17 @@ public: void setOrthoProjection(bool enable); bool isOrthoProjection() const; + void setMeasureFps(bool enable); + inline bool measureFps() const { return m_measureFps; } + inline qreal currentFps() const { return m_currentFps; } + + QAbstract3DGraph::ElementType selectedElement() const; + + void setAspectRatio(float ratio); + float aspectRatio(); + void setPolar(bool enable); + bool isPolar() const; + void emitNeedRender(); virtual void clearSelection() = 0; @@ -320,17 +334,8 @@ public slots: // Renderer callback handlers void handleRequestShadowQuality(QAbstract3DGraph::ShadowQuality quality); - void setMeasureFps(bool enable); - inline bool measureFps() const { return m_measureFps; } - inline qreal currentFps() const { return m_currentFps; } - - QAbstract3DGraph::ElementType selectedElement() const; - void updateCustomItem(); - void setAspectRatio(float ratio); - float aspectRatio(); - signals: void shadowQualityChanged(QAbstract3DGraph::ShadowQuality quality); void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler); @@ -346,6 +351,7 @@ signals: void orthoProjectionChanged(bool enabled); void aspectRatioChanged(float ratio); void optimizationHintsChanged(QAbstract3DGraph::OptimizationHints hints); + void polarChanged(bool enabled); protected: virtual QAbstract3DAxis *createDefaultAxis(QAbstract3DAxis::AxisOrientation orientation); diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp index 132a0514..56a5ba60 100644 --- a/src/datavisualization/engine/abstract3drenderer.cpp +++ b/src/datavisualization/engine/abstract3drenderer.cpp @@ -25,8 +25,16 @@ #include "qcustom3ditem_p.h" #include "qcustom3dlabel_p.h" +#include <QtCore/qmath.h> + QT_BEGIN_NAMESPACE_DATAVISUALIZATION +const qreal doublePi(M_PI * 2.0); +const int polarGridRoundness(64); +const qreal polarGridAngle(doublePi / qreal(polarGridRoundness)); +const float polarGridAngleDegrees(float(360.0 / qreal(polarGridRoundness))); +const qreal polarGridHalfAngle(polarGridAngle / 2.0); + Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) : QObject(0), m_hasNegativeValues(false), @@ -37,6 +45,7 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_cachedSelectionMode(QAbstract3DGraph::SelectionNone), m_cachedOptimizationHint(QAbstract3DGraph::OptimizationDefault), m_textureHelper(0), + m_depthTexture(0), m_cachedScene(new Q3DScene()), m_selectionDirty(true), m_selectionState(SelectNone), @@ -55,7 +64,15 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller) m_backgroundObj(0), m_gridLineObj(0), m_labelObj(0), - m_graphAspectRatio(2.0f) + m_graphAspectRatio(2.0f), + m_polarGraph(false), + m_xRightAngleRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f)), + m_yRightAngleRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f)), + m_zRightAngleRotation(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f)), + m_xRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f)), + m_yRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f)), + m_zRightAngleRotationNeg(QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, -90.0f)), + m_xFlipRotation(QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -180.0f)) { QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures); QObject::connect(this, &Abstract3DRenderer::needRender, controller, @@ -89,7 +106,10 @@ Abstract3DRenderer::~Abstract3DRenderer() ObjectHelper::releaseObjectHelper(this, m_gridLineObj); ObjectHelper::releaseObjectHelper(this, m_labelObj); - delete m_textureHelper; + if (m_textureHelper) { + m_textureHelper->deleteTexture(&m_depthTexture); + delete m_textureHelper; + } } void Abstract3DRenderer::initializeOpenGL() @@ -287,6 +307,14 @@ void Abstract3DRenderer::updateAspectRatio(float ratio) updateCustomItemPositions(); } +void Abstract3DRenderer::updatePolar(bool enable) +{ + m_polarGraph = enable; + foreach (SeriesRenderCache *cache, m_renderCacheList) + cache->setDataDirty(true); + updateCustomItemPositions(); +} + void Abstract3DRenderer::updateOptimizationHint(QAbstract3DGraph::OptimizationHints hint) { m_cachedOptimizationHint = hint; @@ -607,10 +635,9 @@ void Abstract3DRenderer::drawAxisTitleY(const QVector3D &sideLabelRotation, QQuaternion titleRotation; if (m_axisCacheY.isTitleFixed()) { titleRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, yRotation) - * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f); + * m_zRightAngleRotation; } else { - titleRotation = totalRotation - * QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, 90.0f); + titleRotation = totalRotation * m_zRightAngleRotation; } dummyItem.setTranslation(titleTrans + titleOffsetVector); @@ -793,7 +820,6 @@ void Abstract3DRenderer::loadLabelMesh() QStringLiteral(":/defaultMeshes/plane")); } - void Abstract3DRenderer::generateBaseColorTexture(const QColor &color, GLuint *texture) { m_textureHelper->deleteTexture(texture); @@ -1131,4 +1157,118 @@ void Abstract3DRenderer::drawCustomItems(RenderingState state, } } +void Abstract3DRenderer::calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const +{ + // x is angular, z is radial + qreal angle = m_axisCacheX.formatter()->positionAt(dataPos.x()) * doublePi; + qreal radius = m_axisCacheZ.formatter()->positionAt(dataPos.z()); + + // Convert angle & radius to X and Z coords + x = float(radius * qSin(angle)) * m_graphAspectRatio; + z = -float(radius * qCos(angle)) * m_graphAspectRatio; +} + +void Abstract3DRenderer::drawRadialGrid(ShaderHelper *shader, float yFloorLinePos, + const QMatrix4x4 &projectionViewMatrix, + const QMatrix4x4 &depthMatrix) +{ + static QVector<QQuaternion> lineRotations; + if (!lineRotations.size()) { + lineRotations.resize(polarGridRoundness); + for (int j = 0; j < polarGridRoundness; j++) { + lineRotations[j] = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, + polarGridAngleDegrees * float(j)); + } + } + int gridLineCount = m_axisCacheZ.gridLineCount(); + const QVector<float> &gridPositions = m_axisCacheZ.formatter()->gridPositions(); + const QVector<float> &subGridPositions = m_axisCacheZ.formatter()->subGridPositions(); + int mainSize = gridPositions.size(); + QVector3D translateVector(0.0f, yFloorLinePos, 0.0f); + for (int i = 0; i < gridLineCount; i++) { + float gridPosition = (i >= mainSize) + ? subGridPositions.at(i - mainSize) : gridPositions.at(i); + float radiusFraction = m_graphAspectRatio * gridPosition; + QVector3D gridLineScaler(radiusFraction * float(qSin(polarGridHalfAngle)), + gridLineWidth, gridLineWidth); + translateVector.setZ(gridPosition * m_graphAspectRatio); + for (int j = 0; j < polarGridRoundness; j++) { + QMatrix4x4 modelMatrix; + QMatrix4x4 itModelMatrix; + modelMatrix.rotate(lineRotations.at(j)); + itModelMatrix.rotate(lineRotations.at(j)); + modelMatrix.translate(translateVector); + modelMatrix.scale(gridLineScaler); + itModelMatrix.scale(gridLineScaler); + modelMatrix.rotate(m_xRightAngleRotationNeg); + itModelMatrix.rotate(m_xRightAngleRotationNeg); + QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix; + + shader->setUniformValue(shader->model(), modelMatrix); + shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed()); + shader->setUniformValue(shader->MVP(), MVPMatrix); +#if !defined(QT_OPENGL_ES_2) + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { + // Set shadow shader bindings + QMatrix4x4 depthMVPMatrix = depthMatrix * modelMatrix; + shader->setUniformValue(shader->depth(), depthMVPMatrix); + // Draw the object + m_drawer->drawObject(shader, m_gridLineObj, 0, m_depthTexture); + } else { + // Draw the object + m_drawer->drawObject(shader, m_gridLineObj); + } +#else + m_drawer->drawLine(shader); +#endif + } + } +} + +void Abstract3DRenderer::drawAngularGrid(ShaderHelper *shader, float yFloorLinePos, + const QMatrix4x4 &projectionViewMatrix, + const QMatrix4x4 &depthMatrix) +{ + float halfRatio(m_graphAspectRatio / 2.0f); + QVector3D gridLineScaler(gridLineWidth, gridLineWidth, halfRatio); + int gridLineCount = m_axisCacheX.gridLineCount(); + const QVector<float> &gridPositions = m_axisCacheX.formatter()->gridPositions(); + const QVector<float> &subGridPositions = m_axisCacheX.formatter()->subGridPositions(); + int mainSize = gridPositions.size(); + QVector3D translateVector(0.0f, yFloorLinePos, -halfRatio); + for (int i = 0; i < gridLineCount; i++) { + QMatrix4x4 modelMatrix; + QMatrix4x4 itModelMatrix; + float gridPosition = (i >= mainSize) + ? subGridPositions.at(i - mainSize) : gridPositions.at(i); + QQuaternion lineRotation = QQuaternion::fromAxisAndAngle(upVector, gridPosition * 360.0f); + modelMatrix.rotate(lineRotation); + itModelMatrix.rotate(lineRotation); + modelMatrix.translate(translateVector); + modelMatrix.scale(gridLineScaler); + itModelMatrix.scale(gridLineScaler); + modelMatrix.rotate(m_xRightAngleRotationNeg); + itModelMatrix.rotate(m_xRightAngleRotationNeg); + QMatrix4x4 MVPMatrix = projectionViewMatrix * modelMatrix; + + shader->setUniformValue(shader->model(), modelMatrix); + shader->setUniformValue(shader->nModel(), itModelMatrix.inverted().transposed()); + shader->setUniformValue(shader->MVP(), MVPMatrix); +#if !defined(QT_OPENGL_ES_2) + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { + // Set shadow shader bindings + QMatrix4x4 depthMVPMatrix = depthMatrix * modelMatrix; + shader->setUniformValue(shader->depth(), depthMVPMatrix); + // Draw the object + m_drawer->drawObject(shader, m_gridLineObj, 0, m_depthTexture); + } else { + // Draw the object + m_drawer->drawObject(shader, m_gridLineObj); + } +#else + m_drawer->drawLine(shader); +#endif + } +} + QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h index 325ac8e6..33337441 100644 --- a/src/datavisualization/engine/abstract3drenderer_p.h +++ b/src/datavisualization/engine/abstract3drenderer_p.h @@ -125,6 +125,7 @@ public: virtual void updateCustomItem(CustomRenderItem *renderItem); virtual void updateAspectRatio(float ratio); + virtual void updatePolar(bool enable); virtual QVector3D convertPositionToTranslation(const QVector3D &position, bool isAbsolute) = 0; @@ -155,6 +156,7 @@ public: GLuint depthTexture, GLfloat shadowQuality); #endif QVector4D indexToSelectionColor(GLint index); + void calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const; signals: void needRender(); // Emit this if something in renderer causes need for another render pass. @@ -197,6 +199,11 @@ protected: void loadGridLineMesh(); void loadLabelMesh(); + void drawRadialGrid(ShaderHelper *shader, float yFloorLinePos, + const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &depthMatrix); + void drawAngularGrid(ShaderHelper *shader, float yFloorLinePos, + const QMatrix4x4 &projectionViewMatrix, const QMatrix4x4 &depthMatrix); + bool m_hasNegativeValues; Q3DTheme *m_cachedTheme; Drawer *m_drawer; @@ -211,6 +218,7 @@ protected: AxisRenderCache m_axisCacheY; AxisRenderCache m_axisCacheZ; TextureHelper *m_textureHelper; + GLuint m_depthTexture; Q3DScene *m_cachedScene; bool m_selectionDirty; @@ -244,6 +252,15 @@ protected: ObjectHelper *m_labelObj; // Shared reference float m_graphAspectRatio; + bool m_polarGraph; + + QQuaternion m_xRightAngleRotation; + QQuaternion m_yRightAngleRotation; + QQuaternion m_zRightAngleRotation; + QQuaternion m_xRightAngleRotationNeg; + QQuaternion m_yRightAngleRotationNeg; + QQuaternion m_zRightAngleRotationNeg; + QQuaternion m_xFlipRotation; private: friend class Abstract3DController; diff --git a/src/datavisualization/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp index f909c7d6..70310c23 100644 --- a/src/datavisualization/engine/bars3drenderer.cpp +++ b/src/datavisualization/engine/bars3drenderer.cpp @@ -31,7 +31,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION -const GLfloat gridLineWidth = 0.005f; const bool sliceGridLabels = true; Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) @@ -50,7 +49,6 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller) m_backgroundShader(0), m_labelShader(0), m_bgrTexture(0), - m_depthTexture(0), m_selectionTexture(0), m_depthFrameBuffer(0), m_selectionFrameBuffer(0), @@ -421,7 +419,6 @@ void Bars3DRenderer::drawSlicedScene() GLfloat barPosX = 0; QVector3D lightPos; QVector4D lightColor = Utils::vectorFromColor(m_cachedTheme->lightColor()); - static QQuaternion ninetyDegreeRotation = QQuaternion::fromAxisAndAngle(upVector, 90.0f); // Specify viewport glViewport(m_secondarySubViewport.x(), @@ -698,7 +695,7 @@ void Bars3DRenderer::drawSlicedScene() barPosX = item.translation().x(); } else { barPosX = -(item.translation().z()); // flip z; frontmost bar to the left - barRotation *= ninetyDegreeRotation; + barRotation *= m_yRightAngleRotation; } modelMatrix.translate(barPosX, barPosY, 0.0f); @@ -1701,9 +1698,9 @@ void Bars3DRenderer::drawBackground(GLfloat rowScaleFactor, GLfloat columnScaleF modelMatrix.scale(backgroundScaler); if (m_yFlipped) - modelMatrix.rotate(90.0f, 1.0f, 0.0f, 0.0f); + modelMatrix.rotate(m_xRightAngleRotation); else - modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f); + modelMatrix.rotate(m_xRightAngleRotationNeg); itModelMatrix = modelMatrix; @@ -1835,9 +1832,9 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa QVector3D gridLineScaler(rowScaleFactor, gridLineWidth, gridLineWidth); if (m_yFlipped) - lineRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f); + lineRotation = m_xRightAngleRotation; else - lineRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f); + lineRotation = m_xRightAngleRotationNeg; // Floor lines: rows for (GLfloat row = 0.0f; row <= m_cachedRowCount; row++) { @@ -1879,7 +1876,7 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa // Floor lines: columns #if defined(QT_OPENGL_ES_2) - lineRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); + lineRotation = m_yRightAngleRotation; #endif gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, columnScaleFactor); for (GLfloat bar = 0.0f; bar <= m_cachedColumnCount; bar++) { @@ -1939,8 +1936,8 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa modelMatrix.scale(gridLineScaler); itModelMatrix.scale(gridLineScaler); if (m_zFlipped) { - modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); - itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); + modelMatrix.rotate(m_xFlipRotation); + itModelMatrix.rotate(m_xFlipRotation); } MVPMatrix = projectionViewMatrix * modelMatrix; @@ -1973,9 +1970,9 @@ void Bars3DRenderer::drawGridLines(GLfloat rowScaleFactor, GLfloat columnScaleFa xWallLinePosition = -xWallLinePosition; if (m_xFlipped) - lineRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f); + lineRotation = m_yRightAngleRotationNeg; else - lineRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); + lineRotation = m_yRightAngleRotation; gridLineScaler = QVector3D(gridLineWidth, gridLineWidth, columnScaleFactor); for (int line = 0; line < gridLineCount; line++) { diff --git a/src/datavisualization/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h index 29835741..466f7bed 100644 --- a/src/datavisualization/engine/bars3drenderer_p.h +++ b/src/datavisualization/engine/bars3drenderer_p.h @@ -68,7 +68,6 @@ private: ShaderHelper *m_backgroundShader; ShaderHelper *m_labelShader; GLuint m_bgrTexture; - GLuint m_depthTexture; GLuint m_selectionTexture; GLuint m_depthFrameBuffer; GLuint m_selectionFrameBuffer; diff --git a/src/datavisualization/engine/qabstract3dgraph.cpp b/src/datavisualization/engine/qabstract3dgraph.cpp index b8fa92e8..6240f714 100644 --- a/src/datavisualization/engine/qabstract3dgraph.cpp +++ b/src/datavisualization/engine/qabstract3dgraph.cpp @@ -591,8 +591,15 @@ qreal QAbstract3DGraph::currentFps() const * \property QAbstract3DGraph::orthoProjection * \since QtDataVisualization 1.1 * - * If \c {true}, orthographic projection will be used for displaying the graph. Defaults to \c{false}. + * If \c {true}, orthographic projection will be used for displaying the graph. + * \note Orthographic projection can be used to create 2D graphs by replacing the default input + * handler with one that doesn't allow rotating the graph and setting the camera to view the graph + * directly from the side or from the top. Also, axis labels typically need to be rotated when + * viewing the graph from the sides. + * Defaults to \c{false}. * \note Shadows will be disabled when set to \c{true}. + * + * \sa QAbstract3DAxis::labelAutoRotation, Q3DCamera::cameraPreset */ void QAbstract3DGraph::setOrthoProjection(bool enable) { @@ -646,6 +653,28 @@ QAbstract3DGraph::OptimizationHints QAbstract3DGraph::optimizationHints() const } /*! + * \property QAbstract3DGraph::polar + * \since QtDataVisualization 1.2 + * + * If \c {true}, the horizontal axes are changed into polar axes. The X axis becomes the + * angular axis and the Z axis becomes the radial axis. + * Polar mode is not available for bar graphs. + * + * Defaults to \c{false}. + * + * \sa orthoProjection, QAbstract3DAxis::gridOffset, radialLabelOffset + */ +void QAbstract3DGraph::setPolar(bool enable) +{ + d_ptr->m_visualController->setPolar(enable); +} + +bool QAbstract3DGraph::isPolar() const +{ + return d_ptr->m_visualController->isPolar(); +} + +/*! * \internal */ bool QAbstract3DGraph::event(QEvent *event) @@ -795,6 +824,8 @@ void QAbstract3DGraphPrivate::setVisualController(Abstract3DController *controll QObject::connect(m_visualController, &Abstract3DController::aspectRatioChanged, q_ptr, &QAbstract3DGraph::aspectRatioChanged); + QObject::connect(m_visualController, &Abstract3DController::polarChanged, q_ptr, + &QAbstract3DGraph::polarChanged); } void QAbstract3DGraphPrivate::handleDevicePixelRatioChange() diff --git a/src/datavisualization/engine/qabstract3dgraph.h b/src/datavisualization/engine/qabstract3dgraph.h index 59f61aae..ca673358 100644 --- a/src/datavisualization/engine/qabstract3dgraph.h +++ b/src/datavisualization/engine/qabstract3dgraph.h @@ -50,6 +50,7 @@ class QT_DATAVISUALIZATION_EXPORT QAbstract3DGraph : public QWindow, protected Q Q_PROPERTY(ElementType selectedElement READ selectedElement NOTIFY selectedElementChanged) Q_PROPERTY(qreal aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged) Q_PROPERTY(OptimizationHints optimizationHints READ optimizationHints WRITE setOptimizationHints NOTIFY optimizationHintsChanged) + Q_PROPERTY(bool polar READ isPolar WRITE setPolar NOTIFY polarChanged) protected: explicit QAbstract3DGraph(QAbstract3DGraphPrivate *d, const QSurfaceFormat *format, @@ -150,6 +151,9 @@ public: void setOptimizationHints(OptimizationHints hints); OptimizationHints optimizationHints() const; + void setPolar(bool enable); + bool isPolar() const; + protected: bool event(QEvent *event); void resizeEvent(QResizeEvent *event); @@ -173,6 +177,7 @@ signals: void orthoProjectionChanged(bool enabled); void aspectRatioChanged(qreal ratio); void optimizationHintsChanged(QAbstract3DGraph::OptimizationHints hints); + void polarChanged(bool enabled); private: Q_DISABLE_COPY(QAbstract3DGraph) diff --git a/src/datavisualization/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp index 7ac81552..f6b044f6 100644 --- a/src/datavisualization/engine/scatter3drenderer.cpp +++ b/src/datavisualization/engine/scatter3drenderer.cpp @@ -38,7 +38,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION const GLfloat defaultMinSize = 0.01f; const GLfloat defaultMaxSize = 0.1f; const GLfloat itemScaler = 3.0f; -const GLfloat gridLineWidth = 0.005f; Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) : Abstract3DRenderer(controller), @@ -54,7 +53,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller) m_backgroundShader(0), m_labelShader(0), m_bgrTexture(0), - m_depthTexture(0), m_selectionTexture(0), m_depthFrameBuffer(0), m_selectionFrameBuffer(0), @@ -1006,7 +1004,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) modelMatrix.scale(bgScale); // If we're viewing from below, background object must be flipped if (m_yFlipped) { - modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0); + modelMatrix.rotate(m_xFlipRotation); modelMatrix.rotate(270.0f - backgroundRotation, 0.0f, 1.0f, 0.0f); } else { modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f); @@ -1095,14 +1093,14 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) QQuaternion lineXRotation; if (m_xFlipped) - lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f); + lineYRotation = m_yRightAngleRotationNeg; else - lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); + lineYRotation = m_yRightAngleRotation; if (m_yFlipped) - lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f); + lineXRotation = m_xRightAngleRotation; else - lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f); + lineXRotation = m_xRightAngleRotationNeg; GLfloat yFloorLinePosition = -1.0f - m_backgroundMargin + gridLineOffset; if (m_yFlipped) @@ -1189,8 +1187,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) modelMatrix.rotate(lineYRotation); itModelMatrix.rotate(lineYRotation); #else - modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); - itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); + modelMatrix.rotate(m_zRightAngleRotation); + itModelMatrix.rotate(m_zRightAngleRotation); #endif MVPMatrix = projectionViewMatrix * modelMatrix; @@ -1221,7 +1219,7 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) // Columns (= X) if (m_axisCacheX.segmentCount() > 0) { #if defined(QT_OPENGL_ES_2) - lineXRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); + lineXRotation = m_yRightAngleRotation; #endif // Floor lines int gridLineCount = m_axisCacheX.gridLineCount(); @@ -1301,12 +1299,12 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) #if !defined(QT_OPENGL_ES_2) if (m_zFlipped) { - modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); - itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); + modelMatrix.rotate(m_xFlipRotation); + itModelMatrix.rotate(m_xFlipRotation); } #else - modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); - itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); + modelMatrix.rotate(m_zRightAngleRotation); + itModelMatrix.rotate(m_zRightAngleRotation); #endif MVPMatrix = projectionViewMatrix * modelMatrix; @@ -1368,8 +1366,8 @@ void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle) itModelMatrix.scale(gridLineScaler); if (m_zFlipped) { - modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); - itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); + modelMatrix.rotate(m_xFlipRotation); + itModelMatrix.rotate(m_xFlipRotation); } MVPMatrix = projectionViewMatrix * modelMatrix; diff --git a/src/datavisualization/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h index 7f213179..b0b1e411 100644 --- a/src/datavisualization/engine/scatter3drenderer_p.h +++ b/src/datavisualization/engine/scatter3drenderer_p.h @@ -61,7 +61,6 @@ private: ShaderHelper *m_backgroundShader; ShaderHelper *m_labelShader; GLuint m_bgrTexture; - GLuint m_depthTexture; GLuint m_selectionTexture; GLuint m_depthFrameBuffer; GLuint m_selectionFrameBuffer; diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp index 60e57529..60e501f1 100644 --- a/src/datavisualization/engine/surface3drenderer.cpp +++ b/src/datavisualization/engine/surface3drenderer.cpp @@ -33,7 +33,6 @@ QT_BEGIN_NAMESPACE_DATAVISUALIZATION // Margin for background (1.10 make it 10% larger to avoid // selection ball being drawn inside background) const GLfloat backgroundMargin = 1.1f; -const GLfloat gridLineWidth = 0.005f; const GLfloat sliceZScale = 0.1f; const GLfloat sliceUnits = 2.5f; const uint greenMultiplier = 256; @@ -53,12 +52,10 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller) m_selectionShader(0), m_labelShader(0), m_heightNormalizer(0.0f), - m_scaleFactor(0.0f), m_scaleX(0.0f), m_scaleZ(0.0f), m_scaleXWithBackground(0.0f), m_scaleZWithBackground(0.0f), - m_depthTexture(0), m_depthModelTexture(0), m_depthFrameBuffer(0), m_selectionFrameBuffer(0), @@ -301,10 +298,13 @@ void Surface3DRenderer::updateRows(const QVector<Surface3DController::ChangeRow> srcArray->at(row)->at(j + sampleSpace.x()); } - if (cache->isFlatShadingEnabled()) - cache->surfaceObject()->updateCoarseRow(dstArray, row - sampleSpace.y()); - else - cache->surfaceObject()->updateSmoothRow(dstArray, row - sampleSpace.y()); + if (cache->isFlatShadingEnabled()) { + cache->surfaceObject()->updateCoarseRow(dstArray, row - sampleSpace.y(), + m_polarGraph); + } else { + cache->surfaceObject()->updateSmoothRow(dstArray, row - sampleSpace.y(), + m_polarGraph); + } } if (updateBuffers) cache->surfaceObject()->uploadBuffers(); @@ -343,9 +343,9 @@ void Surface3DRenderer::updateItems(const QVector<Surface3DController::ChangeIte (*(dstArray.at(y)))[x] = srcArray->at(point.x())->at(point.y()); if (cache->isFlatShadingEnabled()) - cache->surfaceObject()->updateCoarseItem(dstArray, y, x); + cache->surfaceObject()->updateCoarseItem(dstArray, y, x, m_polarGraph); else - cache->surfaceObject()->updateSmoothItem(dstArray, y, x); + cache->surfaceObject()->updateSmoothItem(dstArray, y, x, m_polarGraph); } if (updateBuffers) cache->surfaceObject()->uploadBuffers(); @@ -538,10 +538,12 @@ void Surface3DRenderer::updateSliceObject(SurfaceSeriesRenderCache *cache, const QRect sliceRect(0, 0, sliceRow->size(), 2); if (sliceRow->size() > 0) { - if (cache->isFlatShadingEnabled()) - cache->sliceSurfaceObject()->setUpData(sliceDataArray, sliceRect, true, flipZX); - else - cache->sliceSurfaceObject()->setUpSmoothData(sliceDataArray, sliceRect, true, flipZX); + if (cache->isFlatShadingEnabled()) { + cache->sliceSurfaceObject()->setUpData(sliceDataArray, sliceRect, true, false, flipZX); + } else { + cache->sliceSurfaceObject()->setUpSmoothData(sliceDataArray, sliceRect, true, false, + flipZX); + } } } @@ -902,8 +904,8 @@ void Surface3DRenderer::drawSlicedScene() modelMatrix.scale(gridLineScaleY); itModelMatrix.scale(gridLineScaleY); #if (defined QT_OPENGL_ES_2) - modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); - itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); + modelMatrix.rotate(m_zRightAngleRotation); + itModelMatrix.rotate(m_zRightAngleRotation); #endif MVPMatrix = projectionViewMatrix * modelMatrix; @@ -1365,7 +1367,7 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) // If we're viewing from below, background object must be flipped if (m_yFlipped) { - modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); + modelMatrix.rotate(m_xFlipRotation); modelMatrix.rotate(270.0f - backgroundRotation, 0.0f, 1.0f, 0.0f); } else { modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f); @@ -1461,205 +1463,213 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) QQuaternion lineXRotation; if (m_xFlipped) - lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -90.0f); + lineYRotation = m_yRightAngleRotationNeg; else - lineYRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); + lineYRotation = m_yRightAngleRotation; if (m_yFlipped) - lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, 90.0f); + lineXRotation = m_xRightAngleRotation; else - lineXRotation = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, -90.0f); + lineXRotation = m_xRightAngleRotationNeg; - GLfloat yFloorLinePosition = -backgroundMargin + gridLineOffset; + float yFloorLinePosition = -backgroundMargin + gridLineOffset; if (m_yFlipped) yFloorLinePosition = -yFloorLinePosition; // Rows (= Z) if (m_axisCacheZ.segmentCount() > 0) { - // Floor lines int gridLineCount = m_axisCacheZ.gridLineCount(); + // Floor lines + if (m_polarGraph) { + drawRadialGrid(lineShader, yFloorLinePosition, projectionViewMatrix, + depthProjectionViewMatrix); + } else { + for (int line = 0; line < gridLineCount; line++) { + QMatrix4x4 modelMatrix; + QMatrix4x4 MVPMatrix; + QMatrix4x4 itModelMatrix; - for (int line = 0; line < gridLineCount; line++) { - QMatrix4x4 modelMatrix; - QMatrix4x4 MVPMatrix; - QMatrix4x4 itModelMatrix; - - modelMatrix.translate(0.0f, yFloorLinePosition, - m_axisCacheZ.gridLinePosition(line)); + modelMatrix.translate(0.0f, yFloorLinePosition, + m_axisCacheZ.gridLinePosition(line)); - modelMatrix.scale(gridLineScaleX); - itModelMatrix.scale(gridLineScaleX); + modelMatrix.scale(gridLineScaleX); + itModelMatrix.scale(gridLineScaleX); - modelMatrix.rotate(lineXRotation); - itModelMatrix.rotate(lineXRotation); + modelMatrix.rotate(lineXRotation); + itModelMatrix.rotate(lineXRotation); - MVPMatrix = projectionViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; - // Set the rest of the shader bindings - lineShader->setUniformValue(lineShader->model(), modelMatrix); - lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); - lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); + // Set the rest of the shader bindings + lineShader->setUniformValue(lineShader->model(), modelMatrix); + lineShader->setUniformValue(lineShader->nModel(), + itModelMatrix.inverted().transposed()); + lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { - // Set shadow shader bindings - QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; - lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); - // Draw the object - m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); - } else { - // Draw the object - m_drawer->drawObject(lineShader, m_gridLineObj); - } + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { + // Set shadow shader bindings + QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; + lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); + } else { + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj); + } #else - m_drawer->drawLine(lineShader); + m_drawer->drawLine(lineShader); #endif - } - - // Side wall lines - GLfloat lineXTrans = m_scaleXWithBackground - gridLineOffset; + } + // Side wall lines + GLfloat lineXTrans = m_scaleXWithBackground - gridLineOffset; - if (!m_xFlipped) - lineXTrans = -lineXTrans; + if (!m_xFlipped) + lineXTrans = -lineXTrans; - for (int line = 0; line < gridLineCount; line++) { - QMatrix4x4 modelMatrix; - QMatrix4x4 MVPMatrix; - QMatrix4x4 itModelMatrix; + for (int line = 0; line < gridLineCount; line++) { + QMatrix4x4 modelMatrix; + QMatrix4x4 MVPMatrix; + QMatrix4x4 itModelMatrix; - modelMatrix.translate(lineXTrans, 0.0f, m_axisCacheZ.gridLinePosition(line)); + modelMatrix.translate(lineXTrans, 0.0f, m_axisCacheZ.gridLinePosition(line)); - modelMatrix.scale(gridLineScaleY); - itModelMatrix.scale(gridLineScaleY); + modelMatrix.scale(gridLineScaleY); + itModelMatrix.scale(gridLineScaleY); #if !defined(QT_OPENGL_ES_2) - modelMatrix.rotate(lineYRotation); - itModelMatrix.rotate(lineYRotation); + modelMatrix.rotate(lineYRotation); + itModelMatrix.rotate(lineYRotation); #else - modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); - itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); + modelMatrix.rotate(m_zRightAngleRotation); + itModelMatrix.rotate(m_zRightAngleRotation); #endif - MVPMatrix = projectionViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; - // Set the rest of the shader bindings - lineShader->setUniformValue(lineShader->model(), modelMatrix); - lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); - lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); + // Set the rest of the shader bindings + lineShader->setUniformValue(lineShader->model(), modelMatrix); + lineShader->setUniformValue(lineShader->nModel(), + itModelMatrix.inverted().transposed()); + lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { - // Set shadow shader bindings - QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; - lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); - // Draw the object - m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); - } else { - // Draw the object - m_drawer->drawObject(lineShader, m_gridLineObj); - } + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { + // Set shadow shader bindings + QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; + lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); + } else { + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj); + } #else - m_drawer->drawLine(lineShader); + m_drawer->drawLine(lineShader); #endif + } } } // Columns (= X) if (m_axisCacheX.segmentCount() > 0) { #if defined(QT_OPENGL_ES_2) - lineXRotation = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, 90.0f); + lineXRotation = m_yRightAngleRotation; #endif // Floor lines int gridLineCount = m_axisCacheX.gridLineCount(); - for (int line = 0; line < gridLineCount; line++) { - QMatrix4x4 modelMatrix; - QMatrix4x4 MVPMatrix; - QMatrix4x4 itModelMatrix; + if (m_polarGraph) { + drawAngularGrid(lineShader, yFloorLinePosition, projectionViewMatrix, + depthProjectionViewMatrix); + } else { + for (int line = 0; line < gridLineCount; line++) { + QMatrix4x4 modelMatrix; + QMatrix4x4 MVPMatrix; + QMatrix4x4 itModelMatrix; - modelMatrix.translate(m_axisCacheX.gridLinePosition(line), yFloorLinePosition, - 0.0f); + modelMatrix.translate(m_axisCacheX.gridLinePosition(line), yFloorLinePosition, + 0.0f); - modelMatrix.scale(gridLineScaleZ); - itModelMatrix.scale(gridLineScaleZ); + modelMatrix.scale(gridLineScaleZ); + itModelMatrix.scale(gridLineScaleZ); - modelMatrix.rotate(lineXRotation); - itModelMatrix.rotate(lineXRotation); + modelMatrix.rotate(lineXRotation); + itModelMatrix.rotate(lineXRotation); - MVPMatrix = projectionViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; - // Set the rest of the shader bindings - lineShader->setUniformValue(lineShader->model(), modelMatrix); - lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); - lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); + // Set the rest of the shader bindings + lineShader->setUniformValue(lineShader->model(), modelMatrix); + lineShader->setUniformValue(lineShader->nModel(), + itModelMatrix.inverted().transposed()); + lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { - // Set shadow shader bindings - QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; - lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); - // Draw the object - m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); - } else { - // Draw the object - m_drawer->drawObject(lineShader, m_gridLineObj); - } + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { + // Set shadow shader bindings + QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; + lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); + } else { + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj); + } #else - m_drawer->drawLine(lineShader); + m_drawer->drawLine(lineShader); #endif - } + } - // Back wall lines - GLfloat lineZTrans = m_scaleZWithBackground - gridLineOffset; + // Back wall lines + GLfloat lineZTrans = m_scaleZWithBackground - gridLineOffset; - if (!m_zFlipped) - lineZTrans = -lineZTrans; + if (!m_zFlipped) + lineZTrans = -lineZTrans; - for (int line = 0; line < gridLineCount; line++) { - QMatrix4x4 modelMatrix; - QMatrix4x4 MVPMatrix; - QMatrix4x4 itModelMatrix; + for (int line = 0; line < gridLineCount; line++) { + QMatrix4x4 modelMatrix; + QMatrix4x4 MVPMatrix; + QMatrix4x4 itModelMatrix; - modelMatrix.translate(m_axisCacheX.gridLinePosition(line), 0.0f, lineZTrans); + modelMatrix.translate(m_axisCacheX.gridLinePosition(line), 0.0f, lineZTrans); - modelMatrix.scale(gridLineScaleY); - itModelMatrix.scale(gridLineScaleY); + modelMatrix.scale(gridLineScaleY); + itModelMatrix.scale(gridLineScaleY); #if !defined(QT_OPENGL_ES_2) - if (m_zFlipped) { - modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); - itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); - } + if (m_zFlipped) { + modelMatrix.rotate(m_xFlipRotation); + itModelMatrix.rotate(m_xFlipRotation); + } #else - modelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); - itModelMatrix.rotate(90.0f, 0.0f, 0.0f, 1.0f); + modelMatrix.rotate(m_zRightAngleRotation); + itModelMatrix.rotate(m_zRightAngleRotation); #endif - MVPMatrix = projectionViewMatrix * modelMatrix; + MVPMatrix = projectionViewMatrix * modelMatrix; - // Set the rest of the shader bindings - lineShader->setUniformValue(lineShader->model(), modelMatrix); - lineShader->setUniformValue(lineShader->nModel(), - itModelMatrix.inverted().transposed()); - lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); + // Set the rest of the shader bindings + lineShader->setUniformValue(lineShader->model(), modelMatrix); + lineShader->setUniformValue(lineShader->nModel(), + itModelMatrix.inverted().transposed()); + lineShader->setUniformValue(lineShader->MVP(), MVPMatrix); #if !defined(QT_OPENGL_ES_2) - if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { - // Set shadow shader bindings - QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; - lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); - // Draw the object - m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); - } else { - // Draw the object - m_drawer->drawObject(lineShader, m_gridLineObj); - } + if (m_cachedShadowQuality > QAbstract3DGraph::ShadowQualityNone) { + // Set shadow shader bindings + QMatrix4x4 depthMVPMatrix = depthProjectionViewMatrix * modelMatrix; + lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix); + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture); + } else { + // Draw the object + m_drawer->drawObject(lineShader, m_gridLineObj); + } #else - m_drawer->drawLine(lineShader); + m_drawer->drawLine(lineShader); #endif + } } } @@ -1684,8 +1694,8 @@ void Surface3DRenderer::drawScene(GLuint defaultFboHandle) itModelMatrix.scale(gridLineScaleX); if (m_zFlipped) { - modelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); - itModelMatrix.rotate(180.0f, 1.0f, 0.0f, 0.0f); + modelMatrix.rotate(m_xFlipRotation); + itModelMatrix.rotate(m_xFlipRotation); } MVPMatrix = projectionViewMatrix * modelMatrix; @@ -1833,8 +1843,15 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa QVector3D positionZComp(0.0f, 0.0f, 0.0f); if (m_axisCacheZ.segmentCount() > 0) { int labelCount = m_axisCacheZ.labelCount(); - GLfloat labelXTrans = m_scaleXWithBackground + labelMargin; - GLfloat labelYTrans = -backgroundMargin; + float labelXTrans = 0.0f; + float labelYTrans = -backgroundMargin; + if (m_polarGraph) { + // TODO optional placement of radial labels - YTrans up only if over background + labelXTrans = m_scaleXWithBackground + labelMargin; + //labelYTrans += gridLineOffset + gridLineWidth; + } else { + labelXTrans = m_scaleXWithBackground + labelMargin; + } Qt::AlignmentFlag alignment = (m_xFlipped == m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; QVector3D labelRotation; if (m_xFlipped) @@ -1921,10 +1938,17 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa float offsetValue = 0.0f; for (int label = startIndex; label != endIndex; label = label + indexStep) { glPolygonOffset(offsetValue++ / -10.0f, 1.0f); + const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(label); // Draw the label here - labelTrans.setZ(m_axisCacheZ.labelPosition(label)); + if (m_polarGraph) { + float direction = m_zFlipped ? -1.0f : 1.0f; + labelTrans.setZ((m_axisCacheZ.formatter()->labelPositions().at(label) + * -m_graphAspectRatio + + m_drawer->scaledFontSize() + gridLineWidth) * direction); + } else { + labelTrans.setZ(m_axisCacheZ.labelPosition(label)); + } m_dummyRenderItem.setTranslation(labelTrans); - const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(label); if (drawSelection) { QVector4D labelColor = QVector4D(label / 255.0f, 0.0f, 0.0f, @@ -1953,8 +1977,13 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa fractionCamX = activeCamera->xRotation() * labelAngleFraction; int labelCount = m_axisCacheX.labelCount(); - GLfloat labelZTrans = m_scaleZWithBackground + labelMargin; + GLfloat labelZTrans = 0.0f; GLfloat labelYTrans = -backgroundMargin; + if (m_polarGraph) + labelYTrans += gridLineOffset + gridLineWidth; + else + labelZTrans = m_scaleZWithBackground + labelMargin; + Qt::AlignmentFlag alignment = (m_xFlipped != m_zFlipped) ? Qt::AlignLeft : Qt::AlignRight; QVector3D labelRotation; if (m_zFlipped) @@ -2023,7 +2052,14 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa } } } + QQuaternion totalRotation = Utils::calculateRotation(labelRotation); + if (m_polarGraph) { + if (m_zFlipped != m_xFlipped) + totalRotation *= m_zRightAngleRotation; + else + totalRotation *= m_zRightAngleRotationNeg; + } QVector3D labelTrans = QVector3D(0.0f, labelYTrans, @@ -2039,10 +2075,44 @@ void Surface3DRenderer::drawLabels(bool drawSelection, const Q3DCamera *activeCa indexStep = 1; } float offsetValue = 0.0f; + bool showLastLabel = false; + QVector<float> &gridPositions = m_axisCacheX.formatter()->gridPositions(); + int lastGridPosIndex = gridPositions.size() - 1; + if (gridPositions.size() + && (gridPositions.at(lastGridPosIndex) != 1.0f || gridPositions.at(0) != 0.0f)) { + // Avoid overlapping first and last label if they would get on same position + showLastLabel = true; + } + for (int label = startIndex; label != endIndex; label = label + indexStep) { glPolygonOffset(offsetValue++ / -10.0f, 1.0f); // Draw the label here - labelTrans.setX(m_axisCacheX.labelPosition(label)); + if (m_polarGraph) { + // Calculate angular position + if (label == lastGridPosIndex && !showLastLabel) + continue; + float gridPosition = m_axisCacheX.formatter()->gridPositions().at(label); + qreal angle = gridPosition * M_PI * 2.0; + labelTrans.setX((m_graphAspectRatio + labelMargin)* float(qSin(angle))); + labelTrans.setZ(-(m_graphAspectRatio + labelMargin) * float(qCos(angle))); + // Alignment depends on label angular position, as well as flips + Qt::AlignmentFlag vAlignment = Qt::AlignCenter; + Qt::AlignmentFlag hAlignment = Qt::AlignCenter; + const float centerMargin = 0.005f; + if (gridPosition < 0.25f - centerMargin || gridPosition > 0.75f + centerMargin) + vAlignment = m_zFlipped ? Qt::AlignTop : Qt::AlignBottom; + else if (gridPosition > 0.25f + centerMargin && gridPosition < 0.75f - centerMargin) + vAlignment = m_zFlipped ? Qt::AlignBottom : Qt::AlignTop; + + if (gridPosition < 0.50f - centerMargin && gridPosition > centerMargin) + hAlignment = m_zFlipped ? Qt::AlignRight : Qt::AlignLeft; + else if (gridPosition < 1.0f - centerMargin && gridPosition > 0.5f + centerMargin) + hAlignment = m_zFlipped ? Qt::AlignLeft : Qt::AlignRight; + + alignment = Qt::AlignmentFlag(vAlignment | hAlignment); + } else { + labelTrans.setX(m_axisCacheX.labelPosition(label)); + } m_dummyRenderItem.setTranslation(labelTrans); const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(label); @@ -2298,13 +2368,18 @@ void Surface3DRenderer::calculateSceneScalingFactors() m_heightNormalizer = GLfloat(m_axisCacheY.max() - m_axisCacheY.min()); m_areaSize.setHeight(m_axisCacheZ.max() - m_axisCacheZ.min()); m_areaSize.setWidth(m_axisCacheX.max() - m_axisCacheX.min()); - m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); - m_scaleX = m_graphAspectRatio * m_areaSize.width() / m_scaleFactor; - m_scaleZ = m_graphAspectRatio * m_areaSize.height() / m_scaleFactor; + float scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()); + if (m_polarGraph) { + m_scaleX = m_graphAspectRatio; + m_scaleZ = m_graphAspectRatio; + } else { + m_scaleX = m_graphAspectRatio * m_areaSize.width() / scaleFactor; + m_scaleZ = m_graphAspectRatio * m_areaSize.height() / scaleFactor; + } m_scaleXWithBackground = m_scaleX + backgroundMargin - 1.0f; m_scaleZWithBackground = m_scaleZ + backgroundMargin - 1.0f; - float factorScaler = 2.0f * m_graphAspectRatio / m_scaleFactor; + float factorScaler = 2.0f * m_graphAspectRatio / scaleFactor; m_axisCacheX.setScale(factorScaler * m_areaSize.width()); m_axisCacheZ.setScale(-factorScaler * m_areaSize.height()); m_axisCacheX.setTranslate(-m_axisCacheX.scale() / 2.0f); @@ -2327,10 +2402,12 @@ void Surface3DRenderer::updateObjects(SurfaceSeriesRenderCache *cache, bool dime QSurfaceDataArray &dataArray = cache->dataArray(); const QRect &sampleSpace = cache->sampleSpace(); - if (cache->isFlatShadingEnabled()) - cache->surfaceObject()->setUpData(dataArray, sampleSpace, dimensionChanged); - else - cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, dimensionChanged); + if (cache->isFlatShadingEnabled()) { + cache->surfaceObject()->setUpData(dataArray, sampleSpace, dimensionChanged, m_polarGraph); + } else { + cache->surfaceObject()->setUpSmoothData(dataArray, sampleSpace, dimensionChanged, + m_polarGraph); + } } void Surface3DRenderer::updateSelectedPoint(const QPoint &position, QSurface3DSeries *series) diff --git a/src/datavisualization/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h index efa8ff7e..a621fae3 100644 --- a/src/datavisualization/engine/surface3drenderer_p.h +++ b/src/datavisualization/engine/surface3drenderer_p.h @@ -57,12 +57,10 @@ private: ShaderHelper *m_selectionShader; ShaderHelper *m_labelShader; GLfloat m_heightNormalizer; - GLfloat m_scaleFactor; GLfloat m_scaleX; GLfloat m_scaleZ; GLfloat m_scaleXWithBackground; GLfloat m_scaleZWithBackground; - GLuint m_depthTexture; GLuint m_depthModelTexture; GLuint m_depthFrameBuffer; GLuint m_selectionFrameBuffer; diff --git a/src/datavisualization/global/datavisualizationglobal_p.h b/src/datavisualization/global/datavisualizationglobal_p.h index abdac998..f1f51309 100644 --- a/src/datavisualization/global/datavisualizationglobal_p.h +++ b/src/datavisualization/global/datavisualizationglobal_p.h @@ -69,6 +69,7 @@ static const GLfloat gradientTextureWidth = 2.0f; static const GLfloat uniformTextureHeight = 64.0f; static const GLfloat uniformTextureWidth = 2.0f; static const GLfloat labelMargin = 0.05f; +static const GLfloat gridLineWidth = 0.005f; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualization/theme/q3dtheme.cpp b/src/datavisualization/theme/q3dtheme.cpp index 97ff8f81..70397e23 100644 --- a/src/datavisualization/theme/q3dtheme.cpp +++ b/src/datavisualization/theme/q3dtheme.cpp @@ -679,7 +679,7 @@ QLinearGradient Q3DTheme::multiHighlightGradient() const /*! * \property Q3DTheme::lightStrength * - * Specular light strength for the whole graph. Value must be 0.0f and 10.0f. + * Specular light strength for the whole graph. Value must be between 0.0f and 10.0f. */ void Q3DTheme::setLightStrength(float strength) { diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp index d999ba90..f8675912 100644 --- a/src/datavisualization/utils/surfaceobject.cpp +++ b/src/datavisualization/utils/surfaceobject.cpp @@ -30,7 +30,8 @@ SurfaceObject::SurfaceObject(Surface3DRenderer *renderer) m_gridIndexCount(0), m_axisCacheX(renderer->m_axisCacheX), m_axisCacheY(renderer->m_axisCacheY), - m_axisCacheZ(renderer->m_axisCacheZ) + m_axisCacheZ(renderer->m_axisCacheZ), + m_renderer(renderer) { m_indicesType = GL_UNSIGNED_INT; @@ -49,7 +50,7 @@ SurfaceObject::~SurfaceObject() } void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, - bool changeGeometry, bool flipXZ) + bool changeGeometry, bool polar, bool flipXZ) { m_columns = space.width(); m_rows = space.height(); @@ -75,9 +76,16 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR const QSurfaceDataRow &p = *dataArray.at(i); for (int j = 0; j < m_columns; j++) { const QSurfaceDataItem &data = p.at(j); - float normalizedX = xCache.positionAt(data.x()); + float normalizedX; + float normalizedZ; + if (polar) { + // Slice don't use polar, so don't care about flip + m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ); + } else { + normalizedX = xCache.positionAt(data.x()); + normalizedZ = zCache.positionAt(data.z()); + } float normalizedY = m_axisCacheY.positionAt(data.y()); - float normalizedZ = zCache.positionAt(data.z()); m_vertices[totalIndex] = QVector3D(normalizedX, normalizedY, normalizedZ); if (changeGeometry) uvs[totalIndex] = QVector2D(GLfloat(j) * uvX, GLfloat(i) * uvY); @@ -137,7 +145,7 @@ void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QR createBuffers(m_vertices, uvs, m_normals, 0, changeGeometry); } -void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex) +void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar) { // Update vertices int p = rowIndex * m_columns; @@ -145,9 +153,15 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI for (int j = 0; j < m_columns; j++) { const QSurfaceDataItem &data = dataRow.at(j); - float normalizedX = m_axisCacheX.positionAt(data.x()); + float normalizedX; + float normalizedZ; + if (polar) { + m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ); + } else { + normalizedX = m_axisCacheX.positionAt(data.x()); + normalizedZ = m_axisCacheZ.positionAt(data.z()); + } float normalizedY = m_axisCacheY.positionAt(data.y()); - float normalizedZ = m_axisCacheZ.positionAt(data.z()); m_vertices[p++] = QVector3D(normalizedX, normalizedY, normalizedZ); } @@ -196,13 +210,20 @@ void SurfaceObject::updateSmoothRow(const QSurfaceDataArray &dataArray, int rowI } } -void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column) +void SurfaceObject::updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column, + bool polar) { // Update a vertice const QSurfaceDataItem &data = dataArray.at(row)->at(column); - float normalizedX = m_axisCacheX.positionAt(data.x()); + float normalizedX; + float normalizedZ; + if (polar) { + m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ); + } else { + normalizedX = m_axisCacheX.positionAt(data.x()); + normalizedZ = m_axisCacheZ.positionAt(data.z()); + } float normalizedY = m_axisCacheY.positionAt(data.y()); - float normalizedZ = m_axisCacheZ.positionAt(data.z()); m_vertices[row * m_columns + column] = QVector3D(normalizedX, normalizedY, normalizedZ); // Create normals @@ -331,7 +352,7 @@ void SurfaceObject::createSmoothGridlineIndices(int x, int y, int endX, int endY } void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space, - bool changeGeometry, bool flipXZ) + bool changeGeometry, bool polar, bool flipXZ) { m_columns = space.width(); m_rows = space.height(); @@ -362,9 +383,16 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s const QSurfaceDataRow &row = *dataArray.at(i); for (int j = 0; j < m_columns; j++) { const QSurfaceDataItem &data = row.at(j); - float normalizedX = xCache.positionAt(data.x()); + float normalizedX; + float normalizedZ; + if (polar) { + // Slice don't use polar, so don't care about flip + m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ); + } else { + normalizedX = xCache.positionAt(data.x()); + normalizedZ = zCache.positionAt(data.z()); + } float normalizedY = m_axisCacheY.positionAt(data.y()); - float normalizedZ = zCache.positionAt(data.z()); m_vertices[totalIndex] = QVector3D(normalizedX, normalizedY, normalizedZ); if (changeGeometry) uvs[totalIndex] = QVector2D(GLfloat(j) * uvX, GLfloat(i) * uvY); @@ -438,7 +466,7 @@ void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &s delete[] indices; } -void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex) +void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar) { int colLimit = m_columns - 1; int doubleColumns = m_columns * 2 - 2; @@ -448,9 +476,15 @@ void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowI for (int j = 0; j < m_columns; j++) { const QSurfaceDataItem &data = dataRow.at(j); - float normalizedX = m_axisCacheX.positionAt(data.x()); + float normalizedX; + float normalizedZ; + if (polar) { + m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ); + } else { + normalizedX = m_axisCacheX.positionAt(data.x()); + normalizedZ = m_axisCacheZ.positionAt(data.z()); + } float normalizedY = m_axisCacheY.positionAt(data.y()); - float normalizedZ = m_axisCacheZ.positionAt(data.z()); m_vertices[p++] = QVector3D(normalizedX, normalizedY, normalizedZ); if (j > 0 && j < colLimit) { @@ -486,7 +520,8 @@ void SurfaceObject::updateCoarseRow(const QSurfaceDataArray &dataArray, int rowI } } -void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column) +void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column, + bool polar) { int colLimit = m_columns - 1; int doubleColumns = m_columns * 2 - 2; @@ -494,9 +529,15 @@ void SurfaceObject::updateCoarseItem(const QSurfaceDataArray &dataArray, int row // Update a vertice int p = row * doubleColumns + column * 2 - (column > 0); const QSurfaceDataItem &data = dataArray.at(row)->at(column); - float normalizedX = m_axisCacheX.positionAt(data.x()); + float normalizedX; + float normalizedZ; + if (polar) { + m_renderer->calculatePolarXZ(data.position(), normalizedX, normalizedZ); + } else { + normalizedX = m_axisCacheX.positionAt(data.x()); + normalizedZ = m_axisCacheZ.positionAt(data.z()); + } float normalizedY = m_axisCacheY.positionAt(data.y()); - float normalizedZ = m_axisCacheZ.positionAt(data.z()); m_vertices[p] = QVector3D(normalizedX, normalizedY, normalizedZ); p++; diff --git a/src/datavisualization/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h index 9c18dcb2..54e6dec3 100644 --- a/src/datavisualization/utils/surfaceobject_p.h +++ b/src/datavisualization/utils/surfaceobject_p.h @@ -54,13 +54,13 @@ public: ~SurfaceObject(); void setUpData(const QSurfaceDataArray &dataArray, const QRect &space, - bool changeGeometry, bool flipXZ = false); + bool changeGeometry, bool polar, bool flipXZ = false); void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, - bool changeGeometry, bool flipXZ = false); - void updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex); - void updateSmoothRow(const QSurfaceDataArray &dataArray, int startRow); - void updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column); - void updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column); + bool changeGeometry, bool polar, bool flipXZ = false); + void updateCoarseRow(const QSurfaceDataArray &dataArray, int rowIndex, bool polar); + void updateSmoothRow(const QSurfaceDataArray &dataArray, int startRow, bool polar); + void updateSmoothItem(const QSurfaceDataArray &dataArray, int row, int column, bool polar); + void updateCoarseItem(const QSurfaceDataArray &dataArray, int row, int column, bool polar); void createSmoothIndices(int x, int y, int endX, int endY); void createCoarseIndices(int x, int y, int columns, int rows); void createSmoothGridlineIndices(int x, int y, int endX, int endY); @@ -90,6 +90,7 @@ private: AxisRenderCache &m_axisCacheX; AxisRenderCache &m_axisCacheY; AxisRenderCache &m_axisCacheZ; + Surface3DRenderer *m_renderer; }; QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp index f7ccbf21..30acc9e4 100644 --- a/src/datavisualizationqml2/abstractdeclarative.cpp +++ b/src/datavisualizationqml2/abstractdeclarative.cpp @@ -329,6 +329,8 @@ void AbstractDeclarative::setSharedController(Abstract3DController *controller) &AbstractDeclarative::aspectRatioChanged); QObject::connect(m_controller.data(), &Abstract3DController::optimizationHintsChanged, this, &AbstractDeclarative::handleOptimizationHintChange); + QObject::connect(m_controller.data(), &Abstract3DController::polarChanged, this, + &AbstractDeclarative::polarChanged); } void AbstractDeclarative::activateOpenGLContext(QQuickWindow *window) @@ -724,6 +726,16 @@ AbstractDeclarative::OptimizationHints AbstractDeclarative::optimizationHints() return OptimizationHints(intmode); } +void AbstractDeclarative::setPolar(bool enable) +{ + m_controller->setPolar(enable); +} + +bool AbstractDeclarative::isPolar() const +{ + return m_controller->isPolar(); +} + void AbstractDeclarative::windowDestroyed(QObject *obj) { // Remove destroyed window from window lists diff --git a/src/datavisualizationqml2/abstractdeclarative_p.h b/src/datavisualizationqml2/abstractdeclarative_p.h index dfcd9537..cd3d6134 100644 --- a/src/datavisualizationqml2/abstractdeclarative_p.h +++ b/src/datavisualizationqml2/abstractdeclarative_p.h @@ -72,6 +72,7 @@ class AbstractDeclarative : public QQuickItem Q_PROPERTY(ElementType selectedElement READ selectedElement NOTIFY selectedElementChanged REVISION 1) Q_PROPERTY(qreal aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged REVISION 1) Q_PROPERTY(OptimizationHints optimizationHints READ optimizationHints WRITE setOptimizationHints NOTIFY optimizationHintsChanged REVISION 1) + Q_PROPERTY(bool polar READ isPolar WRITE setPolar NOTIFY polarChanged REVISION 2) public: enum SelectionFlag { @@ -193,6 +194,9 @@ public: void setOptimizationHints(OptimizationHints hints); OptimizationHints optimizationHints() const; + void setPolar(bool enable); + bool isPolar() const; + public slots: virtual void handleAxisXChanged(QAbstract3DAxis *axis) = 0; virtual void handleAxisYChanged(QAbstract3DAxis *axis) = 0; @@ -230,6 +234,7 @@ signals: Q_REVISION(1) void orthoProjectionChanged(bool enabled); Q_REVISION(1) void aspectRatioChanged(qreal ratio); Q_REVISION(1) void optimizationHintsChanged(AbstractDeclarative::OptimizationHints hints); + Q_REVISION(2) void polarChanged(bool enabled); private: QPointer<Abstract3DController> m_controller; diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp index 09780dc5..c4c0bc70 100644 --- a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp +++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp @@ -106,6 +106,12 @@ void QtDataVisualizationQml2Plugin::registerTypes(const char *uri) // New metatypes qRegisterMetaType<QAbstract3DGraph::ElementType>("QAbstract3DGraph::ElementType"); + + // QtDataVisualization 1.2 + + // New revisions + qmlRegisterUncreatableType<AbstractDeclarative, 2>(uri, 1, 2, "AbstractGraph3D", + QLatin1String("Trying to create uncreatable: AbstractGraph3D.")); } QT_END_NAMESPACE_DATAVISUALIZATION diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp index ed86f03c..56cd23cc 100644 --- a/tests/surfacetest/graphmodifier.cpp +++ b/tests/surfacetest/graphmodifier.cpp @@ -777,6 +777,11 @@ void GraphModifier::toggleZAscending(bool enabled) } } +void GraphModifier::togglePolar(bool enabled) +{ + m_graph->setPolar(enabled); +} + void GraphModifier::resetArrayAndSliders(QSurfaceDataArray *array, float minZ, float maxZ, float minX, float maxX) { m_axisMinSliderX->setValue(minX); diff --git a/tests/surfacetest/graphmodifier.h b/tests/surfacetest/graphmodifier.h index 5f1a252a..e70d35f2 100644 --- a/tests/surfacetest/graphmodifier.h +++ b/tests/surfacetest/graphmodifier.h @@ -131,6 +131,7 @@ public slots: void toggleAxisTitleFixed(bool enabled); void toggleXAscending(bool enabled); void toggleZAscending(bool enabled); + void togglePolar(bool enabled); private: void fillSeries(); diff --git a/tests/surfacetest/main.cpp b/tests/surfacetest/main.cpp index 5806d7b0..87f009cb 100644 --- a/tests/surfacetest/main.cpp +++ b/tests/surfacetest/main.cpp @@ -393,6 +393,10 @@ int main(int argc, char *argv[]) zAscendingCB->setText(QStringLiteral("Z Ascending")); zAscendingCB->setChecked(true); + QCheckBox *polarCB = new QCheckBox(widget); + polarCB->setText(QStringLiteral("Polar")); + polarCB->setChecked(false); + // Add controls to the layout #ifdef MULTI_SERIES vLayout->addWidget(series1CB); @@ -443,6 +447,7 @@ int main(int argc, char *argv[]) vLayout->addWidget(axisMinSliderZ); vLayout->addWidget(xAscendingCB); vLayout->addWidget(zAscendingCB); + vLayout->addWidget(polarCB); vLayout2->addWidget(new QLabel(QStringLiteral("Change font"))); vLayout2->addWidget(fontList); vLayout2->addWidget(labelButton); @@ -650,6 +655,8 @@ int main(int argc, char *argv[]) modifier, &GraphModifier::toggleXAscending); QObject::connect(zAscendingCB, &QCheckBox::stateChanged, modifier, &GraphModifier::toggleZAscending); + QObject::connect(polarCB, &QCheckBox::stateChanged, + modifier, &GraphModifier::togglePolar); QObject::connect(aspectRatioSlider, &QSlider::valueChanged, modifier, &GraphModifier::setAspectRatio); |