60 QPainter painter(
this);
61 painter.setRenderHint(QPainter::Antialiasing,
true);
62 painter.setRenderHint(QPainter::TextAntialiasing,
true);
63 painter.fillRect(rect(), QColor(15, 18, 23));
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()));
76 painter.setPen(QPen(QColor(170, 180, 190), 1.0));
77 painter.drawRect(plotRect);
81 bool haveSamples =
false;
83 if (sample.hasDoubleWell) {
84 if (!haveSamples) tMin = sample.time;
85 tMax = std::max(tMax, sample.time);
89 if (!(tMax > tMin)) tMax = tMin + 1.0;
91 const auto mapX = [plotRect, tMin, tMax](
double t) {
92 return plotRect.left() + (t - tMin) / (tMax - tMin) * plotRect.width();
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();
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); }
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);
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()));
126 QPainterPath leftPath;
127 QPainterPath rightPath;
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));
135 rightPath.moveTo(pr);
139 rightPath.lineTo(pr);
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);
149 painter.setPen(QColor(190, 195, 205));
150 painter.drawText(plotRect, Qt::AlignCenter,
151 QStringLiteral(
"Load the coherent double-well experiment and press Play"));
154 painter.setPen(QColor(210, 215, 222));
155 painter.drawText(QRectF(plotRect.left(), 2.0, plotRect.width(), 20.0),
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"));
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"));