Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
quantumdiracmasslesscomparisonplotwidget.cpp
Go to the documentation of this file.
1/**
2 * @file quantumdiracmasslesscomparisonplotwidget.cpp
3 * @brief Implements the quantumdiracmasslesscomparisonplotwidget visualization component used by QPE.
4 * @ingroup qpe_graphics
5 *
6 * Source: @c graphics/renderer/quantumdiracmasslesscomparisonplotwidget.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
25
28 double currentAngleDegrees,
29 double packetTransmission)
30{
31 scan_ = scan;
32 currentAngleDegrees_ = currentAngleDegrees;
33 packetTransmission_ = packetTransmission;
34 update();
35}
36
43
45{
46 return QSize(700, 460);
47}
48
50{
51 Q_UNUSED(event);
52 QPainter p(this);
53 p.setRenderHint(QPainter::Antialiasing, true);
54 p.fillRect(rect(), QColor(9, 13, 19));
55
56 QFont titleFont = font();
57 titleFont.setBold(true);
58 p.setFont(titleFont);
59 p.setPen(QColor(230, 238, 246));
60 p.drawText(QRect(12, 6, width() - 24, 25), Qt::AlignLeft | Qt::AlignVCenter,
61 QStringLiteral("Massless Dirac / graphene-like analogue — same E, same barrier"));
62
63 if (!scan_.valid || scan_.points.empty()) {
64 p.setFont(font());
65 p.setPen(QColor(145, 162, 178));
66 p.drawText(QRect(20, 45, width() - 40, height() - 65),
67 Qt::AlignCenter | Qt::TextWordWrap,
68 QStringLiteral("Load the Massless Dirac / Graphene-like Klein Analogue preset."));
69 return;
70 }
71
72 const int left = 64, right = 24, top = 50, bottom = 62;
73 QRect plot(left, top, std::max(120, width() - left - right),
74 std::max(120, height() - top - bottom));
75 p.setBrush(QColor(5, 9, 15));
76 p.setPen(QColor(54, 72, 88));
77 p.drawRect(plot);
78
79 const double amin = scan_.minimumAngleDegrees;
80 const double amax = scan_.maximumAngleDegrees;
81 const auto xOf = [&](double angle) {
82 return plot.left() + (angle - amin) / std::max(1.0e-12, amax - amin) * plot.width();
83 };
84 const auto yOf = [&](double transmission) {
85 return plot.bottom() - std::max(0.0, std::min(1.0, transmission)) * plot.height();
86 };
87
88 // Emphasize the near-normal sector where chirality-protected transmission
89 // is easiest to read before finite-width resonances dominate the curve.
90 const double nearNormalEnd = std::min(12.0, amax);
91 if (nearNormalEnd > amin) {
92 p.fillRect(QRectF(xOf(amin), plot.top(), xOf(nearNormalEnd) - xOf(amin), plot.height()),
93 QColor(45, 80, 110, 42));
94 }
95
96 p.setFont(font());
97 p.setPen(QColor(77, 94, 109));
98 for (int i = 0; i <= 5; ++i) {
99 const double t = static_cast<double>(i) / 5.0;
100 const int y = static_cast<int>(std::lround(yOf(t)));
101 p.drawLine(plot.left(), y, plot.right(), y);
102 p.setPen(QColor(170, 184, 197));
103 p.drawText(QRect(7, y - 9, 50, 18), Qt::AlignRight | Qt::AlignVCenter,
104 QString::number(t, 'f', 1));
105 p.setPen(QColor(77, 94, 109));
106 }
107 for (int i = 0; i <= 7; ++i) {
108 const double angle = amin + (amax - amin) * static_cast<double>(i) / 7.0;
109 const int x = static_cast<int>(std::lround(xOf(angle)));
110 p.drawLine(x, plot.top(), x, plot.bottom());
111 p.setPen(QColor(170, 184, 197));
112 p.drawText(QRect(x - 28, plot.bottom() + 5, 56, 20), Qt::AlignHCenter | Qt::AlignTop,
113 QString::number(angle, 'f', 0));
114 p.setPen(QColor(77, 94, 109));
115 }
116
117 auto drawCurve = [&](bool massless, const QColor &color, double width) {
118 QPainterPath path;
119 bool first = true;
121 if (!point.valid) { first = true; continue; }
122 const double t = massless ? point.masslessTransmission : point.massiveTransmission;
123 const QPointF q(xOf(point.angleDegrees), yOf(t));
124 if (first) { path.moveTo(q); first = false; }
125 else path.lineTo(q);
126 }
127 p.setBrush(Qt::NoBrush);
128 p.setPen(QPen(color, width));
129 p.drawPath(path);
130 };
131
132 drawCurve(false, QColor(220, 130, 255), 2.0);
133 drawCurve(true, QColor(100, 220, 255), 2.6);
134
135 if (currentAngleDegrees_ >= amin && currentAngleDegrees_ <= amax) {
136 double referenceT = scan_.points.front().masslessTransmission;
137 for (std::size_t i = 1; i < scan_.points.size(); ++i) {
138 const auto &a0 = scan_.points[i - 1u];
139 const auto &a1 = scan_.points[i];
140 if (!a0.valid || !a1.valid) continue;
141 if (currentAngleDegrees_ <= a1.angleDegrees) {
142 const double f = (currentAngleDegrees_ - a0.angleDegrees) /
143 std::max(1.0e-12, a1.angleDegrees - a0.angleDegrees);
144 referenceT = a0.masslessTransmission + f *
145 (a1.masslessTransmission - a0.masslessTransmission);
146 break;
147 }
148 }
149 const int x = static_cast<int>(std::lround(xOf(currentAngleDegrees_)));
150 p.setPen(QPen(QColor(255, 205, 95), 1.5, Qt::DashLine));
151 p.drawLine(x, plot.top(), x, plot.bottom());
152 p.setBrush(QColor(255, 205, 95));
153 p.setPen(Qt::NoPen);
154 p.drawEllipse(QPointF(xOf(currentAngleDegrees_), yOf(referenceT)), 5.0, 5.0);
155 if (packetTransmission_ >= 0.0 && packetTransmission_ <= 1.05) {
156 p.setBrush(QColor(255, 126, 126));
157 p.drawEllipse(QPointF(xOf(currentAngleDegrees_), yOf(packetTransmission_)), 5.0, 5.0);
158 }
159 }
160
161 p.setPen(QColor(188, 202, 214));
162 p.setFont(font());
163 p.drawText(QRect(plot.left(), plot.bottom() + 30, plot.width(), 24), Qt::AlignCenter,
164 QStringLiteral("incidence angle (deg) cyan: m=0 violet: massive fixed-E control yellow: current m=0 reference red: packet max P_right"));
165
167 p.setPen(QColor(235, 240, 245));
168 p.drawText(QRect(plot.left() + 8, plot.top() + 6, plot.width() - 16, 44),
169 Qt::AlignLeft | Qt::AlignTop,
170 QStringLiteral("E=%1 V0=%2 width=%3 p(m=0)=%4 p(m=%5)=%6 T0: %7 vs %8")
171 .arg(scan_.fixedIncidentEnergy, 0, 'f', 4)
172 .arg(scan_.barrierHeight, 0, 'f', 3)
173 .arg(scan_.barrierWidth, 0, 'f', 3)
174 .arg(scan_.masslessMomentumMagnitude, 0, 'f', 4)
175 .arg(scan_.massiveRestMass, 0, 'f', 2)
176 .arg(scan_.massiveMomentumMagnitude, 0, 'f', 4)
177 .arg(normal.valid ? normal.masslessTransmission : 0.0, 0, 'f', 4)
178 .arg(normal.valid ? normal.massiveTransmission : 0.0, 0, 'f', 4));
179
180 p.setPen(QColor(170, 184, 197));
181 p.drawText(QRect(static_cast<int>(xOf(amin)) + 4, plot.top() + 30,
182 std::max(0, static_cast<int>(xOf(nearNormalEnd) - xOf(amin)) - 8), 20),
183 Qt::AlignCenter, QStringLiteral("near-normal chirality window"));
184}
void paintEvent(QPaintEvent *event) override
Paints event.
void setData(const qpe::QuantumDiracMasslessComparison2DResult &scan, double currentAngleDegrees, double packetTransmission=-1.0)
Sets data.
QuantumDiracMasslessComparisonPlotWidget(QWidget *parent=nullptr)
Performs quantum dirac massless comparison plot widget.
QSize minimumSizeHint() const override
Performs minimum size hint.
Declares the quantumdiracmasslesscomparisonplotwidget visualization component used by QPE.
Data record containing Quantum Dirac Massless Comparison2D Result.
std::vector< QuantumDiracMasslessComparisonPoint2D > points
Data structure used by the Quantum Dirac Massless Comparison Point2D component.