Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
quantumdoublewellplotwidget.cpp
Go to the documentation of this file.
1/**
2 * @file quantumdoublewellplotwidget.cpp
3 * @brief Implements the quantumdoublewellplotwidget visualization component used by QPE.
4 * @ingroup qpe_graphics
5 *
6 * Source: @c graphics/renderer/quantumdoublewellplotwidget.cpp. This file is part of Quantum Phenomena Explorer (QPE),
7 * maintained by Officina Turini. See LICENSE_IT.txt / LICENSE.txt for the
8 * QPE freeware source-available terms and THIRD_PARTY_NOTICES.txt for
9 * third-party components.
10 */
11
13
14#include <QPaintEvent>
15#include <QPainter>
16#include <QPainterPath>
17
18#include <algorithm>
19#include <cmath>
20
21namespace {
22constexpr double kPi = 3.141592653589793238462643383279502884;
23}
24
26 : QWidget(parent)
27{
28 setMinimumHeight(180);
29 setAutoFillBackground(false);
30}
31
33 const std::vector<qpe::ObservablesTimeSeries2DSample> &samples)
34{
35 samples_ = samples;
36 update();
37}
38
40{
41 period_ = period;
42 update();
43}
44
46{
47 samples_.clear();
48 period_ = 0.0;
49 update();
50}
51
53{
54 return QSize(480, 180);
55}
56
58{
59 Q_UNUSED(event);
60 QPainter painter(this);
61 painter.setRenderHint(QPainter::Antialiasing, true);
62 painter.setRenderHint(QPainter::TextAntialiasing, true);
63 painter.fillRect(rect(), QColor(15, 18, 23));
64
65 const QRectF plotRect(58.0, 26.0,
66 std::max(10.0, width() - 78.0),
67 std::max(10.0, height() - 64.0));
68 painter.setPen(QPen(QColor(78, 86, 96), 1.0));
69 for (int i = 0; i <= 4; ++i) {
70 const double u = static_cast<double>(i) / 4.0;
71 painter.drawLine(QPointF(plotRect.left() + u * plotRect.width(), plotRect.top()),
72 QPointF(plotRect.left() + u * plotRect.width(), plotRect.bottom()));
73 painter.drawLine(QPointF(plotRect.left(), plotRect.top() + u * plotRect.height()),
74 QPointF(plotRect.right(), plotRect.top() + u * plotRect.height()));
75 }
76 painter.setPen(QPen(QColor(170, 180, 190), 1.0));
77 painter.drawRect(plotRect);
78
79 double tMin = 0.0;
80 double tMax = period_ > 0.0 ? period_ : 1.0;
81 bool haveSamples = false;
82 for (const qpe::ObservablesTimeSeries2DSample &sample : samples_) {
83 if (sample.hasDoubleWell) {
84 if (!haveSamples) tMin = sample.time;
85 tMax = std::max(tMax, sample.time);
86 haveSamples = true;
87 }
88 }
89 if (!(tMax > tMin)) tMax = tMin + 1.0;
90
91 const auto mapX = [plotRect, tMin, tMax](double t) {
92 return plotRect.left() + (t - tMin) / (tMax - tMin) * plotRect.width();
93 };
94 const auto mapY = [plotRect](double p) {
95 const double clamped = std::max(0.0, std::min(1.0, p));
96 return plotRect.bottom() - clamped * plotRect.height();
97 };
98
99 if (period_ > 0.0) {
100 QPainterPath idealLeft;
101 QPainterPath idealRight;
102 const int segments = 240;
103 for (int i = 0; i <= segments; ++i) {
104 const double t = tMin + (tMax - tMin) * static_cast<double>(i) / static_cast<double>(segments);
105 const double phase = kPi * t / period_;
106 const double left = std::cos(phase) * std::cos(phase);
107 const double right = std::sin(phase) * std::sin(phase);
108 const QPointF pl(mapX(t), mapY(left));
109 const QPointF pr(mapX(t), mapY(right));
110 if (i == 0) { idealLeft.moveTo(pl); idealRight.moveTo(pr); }
111 else { idealLeft.lineTo(pl); idealRight.lineTo(pr); }
112 }
113 painter.setPen(QPen(QColor(100, 190, 225, 125), 1.2, Qt::DashLine));
114 painter.drawPath(idealLeft);
115 painter.setPen(QPen(QColor(255, 180, 105, 125), 1.2, Qt::DashLine));
116 painter.drawPath(idealRight);
117
118 const double transfer = 0.5 * period_;
119 if (transfer >= tMin && transfer <= tMax) {
120 painter.setPen(QPen(QColor(170, 175, 185), 1.0, Qt::DashDotLine));
121 painter.drawLine(QPointF(mapX(transfer), plotRect.top()),
122 QPointF(mapX(transfer), plotRect.bottom()));
123 }
124 }
125
126 QPainterPath leftPath;
127 QPainterPath rightPath;
128 bool first = true;
129 for (const qpe::ObservablesTimeSeries2DSample &sample : samples_) {
130 if (!sample.hasDoubleWell) continue;
131 const QPointF pl(mapX(sample.time), mapY(sample.leftWellProbability));
132 const QPointF pr(mapX(sample.time), mapY(sample.rightWellProbability));
133 if (first) {
134 leftPath.moveTo(pl);
135 rightPath.moveTo(pr);
136 first = false;
137 } else {
138 leftPath.lineTo(pl);
139 rightPath.lineTo(pr);
140 }
141 }
142
143 if (!first) {
144 painter.setPen(QPen(QColor(100, 220, 255), 2.2));
145 painter.drawPath(leftPath);
146 painter.setPen(QPen(QColor(255, 185, 95), 2.2));
147 painter.drawPath(rightPath);
148 } else {
149 painter.setPen(QColor(190, 195, 205));
150 painter.drawText(plotRect, Qt::AlignCenter,
151 QStringLiteral("Load the coherent double-well experiment and press Play"));
152 }
153
154 painter.setPen(QColor(210, 215, 222));
155 painter.drawText(QRectF(plotRect.left(), 2.0, plotRect.width(), 20.0),
156 Qt::AlignCenter,
157 QStringLiteral("Coherent tunnelling: left/right well population"));
158 painter.setPen(QColor(160, 168, 178));
159 painter.drawText(QRectF(2.0, plotRect.top() - 8.0, 52.0, 18.0),
160 Qt::AlignRight | Qt::AlignVCenter, QStringLiteral("1.0"));
161 painter.drawText(QRectF(2.0, plotRect.bottom() - 10.0, 52.0, 18.0),
162 Qt::AlignRight | Qt::AlignVCenter, QStringLiteral("0.0"));
163 painter.drawText(QRectF(plotRect.left(), plotRect.bottom() + 5.0,
164 plotRect.width(), 22.0),
165 Qt::AlignCenter, QStringLiteral("simulation time"));
166
167 painter.setPen(QColor(100, 220, 255));
168 painter.drawText(QRectF(plotRect.left() + 8.0, plotRect.top() + 5.0, 150.0, 18.0),
169 Qt::AlignLeft, QStringLiteral("P_left"));
170 painter.setPen(QColor(255, 185, 95));
171 painter.drawText(QRectF(plotRect.left() + 82.0, plotRect.top() + 5.0, 150.0, 18.0),
172 Qt::AlignLeft, QStringLiteral("P_right"));
173}
std::vector< qpe::ObservablesTimeSeries2DSample > samples_
void setSamples(const std::vector< qpe::ObservablesTimeSeries2DSample > &samples)
Sets samples.
void setTheory(double period)
Sets theory.
void paintEvent(QPaintEvent *event) override
Paints event.
QuantumDoubleWellPlotWidget(QWidget *parent=nullptr)
Performs quantum double well plot widget.
QSize minimumSizeHint() const override
Performs minimum size hint.
Declares the quantumdoublewellplotwidget visualization component used by QPE.
Data record containing Observables Time Series2D Sample.