Quantum Phenomena Explorer 7.9.8
Interactive quantum-phenomena Explorer Tutor — source documentation
Loading...
Searching...
No Matches
quantumkleinanglescanplotwidget.cpp
Go to the documentation of this file.
1/**
2 * @file quantumkleinanglescanplotwidget.cpp
3 * @brief Implements the quantumkleinanglescanplotwidget visualization component used by QPE.
4 * @ingroup qpe_graphics
5 *
6 * Source: @c graphics/renderer/quantumkleinanglescanplotwidget.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
22 : QWidget(parent)
23{
24}
25
27 double currentAngleDegrees,
28 double packetTransmission)
29{
30 scan_ = scan;
31 currentAngleDegrees_ = currentAngleDegrees;
32 packetTransmission_ = packetTransmission;
33 update();
34}
35
42
44{
45 return QSize(670, 440);
46}
47
49{
50 Q_UNUSED(event);
51 QPainter p(this);
52 p.setRenderHint(QPainter::Antialiasing, true);
53 p.fillRect(rect(), QColor(9, 13, 19));
54
55 QFont titleFont = font();
56 titleFont.setBold(true);
57 p.setFont(titleFont);
58 p.setPen(QColor(230, 238, 246));
59 p.drawText(QRect(12, 6, width() - 24, 25), Qt::AlignLeft | Qt::AlignVCenter,
60 QStringLiteral("Klein angular reference — stationary plane-wave T(theta) at fixed |p|"));
61
62 if (!scan_.valid || scan_.points.empty()) {
63 p.setFont(font());
64 p.setPen(QColor(145, 162, 178));
65 p.drawText(QRect(20, 45, width() - 40, height() - 65),
66 Qt::AlignCenter | Qt::TextWordWrap,
67 QStringLiteral("Load the Klein Transmission vs Incidence Angle preset."));
68 return;
69 }
70
71 const int left = 62, right = 22, top = 46, bottom = 54;
72 QRect plot(left, top, std::max(120, width() - left - right),
73 std::max(120, height() - top - bottom));
74 p.setBrush(QColor(5, 9, 15));
75 p.setPen(QColor(54, 72, 88));
76 p.drawRect(plot);
77
78 const double amin = scan_.minimumAngleDegrees;
79 const double amax = scan_.maximumAngleDegrees;
80 const auto xOf = [&](double angle) {
81 return plot.left() + (angle - amin) / std::max(1.0e-12, amax - amin) * plot.width();
82 };
83 const auto yOf = [&](double transmission) {
84 return plot.bottom() - std::max(0.0, std::min(1.0, transmission)) * plot.height();
85 };
86
87 p.setFont(font());
88 p.setPen(QColor(77, 94, 109));
89 for (int i = 0; i <= 5; ++i) {
90 const double t = static_cast<double>(i) / 5.0;
91 const int y = static_cast<int>(std::lround(yOf(t)));
92 p.drawLine(plot.left(), y, plot.right(), y);
93 p.setPen(QColor(170, 184, 197));
94 p.drawText(QRect(6, y - 9, 50, 18), Qt::AlignRight | Qt::AlignVCenter,
95 QString::number(t, 'f', 1));
96 p.setPen(QColor(77, 94, 109));
97 }
98
99 for (int a = 0; a <= 70; a += 10) {
100 if (a < amin || a > amax) continue;
101 const int x = static_cast<int>(std::lround(xOf(static_cast<double>(a))));
102 p.drawLine(x, plot.top(), x, plot.bottom());
103 p.setPen(QColor(170, 184, 197));
104 p.drawText(QRect(x - 24, plot.bottom() + 5, 48, 20), Qt::AlignHCenter | Qt::AlignTop,
105 QStringLiteral("%1 deg").arg(a));
106 p.setPen(QColor(77, 94, 109));
107 }
108
109 QPainterPath path;
110 bool first = true;
111 for (const qpe::QuantumKleinAnglePoint2D &point : scan_.points) {
112 if (!point.valid) { first = true; continue; }
113 const QPointF q(xOf(point.angleDegrees), yOf(point.transmission));
114 if (first) { path.moveTo(q); first = false; }
115 else path.lineTo(q);
116 }
117 p.setPen(QPen(QColor(100, 220, 255), 2.4));
118 p.setBrush(Qt::NoBrush);
119 p.drawPath(path);
120
121 if (currentAngleDegrees_ >= amin && currentAngleDegrees_ <= amax) {
122 // Interpolate the displayed reference curve at the current angle.
123 double referenceT = scan_.points.front().transmission;
124 for (std::size_t i = 1; i < scan_.points.size(); ++i) {
125 const auto &a0 = scan_.points[i - 1u];
126 const auto &a1 = scan_.points[i];
127 if (currentAngleDegrees_ <= a1.angleDegrees) {
128 const double f = (currentAngleDegrees_ - a0.angleDegrees) /
129 std::max(1.0e-12, a1.angleDegrees - a0.angleDegrees);
130 referenceT = a0.transmission + f * (a1.transmission - a0.transmission);
131 break;
132 }
133 }
134 const int x = static_cast<int>(std::lround(xOf(currentAngleDegrees_)));
135 p.setPen(QPen(QColor(255, 205, 95), 1.5, Qt::DashLine));
136 p.drawLine(x, plot.top(), x, plot.bottom());
137 p.setBrush(QColor(255, 205, 95));
138 p.setPen(Qt::NoPen);
139 p.drawEllipse(QPointF(xOf(currentAngleDegrees_), yOf(referenceT)), 5.0, 5.0);
140
141 if (packetTransmission_ >= 0.0 && packetTransmission_ <= 1.05) {
142 p.setBrush(QColor(255, 126, 126));
143 p.drawEllipse(QPointF(xOf(currentAngleDegrees_), yOf(packetTransmission_)), 5.0, 5.0);
144 }
145 }
146
147 p.setPen(QColor(188, 202, 214));
148 p.setFont(font());
149 p.drawText(QRect(plot.left(), plot.bottom() + 27, plot.width(), 22), Qt::AlignCenter,
150 QStringLiteral("incidence angle theta | cyan: plane-wave reference yellow: current reference red: time-domain packet max P_right"));
151
152 p.setPen(QColor(235, 240, 245));
153 p.drawText(QRect(plot.left() + 8, plot.top() + 6, plot.width() - 16, 42),
154 Qt::AlignLeft | Qt::AlignTop,
155 QStringLiteral("|p|=%1 E=%2 V0=%3 width=%4 scan=%5..%6 deg")
156 .arg(scan_.momentumMagnitude, 0, 'f', 4)
157 .arg(scan_.incidentEnergy, 0, 'f', 4)
158 .arg(scan_.barrierHeight, 0, 'f', 3)
159 .arg(scan_.barrierWidth, 0, 'f', 3)
160 .arg(scan_.minimumAngleDegrees, 0, 'f', 0)
161 .arg(scan_.maximumAngleDegrees, 0, 'f', 0));
162}
void setData(const qpe::QuantumKleinAngleScan2DResult &scan, double currentAngleDegrees, double packetTransmission=-1.0)
Sets data.
qpe::QuantumKleinAngleScan2DResult scan_
QSize minimumSizeHint() const override
Performs minimum size hint.
QuantumKleinAngleScanPlotWidget(QWidget *parent=nullptr)
Performs quantum klein angle scan plot widget.
void paintEvent(QPaintEvent *event) override
Paints event.
Declares the quantumkleinanglescanplotwidget visualization component used by QPE.
Data structure used by the Quantum Klein Angle Point2D component.
Data record containing Quantum Klein Angle Scan2D Result.
std::vector< QuantumKleinAnglePoint2D > points