Merge branch 'master' into trace_math

This commit is contained in:
Jan Käberich 2020-11-26 21:02:37 +01:00
commit 692bb85b5d
5 changed files with 70 additions and 27 deletions

View File

@ -6,6 +6,7 @@
#include <QKeyEvent>
#include <QDebug>
#include <QTimer>
#include <cmath>
SIUnitEdit::SIUnitEdit(QString unit, QString prefixes, int precision, QWidget *parent)
: QLineEdit(parent)
@ -88,6 +89,30 @@ bool SIUnitEdit::eventFilter(QObject *, QEvent *event)
// online found clumsy way to select all text when clicked!?!
// just selectAll() alone does _not_ work!
QTimer::singleShot(0, this, &SIUnitEdit::continueEditing);
} else if(event->type() == QEvent::Wheel) {
if(_value == 0.0) {
// can't figure out step size with zero value
return false;
}
auto wheel = static_cast<QWheelEvent*>(event);
// most mousewheel have 15 degree increments, the reported delta is in 1/8th degree -> 120
auto increment = wheel->angleDelta().y() / 120.0;
// round toward bigger step in case of special higher resolution mousewheel
unsigned int steps = abs(increment > 0 ? ceil(increment) : floor(increment));
int sign = increment > 0 ? 1 : -1;
// figure out step increment
auto newVal = _value;
while(steps > 0) {
// do update in multiple steps because the step size could change inbetween
constexpr int nthDigit = 3;
auto step_size = pow(10, floor(log10(abs(newVal))) - nthDigit + 1);
newVal += step_size * sign;
steps--;
}
setValue(newVal);
continueEditing();
setFocus();
return true;
}
return false;
}

View File

@ -173,6 +173,11 @@ void Trace::removeMarker(TraceMarker *m)
void Trace::updateTimeDomainData()
{
if(_data.size() < 2) {
// can't compute anything
timeDomain.clear();
return;
}
// using namespace std::chrono;
// auto starttime = duration_cast< milliseconds >(
// system_clock::now().time_since_epoch()
@ -228,7 +233,7 @@ void Trace::updateTimeDomainData()
t.impedance = numeric_limits<double>::quiet_NaN();
}
last_step += t.impulseResponse;
timeDomain.push_back(t);
timeDomain[i] = t;
}
// auto duration = duration_cast< milliseconds >(
// system_clock::now().time_since_epoch()

View File

@ -227,6 +227,7 @@ void TracePlot::dropEvent(QDropEvent *event)
}
dropPending = false;
dropTrace = nullptr;
replot();
}
void TracePlot::dragLeaveEvent(QDragLeaveEvent *event)
@ -234,7 +235,7 @@ void TracePlot::dragLeaveEvent(QDragLeaveEvent *event)
Q_UNUSED(event)
dropPending = false;
dropTrace = nullptr;
triggerReplot();
replot();
}
std::set<TracePlot *> TracePlot::getPlots()

View File

@ -355,8 +355,8 @@ void TraceXYPlot::draw(QPainter &p)
p.setPen(pen);
auto nPoints = numTraceSamples(t);
for(unsigned int j=1;j<nPoints;j++) {
auto last = transformY(t, j-1, YAxis[i].type);
auto now = transformY(t, j, YAxis[i].type);
auto last = traceToCoordinate(t, j-1, YAxis[i].type);
auto now = traceToCoordinate(t, j, YAxis[i].type);
if(isnan(last.y()) || isnan(now.y()) || isinf(last.y()) || isinf(now.y())) {
continue;
@ -393,7 +393,7 @@ void TraceXYPlot::draw(QPainter &p)
if (xPosition < XAxis.rangeMin || xPosition > XAxis.rangeMax) {
continue;
}
QPointF markerPoint = QPointF(xPosition, transformY(m->getData(), YAxis[i].type));
QPointF markerPoint = QPointF(xPosition, traceToCoordinate(m->getData(), YAxis[i].type));
auto point = plotValueToPixel(markerPoint, i);
if(!plotRect.contains(point)) {
// out of screen
@ -451,7 +451,12 @@ void TraceXYPlot::updateAxisTicks()
{
auto createEvenlySpacedTicks = [](vector<double>& ticks, double start, double stop, double step) {
ticks.clear();
for(double tick = start; tick - stop < numeric_limits<double>::epsilon() ;tick+= step) {
if(start > stop) {
swap(start, stop);
}
step = abs(step);
constexpr unsigned int maxTicks = 100;
for(double tick = start; tick - stop < numeric_limits<double>::epsilon() && ticks.size() <= maxTicks;tick+= step) {
ticks.push_back(tick);
}
};
@ -494,6 +499,10 @@ void TraceXYPlot::updateAxisTicks()
|| tracesAxis[1].find(t.first) != tracesAxis[1].end());
auto trace = t.first;
if(enabled && trace->isVisible()) {
if(!numTraceSamples(trace)) {
// empty trace, do not use for automatic axis calculation
continue;
}
// this trace is currently displayed
double trace_min = std::numeric_limits<double>::max();
double trace_max = std::numeric_limits<double>::lowest();
@ -520,14 +529,13 @@ void TraceXYPlot::updateAxisTicks()
}
}
}
if(min >= max) {
// still at initial values, no traces are active, leave axis unchanged
return;
}
if(min < max) {
// found min/max values
XAxis.rangeMin = min;
XAxis.rangeMax = max;
XAxis.rangeDiv = createAutomaticTicks(XAxis.ticks, min, max, 8);
}
}
for(int i=0;i<2;i++) {
if(!YAxis[i].autorange) {
@ -539,7 +547,12 @@ void TraceXYPlot::updateAxisTicks()
for(auto t : tracesAxis[i]) {
unsigned int samples = numTraceSamples(t);
for(unsigned int j=0;j<samples;j++) {
auto point = transformY(t, j, YAxis[i].type);
auto point = traceToCoordinate(t, j, YAxis[i].type);
if(point.x() < XAxis.rangeMin || point.x() > XAxis.rangeMax) {
// this point is not in the displayed X range, skip for auto Y range calculation
continue;
}
if(point.y() > max) {
max = point.y();
@ -557,7 +570,6 @@ void TraceXYPlot::updateAxisTicks()
YAxis[i].rangeDiv = createAutomaticTicks(YAxis[i].ticks, min, max, 8);
}
}
triggerReplot();
}
QString TraceXYPlot::AxisTypeToName(TraceXYPlot::YAxisType type)
@ -620,7 +632,7 @@ bool TraceXYPlot::supported(Trace *t, TraceXYPlot::YAxisType type)
return true;
}
double TraceXYPlot::transformY(std::complex<double> data, TraceXYPlot::YAxisType type)
double TraceXYPlot::traceToCoordinate(std::complex<double> data, TraceXYPlot::YAxisType type)
{
switch(type) {
case YAxisType::Magnitude:
@ -646,7 +658,7 @@ double TraceXYPlot::transformY(std::complex<double> data, TraceXYPlot::YAxisType
return numeric_limits<double>::quiet_NaN();
}
QPointF TraceXYPlot::transformY(Trace *t, unsigned int sample, TraceXYPlot::YAxisType type)
QPointF TraceXYPlot::traceToCoordinate(Trace *t, unsigned int sample, TraceXYPlot::YAxisType type)
{
QPointF ret = QPointF(numeric_limits<double>::quiet_NaN(), numeric_limits<double>::quiet_NaN());
switch(type) {
@ -654,8 +666,8 @@ QPointF TraceXYPlot::transformY(Trace *t, unsigned int sample, TraceXYPlot::YAxi
case YAxisType::Phase:
case YAxisType::VSWR: {
auto d = t->sample(sample);
ret.setY(transformY(d.y, type));
ret.setX(d.x);
ret.setY(traceToCoordinate(d.S, type));
ret.setX(d.frequency);
}
break;
case YAxisType::Impulse:
@ -702,12 +714,12 @@ unsigned int TraceXYPlot::numTraceSamples(Trace *t)
QPoint TraceXYPlot::dataToPixel(Trace::Data d)
{
if(d.x < XAxis.rangeMin || d.x > XAxis.rangeMax) {
if(d.frequency < XAxis.rangeMin || d.frequency > XAxis.rangeMax) {
return QPoint();
}
auto y = transformY(d.y, YAxis[0].type);
auto y = traceToCoordinate(d.S, YAxis[0].type);
QPoint p;
p.setX(Util::Scale<double>(d.x, XAxis.rangeMin, XAxis.rangeMax, plotAreaLeft, plotAreaLeft + plotAreaWidth));
p.setX(Util::Scale<double>(d.frequency, XAxis.rangeMin, XAxis.rangeMax, plotAreaLeft, plotAreaLeft + plotAreaWidth));
p.setY(Util::Scale<double>(y, YAxis[0].rangeMin, YAxis[0].rangeMax, plotAreaBottom, 0));
return p;
}
@ -736,7 +748,7 @@ QPoint TraceXYPlot::markerToPixel(TraceMarker *m)
return ret;
}
QPointF plotPoint;
plotPoint.setY(transformY(m->getData(), YAxis[0].type));
plotPoint.setY(traceToCoordinate(m->getData(), YAxis[0].type));
if(m->isTimeDomain()) {
auto timedata = m->getTimeData();
if(XAxis.type == XAxisType::Distance) {
@ -760,13 +772,13 @@ double TraceXYPlot::nearestTracePoint(Trace *t, QPoint pixel)
double closestXpos = 0;
auto samples = numTraceSamples(t);
for(unsigned int i=0;i<samples;i++) {
auto point = transformY(t, i, YAxis[0].type);
auto point = traceToCoordinate(t, i, YAxis[0].type);
if(isnan(point.x()) || isnan(point.y())) {
continue;
}
auto plotPoint = plotValueToPixel(point, 0);
auto diff = plotPoint - pixel;
unsigned int distance = diff.x() * diff.x() + diff.y() * diff.y();
QPointF diff = plotPoint - pixel;
auto distance = diff.x() * diff.x() + diff.y() * diff.y();
if(distance < closestDistance) {
closestDistance = distance;
closestXpos = point.x();

View File

@ -58,8 +58,8 @@ private:
QString AxisTypeToName(YAxisType type);
void enableTraceAxis(Trace *t, int axis, bool enabled);
bool supported(Trace *t, YAxisType type);
double transformY(std::complex<double> data, YAxisType type);
QPointF transformY(Trace *t, unsigned int sample, YAxisType type);
double traceToCoordinate(std::complex<double> data, YAxisType type);
QPointF traceToCoordinate(Trace *t, unsigned int sample, YAxisType type);
unsigned int numTraceSamples(Trace *t);
QPoint dataToPixel(Trace::Data d);
QPoint plotValueToPixel(QPointF plotValue, int Yaxis);