66 QPainter painter(
this);
67 painter.setRenderHint(QPainter::Antialiasing,
true);
68 painter.setRenderHint(QPainter::TextAntialiasing,
true);
69 painter.fillRect(rect(), QColor(15, 18, 23));
71 const QRectF plotRect(58.0, 28.0,
72 std::max(10.0, width() - 78.0),
73 std::max(10.0, height() - 66.0));
74 painter.setPen(QPen(QColor(78, 86, 96), 1.0));
75 for (
int i = 0; i <= 4; ++i) {
76 const double u =
static_cast<double>(i) / 4.0;
77 painter.drawLine(QPointF(plotRect.left() + u * plotRect.width(), plotRect.top()),
78 QPointF(plotRect.left() + u * plotRect.width(), plotRect.bottom()));
79 painter.drawLine(QPointF(plotRect.left(), plotRect.top() + u * plotRect.height()),
80 QPointF(plotRect.right(), plotRect.top() + u * plotRect.height()));
82 painter.setPen(QPen(QColor(170, 180, 190), 1.0));
83 painter.drawRect(plotRect);
87 double energyMin = std::numeric_limits<double>::infinity();
88 double energyMax = -std::numeric_limits<double>::infinity();
90 tMax = std::max(tMax, sample.time);
91 if (std::isfinite(sample.meanX)) xMaxAbs = std::max(xMaxAbs, std::abs(sample.meanX));
92 if (std::isfinite(sample.totalEnergy)) {
93 energyMin = std::min(energyMin, sample.totalEnergy);
94 energyMax = std::max(energyMax, sample.totalEnergy);
98 if (!(energyMax > energyMin)) {
99 if (!std::isfinite(energyMin)) { energyMin = 0.0; energyMax = 1.0; }
100 else { energyMin -= 0.5; energyMax += 0.5; }
102 const double ePad = 0.10 * std::max(1.0e-6, energyMax - energyMin);
106 const auto mapX = [plotRect, tMax](
double t) {
107 return plotRect.left() + t / tMax * plotRect.width();
109 const auto mapPosition = [plotRect, xMaxAbs](
double v) {
110 return plotRect.center().y() - v / xMaxAbs * 0.5 * plotRect.height();
112 const auto mapEnergy = [plotRect, energyMin, energyMax](
double v) {
113 return plotRect.bottom() - (v - energyMin) / (energyMax - energyMin) * plotRect.height();
116 painter.setPen(QPen(QColor(125, 132, 142), 1.0, Qt::DashLine));
117 painter.drawLine(QPointF(plotRect.left(), mapPosition(0.0)),
118 QPointF(plotRect.right(), mapPosition(0.0)));
120 QPainterPath drivePath;
121 const int samples = 300;
122 for (
int i = 0; i <= samples; ++i) {
123 const double t = tMax *
static_cast<double>(i) / samples;
125 const QPointF p(mapX(t), mapPosition(center));
126 if (i == 0) drivePath.moveTo(p);
else drivePath.lineTo(p);
128 painter.setPen(QPen(QColor(175, 125, 255), 1.4, Qt::DashLine));
129 painter.drawPath(drivePath);
131 QPainterPath meanPath;
132 QPainterPath energyPath;
135 const QPointF pm(mapX(sample.time), mapPosition(sample.meanX));
136 const QPointF pe(mapX(sample.time), mapEnergy(sample.totalEnergy));
139 energyPath.moveTo(pe);
143 energyPath.lineTo(pe);
147 painter.setPen(QPen(QColor(100, 220, 255), 2.2));
148 painter.drawPath(meanPath);
149 painter.setPen(QPen(QColor(255, 170, 105), 1.7));
150 painter.drawPath(energyPath);
152 painter.setPen(QColor(190, 195, 205));
153 painter.drawText(plotRect, Qt::AlignCenter,
154 QStringLiteral(
"Load a Driven Harmonic Trap and press Play"));
157 painter.setPen(QColor(210, 215, 222));
158 painter.drawText(QRectF(plotRect.left(), 2.0, plotRect.width(), 22.0),
160 QStringLiteral(
"Periodic drive: packet centre, trap centre and total energy"));
161 painter.setPen(QColor(100, 220, 255));
162 painter.drawText(QRectF(plotRect.left() + 8.0, plotRect.top() + 5.0, 90.0, 18.0),
163 Qt::AlignLeft, QStringLiteral(
"<x>"));
164 painter.setPen(QColor(175, 125, 255));
165 painter.drawText(QRectF(plotRect.left() + 52.0, plotRect.top() + 5.0, 120.0, 18.0),
166 Qt::AlignLeft, QStringLiteral(
"trap centre"));
167 painter.setPen(QColor(255, 170, 105));
168 painter.drawText(QRectF(plotRect.left() + 145.0, plotRect.top() + 5.0, 90.0, 18.0),
169 Qt::AlignLeft, QStringLiteral(
"<H>"));
170 painter.setPen(QColor(160, 168, 178));
171 painter.drawText(QRectF(plotRect.left(), plotRect.bottom() + 5.0,
172 plotRect.width(), 22.0),
173 Qt::AlignCenter, QStringLiteral(
"simulation time"));