78 p.setRenderHint(QPainter::Antialiasing,
true);
79 p.fillRect(rect(), QColor(11, 16, 22));
84 p.setPen(QColor(224, 234, 242));
85 p.drawText(QRect(12, 7, width() - 24, 24), Qt::AlignLeft | Qt::AlignVCenter,
86 QStringLiteral(
"Kapitza-Dirac diffraction — momentum orders from a light grating"));
90 p.setPen(QColor(150, 166, 180));
91 p.drawText(QRect(20, 50, width() - 40, height() - 70),
92 Qt::AlignCenter | Qt::TextWordWrap,
93 QStringLiteral(
"Load Kapitza-Dirac Diffraction and press Play"));
97 const std::vector<qpe::QuantumKapitzaDiracSample2D> &samples =
history_->
samples();
102 const int right = 18;
105 const int barsH = std::max(120, height() / 3);
106 const int carpetBottom = height() - barsH - gap;
107 QRect carpet(left, top, std::max(20, width() - left - right),
108 std::max(90, carpetBottom - top));
109 QRect bars(left, carpet.bottom() + gap, carpet.width(),
110 std::max(80, height() - (carpet.bottom() + gap) - 28));
112 p.setPen(QColor(62, 77, 90));
113 p.setBrush(QColor(6, 11, 16));
117 double maxP = 1.0e-12;
119 for (
float v : s.momentumProbability) maxP = std::max(maxP,
static_cast<double>(v));
123 for (std::size_t row = 0u; row < samples.size(); ++row) {
125 const int y0 = carpet.top() +
static_cast<int>(
126 static_cast<double>(row) / samples.size() * carpet.height());
127 const int y1 = carpet.top() +
static_cast<int>(
128 static_cast<double>(row + 1u) / samples.size() * carpet.height());
130 const int x0 = carpet.left() +
static_cast<int>(
131 static_cast<double>(col) / bins * carpet.width());
132 const int x1 = carpet.left() +
static_cast<int>(
133 static_cast<double>(col + 1u) / bins * carpet.width());
134 const double q = std::sqrt(std::max(0.0,
136 p.fillRect(QRect(x0, y0, std::max(1, x1 - x0 + 1),
137 std::max(1, y1 - y0 + 1)), heatColor(q));
143 last.
momentumStep *
static_cast<double>(bins > 0u ? bins - 1u : 0u);
144 const auto mapP = [&](
double momentum) {
145 const double u = (momentum - pMin) / std::max(1.0e-12, pMax - pMin);
146 return carpet.left() + u * carpet.width();
148 p.setPen(QPen(QColor(255, 205, 78, 180), 1.0, Qt::DashLine));
151 if (px < pMin || px > pMax)
continue;
152 p.drawLine(QPointF(mapP(px), carpet.top()), QPointF(mapP(px), carpet.bottom()));
154 p.setPen(QColor(180, 197, 210));
155 p.drawText(QRect(carpet.left(), carpet.bottom() + 4, carpet.width(), 20),
157 QStringLiteral(
"p_x — gold guides: n G, G=2 pi hbar / a"));
158 p.drawText(QRect(4, carpet.top(), left - 10, 20),
159 Qt::AlignRight | Qt::AlignVCenter, QStringLiteral(
"t=0"));
160 p.drawText(QRect(4, carpet.bottom() - 20, left - 10, 20),
161 Qt::AlignRight | Qt::AlignVCenter,
162 QStringLiteral(
"%1").arg(last.
time, 0,
'f', 2));
166 if (orderCount > 0) {
167 double maxOrderP = 1.0e-12;
168 for (
float v : last.
orderProbability) maxOrderP = std::max(maxOrderP,
static_cast<double>(v));
169 const double cellW =
static_cast<double>(bars.width()) / orderCount;
170 for (
int i = 0; i < orderCount; ++i) {
171 const double v =
static_cast<double>(last.
orderProbability[
static_cast<std::size_t
>(i)]);
172 const double h = v / maxOrderP * (bars.height() - 30);
173 const QRectF r(bars.left() + i * cellW + 0.12 * cellW,
177 p.fillRect(r, QColor(83, 211, 238));
178 p.setPen(QColor(205, 220, 231));
180 p.drawText(QRectF(bars.left() + i * cellW, bars.bottom() + 3,
181 cellW, 20), Qt::AlignCenter,
184 p.setPen(QColor(180, 197, 210));
185 p.drawText(QRect(4, bars.top(), left - 10, 20),
186 Qt::AlignRight | Qt::AlignVCenter,
187 QStringLiteral(
"Pmax"));
188 p.drawText(QRect(bars.left(), bars.bottom() + 22, bars.width(), 20),
190 QStringLiteral(
"diffraction order n"));
193 p.setPen(QColor(225, 235, 242));
194 const QString stage = last.
pulseActive ? QStringLiteral(
"LIGHT PULSE ON") :
196 ? QStringLiteral(
"free expansion") : QStringLiteral(
"before pulse"));
197 p.drawText(QRect(bars.left() + 8, bars.top() + 5, bars.width() - 16, 20),
198 Qt::AlignLeft | Qt::AlignVCenter,
199 QStringLiteral(
"%1 samples=%2 t=%3 G=%4 pulse area beta=%5")
201 .arg(
static_cast<qulonglong
>(samples.size()))
202 .arg(last.
time, 0,
'f', 3)