pan/zoom for smith chart and polar plot
This commit is contained in:
parent
7889676ac7
commit
dfd1abeea5
@ -124,24 +124,24 @@
|
|||||||
<widget class="SIUnitEdit" name="zoomFactor"/>
|
<widget class="SIUnitEdit" name="zoomFactor"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p>|Γ| at edge:</p></body></html></string>
|
<string>Offset X axis:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
<widget class="SIUnitEdit" name="zoomReflection"/>
|
<widget class="SIUnitEdit" name="offsetXaxis"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Offset real axis:</string>
|
<string>Offset Y axis:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="SIUnitEdit" name="offsetRealAxis"/>
|
<widget class="SIUnitEdit" name="offsetYaxis"/>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>976</width>
|
<width>974</width>
|
||||||
<height>460</height>
|
<height>491</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -155,13 +155,23 @@
|
|||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_6">
|
<widget class="QLabel" name="label_6">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Offset real axis</string>
|
<string>Offset real axis:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="SIUnitEdit" name="offsetRealAxis"/>
|
<widget class="SIUnitEdit" name="offsetRealAxis"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_9">
|
||||||
|
<property name="text">
|
||||||
|
<string>Offset imag axis:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="SIUnitEdit" name="offsetImagAxis"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -16,7 +16,7 @@ TracePolar::TracePolar(TraceModel &model, QWidget *parent)
|
|||||||
fmin = 0;
|
fmin = 0;
|
||||||
fmax = 6000000000;
|
fmax = 6000000000;
|
||||||
edgeReflection = 1.0;
|
edgeReflection = 1.0;
|
||||||
dx = 0;
|
offset = QPointF(0.0, 0.0);
|
||||||
initializeTraceInfo();
|
initializeTraceInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,7 +26,8 @@ nlohmann::json TracePolar::toJSON()
|
|||||||
j["limit_to_span"] = limitToSpan;
|
j["limit_to_span"] = limitToSpan;
|
||||||
j["limit_to_edge"] = limitToEdge;
|
j["limit_to_edge"] = limitToEdge;
|
||||||
j["edge_reflection"] = edgeReflection;
|
j["edge_reflection"] = edgeReflection;
|
||||||
j["offset_axis_x"] = dx;
|
j["offset_axis_x"] = offset.x();
|
||||||
|
j["offset_axis_y"] = offset.y();
|
||||||
j["frequency_override"] = manualFrequencyRange;
|
j["frequency_override"] = manualFrequencyRange;
|
||||||
j["override_min"] = fmin;
|
j["override_min"] = fmin;
|
||||||
j["override_max"] = fmax;
|
j["override_max"] = fmax;
|
||||||
@ -48,7 +49,7 @@ void TracePolar::fromJSON(nlohmann::json j)
|
|||||||
manualFrequencyRange = j.value("frequency_override", false);
|
manualFrequencyRange = j.value("frequency_override", false);
|
||||||
fmin = j.value("override_min", 0.0);
|
fmin = j.value("override_min", 0.0);
|
||||||
fmax = j.value("override_max", 6000000000.0);
|
fmax = j.value("override_max", 6000000000.0);
|
||||||
dx = j.value("offset_axis_x", 0.0);
|
offset = QPointF(j.value("offset_axis_x", 0.0), j.value("offset_axis_y", 0.0));
|
||||||
for(unsigned int hash : j["traces"]) {
|
for(unsigned int hash : j["traces"]) {
|
||||||
// attempt to find the traces with this hash
|
// attempt to find the traces with this hash
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -65,21 +66,59 @@ void TracePolar::fromJSON(nlohmann::json j)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TracePolar::wheelEvent(QWheelEvent *event)
|
void TracePolar::move(const QPoint &vect)
|
||||||
{
|
{
|
||||||
// most mousewheel have 15 degree increments, the reported delta is in 1/8th degree -> 120
|
Trace::Data center;
|
||||||
auto increment = event->angleDelta().y() / 120.0;
|
center.y = 0.0;
|
||||||
// round toward bigger step in case of special higher resolution mousewheel
|
center.x = 0.0;
|
||||||
int steps = increment > 0 ? ceil(increment) : floor(increment);
|
auto shift = pixelToData(dataToPixel(center) + vect);
|
||||||
|
offset.rx() += shift.real();
|
||||||
|
offset.ry() += shift.imag();
|
||||||
|
replot();
|
||||||
|
}
|
||||||
|
|
||||||
constexpr double zoomfactor = 1.1;
|
void TracePolar::zoom(const QPoint ¢er, double factor, bool horizontally, bool vertically)
|
||||||
auto zoom = pow(zoomfactor, steps);
|
{
|
||||||
edgeReflection /= zoom;
|
Q_UNUSED(horizontally);
|
||||||
|
Q_UNUSED(vertically);
|
||||||
|
auto pos = pixelToData(center);
|
||||||
|
auto shift = QPointF(pos.real(), pos.imag());
|
||||||
|
offset -= shift;
|
||||||
|
edgeReflection *= factor;
|
||||||
|
offset += shift * factor;
|
||||||
|
replot();
|
||||||
|
}
|
||||||
|
|
||||||
auto incrementX = event->angleDelta().x() / 120.0;
|
void TracePolar::setAuto(bool horizontally, bool vertically)
|
||||||
dx += incrementX/10;
|
{
|
||||||
|
Q_UNUSED(horizontally);
|
||||||
|
Q_UNUSED(vertically);
|
||||||
|
edgeReflection = 1.0;
|
||||||
|
offset = QPointF(0.0, 0.0);
|
||||||
|
replot();
|
||||||
|
}
|
||||||
|
|
||||||
triggerReplot();
|
//void TracePolar::wheelEvent(QWheelEvent *event)
|
||||||
|
//{
|
||||||
|
// // most mousewheel have 15 degree increments, the reported delta is in 1/8th degree -> 120
|
||||||
|
// auto increment = event->angleDelta().y() / 120.0;
|
||||||
|
// // round toward bigger step in case of special higher resolution mousewheel
|
||||||
|
// int steps = increment > 0 ? ceil(increment) : floor(increment);
|
||||||
|
|
||||||
|
// constexpr double zoomfactor = 1.1;
|
||||||
|
// auto zoom = pow(zoomfactor, steps);
|
||||||
|
// edgeReflection /= zoom;
|
||||||
|
|
||||||
|
// auto incrementX = event->angleDelta().x() / 120.0;
|
||||||
|
//// dx += incrementX/10;
|
||||||
|
|
||||||
|
// triggerReplot();
|
||||||
|
//}
|
||||||
|
|
||||||
|
bool TracePolar::positionWithinGraphArea(const QPoint &p)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint TracePolar::dataToPixel(std::complex<double> d)
|
QPoint TracePolar::dataToPixel(std::complex<double> d)
|
||||||
@ -92,19 +131,24 @@ QPoint TracePolar:: dataToPixel(Trace::Data d)
|
|||||||
return dataToPixel(d.y);
|
return dataToPixel(d.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::complex<double> TracePolar::dataAddDx(std::complex<double> d)
|
std::complex<double> TracePolar::dataAddOffset(std::complex<double> d)
|
||||||
{
|
{
|
||||||
auto dataShift = complex<double>(dx, 0);
|
auto dataShift = complex<double>(offset.x(), offset.y());
|
||||||
d = d + dataShift;
|
d = d + dataShift;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
Trace::Data TracePolar::dataAddDx(Trace::Data d)
|
Trace::Data TracePolar::dataAddOffset(Trace::Data d)
|
||||||
{
|
{
|
||||||
d.y = dataAddDx(d.y);
|
d.y = dataAddOffset(d.y);
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPoint TracePolar::dataToPixel(QPointF d)
|
||||||
|
{
|
||||||
|
return dataToPixel(complex<double>(d.x(), d.y()));
|
||||||
|
}
|
||||||
|
|
||||||
std::complex<double> TracePolar::pixelToData(QPoint p)
|
std::complex<double> TracePolar::pixelToData(QPoint p)
|
||||||
{
|
{
|
||||||
auto data = transform.inverted().map(QPointF(p));
|
auto data = transform.inverted().map(QPointF(p));
|
||||||
@ -117,7 +161,7 @@ QPoint TracePolar::markerToPixel(Marker *m)
|
|||||||
// if(!m->isTimeDomain()) {
|
// if(!m->isTimeDomain()) {
|
||||||
if(m->getPosition() >= sweep_fmin && m->getPosition() <= sweep_fmax) {
|
if(m->getPosition() >= sweep_fmin && m->getPosition() <= sweep_fmax) {
|
||||||
auto d = m->getData();
|
auto d = m->getData();
|
||||||
d = dataAddDx(d);
|
d = dataAddOffset(d);
|
||||||
ret = dataToPixel(d);
|
ret = dataToPixel(d);
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
@ -132,7 +176,7 @@ double TracePolar::nearestTracePoint(Trace *t, QPoint pixel, double *distance)
|
|||||||
auto samples = t->size();
|
auto samples = t->size();
|
||||||
for(unsigned int i=0;i<samples;i++) {
|
for(unsigned int i=0;i<samples;i++) {
|
||||||
auto data = t->sample(i);
|
auto data = t->sample(i);
|
||||||
data = dataAddDx(data);
|
data = dataAddOffset(data);
|
||||||
auto plotPoint = dataToPixel(data);
|
auto plotPoint = dataToPixel(data);
|
||||||
if (plotPoint.isNull()) {
|
if (plotPoint.isNull()) {
|
||||||
// destination point outside of currently displayed range
|
// destination point outside of currently displayed range
|
||||||
@ -149,8 +193,8 @@ double TracePolar::nearestTracePoint(Trace *t, QPoint pixel, double *distance)
|
|||||||
closestDistance = sqrt(closestDistance);
|
closestDistance = sqrt(closestDistance);
|
||||||
|
|
||||||
if(closestIndex > 0) {
|
if(closestIndex > 0) {
|
||||||
auto l1 = dataToPixel(dataAddDx(t->sample(closestIndex-1)));
|
auto l1 = dataToPixel(dataAddOffset(t->sample(closestIndex-1)));
|
||||||
auto l2 = dataToPixel(dataAddDx(t->sample(closestIndex)));
|
auto l2 = dataToPixel(dataAddOffset(t->sample(closestIndex)));
|
||||||
double ratio;
|
double ratio;
|
||||||
auto distance = Util::distanceToLine(pixel, l1, l2, nullptr, &ratio);
|
auto distance = Util::distanceToLine(pixel, l1, l2, nullptr, &ratio);
|
||||||
if(distance < closestDistance) {
|
if(distance < closestDistance) {
|
||||||
@ -159,8 +203,8 @@ double TracePolar::nearestTracePoint(Trace *t, QPoint pixel, double *distance)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(closestIndex < t->size() - 1) {
|
if(closestIndex < t->size() - 1) {
|
||||||
auto l1 = dataToPixel(dataAddDx(t->sample(closestIndex)));
|
auto l1 = dataToPixel(dataAddOffset(t->sample(closestIndex)));
|
||||||
auto l2 = dataToPixel(dataAddDx(t->sample(closestIndex+1)));
|
auto l2 = dataToPixel(dataAddOffset(t->sample(closestIndex+1)));
|
||||||
double ratio;
|
double ratio;
|
||||||
auto distance = Util::distanceToLine(pixel, l1, l2, nullptr, &ratio);
|
auto distance = Util::distanceToLine(pixel, l1, l2, nullptr, &ratio);
|
||||||
if(distance < closestDistance) {
|
if(distance < closestDistance) {
|
||||||
|
@ -21,7 +21,11 @@ public:
|
|||||||
virtual nlohmann::json toJSON() override; // derived classes must call TracePolar::joJSON before doing anything
|
virtual nlohmann::json toJSON() override; // derived classes must call TracePolar::joJSON before doing anything
|
||||||
virtual void fromJSON(nlohmann::json j) override; // derived classes must call TracePolar::joJSON before doing anything
|
virtual void fromJSON(nlohmann::json j) override; // derived classes must call TracePolar::joJSON before doing anything
|
||||||
|
|
||||||
void wheelEvent(QWheelEvent *event) override;
|
virtual void move(const QPoint &vect) override;
|
||||||
|
virtual void zoom(const QPoint ¢er, double factor, bool horizontally, bool vertically) override;
|
||||||
|
virtual void setAuto(bool horizontally, bool vertically) override;
|
||||||
|
|
||||||
|
// void wheelEvent(QWheelEvent *event) override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void axisSetupDialog() {}
|
virtual void axisSetupDialog() {}
|
||||||
@ -29,9 +33,11 @@ public slots:
|
|||||||
protected:
|
protected:
|
||||||
static constexpr double polarCoordMax = 4096;
|
static constexpr double polarCoordMax = 4096;
|
||||||
|
|
||||||
virtual std::complex<double> dataAddDx(std::complex<double> d);
|
virtual bool positionWithinGraphArea(const QPoint &p) override;
|
||||||
virtual Trace::Data dataAddDx(Trace::Data d);
|
virtual std::complex<double> dataAddOffset(std::complex<double> d);
|
||||||
|
virtual Trace::Data dataAddOffset(Trace::Data d);
|
||||||
|
|
||||||
|
QPoint dataToPixel(QPointF d);
|
||||||
QPoint dataToPixel(std::complex<double> d);
|
QPoint dataToPixel(std::complex<double> d);
|
||||||
QPoint dataToPixel(Trace::Data d);
|
QPoint dataToPixel(Trace::Data d);
|
||||||
std::complex<double> pixelToData(QPoint p);
|
std::complex<double> pixelToData(QPoint p);
|
||||||
@ -54,7 +60,7 @@ protected:
|
|||||||
double fmin, fmax; // frequency range when manual range is selected
|
double fmin, fmax; // frequency range when manual range is selected
|
||||||
|
|
||||||
double edgeReflection; // magnitude of reflection coefficient at the edge of the polar chart (zoom factor)
|
double edgeReflection; // magnitude of reflection coefficient at the edge of the polar chart (zoom factor)
|
||||||
double dx;
|
QPointF offset;
|
||||||
QTransform transform;
|
QTransform transform;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,12 +48,12 @@ void TracePolarChart::axisSetupDialog()
|
|||||||
ui->displayFreqOverride->setChecked(manualFrequencyRange);
|
ui->displayFreqOverride->setChecked(manualFrequencyRange);
|
||||||
emit ui->displayFreqOverride->toggled(manualFrequencyRange);
|
emit ui->displayFreqOverride->toggled(manualFrequencyRange);
|
||||||
|
|
||||||
ui->zoomReflection->setPrecision(3);
|
|
||||||
ui->zoomFactor->setPrecision(3);
|
ui->zoomFactor->setPrecision(3);
|
||||||
ui->offsetRealAxis->setPrecision(3);
|
ui->offsetXaxis->setPrecision(3);
|
||||||
ui->zoomReflection->setValue(edgeReflection);
|
ui->offsetYaxis->setPrecision(3);
|
||||||
ui->zoomFactor->setValue(1.0/edgeReflection);
|
ui->zoomFactor->setValue(1.0/edgeReflection);
|
||||||
ui->offsetRealAxis->setValue(dx);
|
ui->offsetXaxis->setValue(offset.x());
|
||||||
|
ui->offsetYaxis->setValue(offset.y());
|
||||||
|
|
||||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
||||||
limitToSpan = ui->displayModeFreq->currentIndex() == 1;
|
limitToSpan = ui->displayModeFreq->currentIndex() == 1;
|
||||||
@ -65,14 +65,12 @@ void TracePolarChart::axisSetupDialog()
|
|||||||
});
|
});
|
||||||
connect(ui->zoomFactor, &SIUnitEdit::valueChanged, [=](){
|
connect(ui->zoomFactor, &SIUnitEdit::valueChanged, [=](){
|
||||||
edgeReflection = 1.0 / ui->zoomFactor->value();
|
edgeReflection = 1.0 / ui->zoomFactor->value();
|
||||||
ui->zoomReflection->setValueQuiet(edgeReflection);
|
|
||||||
});
|
});
|
||||||
connect(ui->zoomReflection, &SIUnitEdit::valueChanged, [=](){
|
connect(ui->offsetXaxis, &SIUnitEdit::valueChanged, [=](){
|
||||||
edgeReflection = ui->zoomReflection->value();
|
offset = QPointF(ui->offsetXaxis->value(), offset.y());
|
||||||
ui->zoomFactor->setValueQuiet(1.0 / edgeReflection);
|
|
||||||
});
|
});
|
||||||
connect(ui->offsetRealAxis, &SIUnitEdit::valueChanged, [=](){
|
connect(ui->offsetXaxis, &SIUnitEdit::valueChanged, [=](){
|
||||||
dx = ui->offsetRealAxis->value();
|
offset = QPointF(offset.x(), ui->offsetXaxis->value());
|
||||||
});
|
});
|
||||||
if(AppWindow::showGUI()) {
|
if(AppWindow::showGUI()) {
|
||||||
dialog->show();
|
dialog->show();
|
||||||
@ -123,20 +121,20 @@ void TracePolarChart::draw(QPainter &p) {
|
|||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
for(int i=1;i<Circles;i++) {
|
for(int i=1;i<Circles;i++) {
|
||||||
auto radius = (double) i / Circles;
|
auto radius = (double) i / Circles;
|
||||||
drawArc(PolarArc(QPointF(0.0 + dx,0), radius, 0, 2*M_PI));
|
drawArc(PolarArc(offset, radius, 0, 2*M_PI));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto constraintLineToCircle = [&](PolarArc cir) { // PolarArc
|
auto constraintLineToCircle = [&](PolarArc cir) { // PolarArc
|
||||||
if ( (cir.spanAngle == 90 )&& (dx != 0.0)) {
|
if ( (cir.spanAngle == 90 )&& (offset == QPointF(0.0, 0.0))) {
|
||||||
auto angle = acos(dx/cir.radius);
|
auto angle = acos(offset.x() / cir.radius);
|
||||||
auto p1 = complex<double>(dx, cir.center.y() + cir.radius*sin(angle));
|
auto p1 = complex<double>(offset.x(), cir.center.y() + cir.radius*sin(angle));
|
||||||
auto p2 = complex<double>(dx, cir.center.y() - cir.radius*sin(angle));
|
auto p2 = complex<double>(offset.x(), cir.center.y() - cir.radius*sin(angle));
|
||||||
p.drawLine(dataToPixel(p1),dataToPixel(p2));
|
p.drawLine(dataToPixel(p1),dataToPixel(p2));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto slope = tan(cir.spanAngle*2*M_PI/360);
|
auto slope = tan(cir.spanAngle*2*M_PI/360);
|
||||||
auto y0 = cir.center.y();
|
auto y0 = cir.center.y();
|
||||||
auto f = dx;
|
auto f = offset.x();
|
||||||
auto a = 1 + (slope*slope);
|
auto a = 1 + (slope*slope);
|
||||||
auto b = (-2*cir.center.x())-(2*f*slope*slope)+(2*slope*y0)-(2*cir.center.y()*slope);
|
auto b = (-2*cir.center.x())-(2*f*slope*slope)+(2*slope*y0)-(2*cir.center.y()*slope);
|
||||||
auto c = (cir.center.x()*cir.center.x()) +(cir.center.y()*cir.center.y()) - (cir.radius*cir.radius) + (y0*y0) \
|
auto c = (cir.center.x()*cir.center.x()) +(cir.center.y()*cir.center.y()) - (cir.radius*cir.radius) + (y0*y0) \
|
||||||
@ -157,8 +155,15 @@ void TracePolarChart::draw(QPainter &p) {
|
|||||||
|
|
||||||
constexpr int Lines = 6;
|
constexpr int Lines = 6;
|
||||||
for(int i=0;i<Lines;i++) {
|
for(int i=0;i<Lines;i++) {
|
||||||
auto angle = (double) i * 30;
|
auto angle = (double) i * 30 / 180.0 * M_PI;
|
||||||
constraintLineToCircle(PolarArc(QPointF(0,0), edgeReflection, 0, angle)); // PolarArc
|
auto p1 = QPointF(sin(angle)*100, cos(angle)*100);
|
||||||
|
auto p2 = -p1;
|
||||||
|
p1 += offset;
|
||||||
|
p2 += offset;
|
||||||
|
if(TracePolar::constrainLineToCircle(p1, p2, QPointF(0,0), edgeReflection)) {
|
||||||
|
// center line visible
|
||||||
|
p.drawLine(dataToPixel(p1),dataToPixel(p2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto t : traces) {
|
for(auto t : traces) {
|
||||||
@ -195,8 +200,8 @@ void TracePolarChart::draw(QPainter &p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last = dataAddDx(last);
|
last = dataAddOffset(last);
|
||||||
now = dataAddDx(now);
|
now = dataAddOffset(now);
|
||||||
|
|
||||||
// scale to size of smith diagram
|
// scale to size of smith diagram
|
||||||
QPointF p1 = dataToPixel(last);
|
QPointF p1 = dataToPixel(last);
|
||||||
@ -228,7 +233,7 @@ void TracePolarChart::draw(QPainter &p) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto coords = m->getData();
|
auto coords = m->getData();
|
||||||
coords = dataAddDx(coords);
|
coords = dataAddOffset(coords);
|
||||||
|
|
||||||
if (limitToEdge && abs(coords) > edgeReflection) {
|
if (limitToEdge && abs(coords) > edgeReflection) {
|
||||||
// outside of visible area
|
// outside of visible area
|
||||||
@ -278,7 +283,7 @@ QString TracePolarChart::mouseText(QPoint pos)
|
|||||||
{
|
{
|
||||||
auto dataDx = pixelToData(pos);
|
auto dataDx = pixelToData(pos);
|
||||||
if(abs(dataDx) <= edgeReflection) {
|
if(abs(dataDx) <= edgeReflection) {
|
||||||
auto data = complex<double>(dataDx.real()-dx, dataDx.imag());
|
auto data = complex<double>(dataDx.real()-offset.x(), dataDx.imag()-offset.y());
|
||||||
auto ret = Unit::ToString(abs(data), "", " ", 3);
|
auto ret = Unit::ToString(abs(data), "", " ", 3);
|
||||||
ret += QString("∠");
|
ret += QString("∠");
|
||||||
auto phase = atan(data.imag()/data.real())*180/M_PI;
|
auto phase = atan(data.imag()/data.real())*180/M_PI;
|
||||||
|
@ -84,7 +84,10 @@ void TraceSmithChart::axisSetupDialog()
|
|||||||
ui->zoomFactor->setPrecision(3);
|
ui->zoomFactor->setPrecision(3);
|
||||||
ui->zoomReflection->setValue(edgeReflection);
|
ui->zoomReflection->setValue(edgeReflection);
|
||||||
ui->zoomFactor->setValue(1.0/edgeReflection);
|
ui->zoomFactor->setValue(1.0/edgeReflection);
|
||||||
ui->offsetRealAxis->setValue(dx);
|
ui->offsetRealAxis->setPrecision(4);
|
||||||
|
ui->offsetRealAxis->setValue(offset.x());
|
||||||
|
ui->offsetImagAxis->setPrecision(4);
|
||||||
|
ui->offsetImagAxis->setValue(offset.y());
|
||||||
|
|
||||||
ui->impedance->setUnit("Ω");
|
ui->impedance->setUnit("Ω");
|
||||||
ui->impedance->setPrecision(3);
|
ui->impedance->setPrecision(3);
|
||||||
@ -113,7 +116,10 @@ void TraceSmithChart::axisSetupDialog()
|
|||||||
ui->zoomFactor->setValueQuiet(1.0 / edgeReflection);
|
ui->zoomFactor->setValueQuiet(1.0 / edgeReflection);
|
||||||
});
|
});
|
||||||
connect(ui->offsetRealAxis, &SIUnitEdit::valueChanged, [=](){
|
connect(ui->offsetRealAxis, &SIUnitEdit::valueChanged, [=](){
|
||||||
dx = ui->offsetRealAxis->value();
|
offset = QPointF(ui->offsetRealAxis->value(), offset.y());
|
||||||
|
});
|
||||||
|
connect(ui->offsetImagAxis, &SIUnitEdit::valueChanged, [=](){
|
||||||
|
offset = QPointF(offset.x(), ui->offsetRealAxis->value());
|
||||||
});
|
});
|
||||||
connect(ui->impedance, &SIUnitEdit::valueChanged, [=](){
|
connect(ui->impedance, &SIUnitEdit::valueChanged, [=](){
|
||||||
Z0 = ui->impedance->value();
|
Z0 = ui->impedance->value();
|
||||||
@ -232,17 +238,22 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
for(int i=1;i<Circles * 2;i++) {
|
for(int i=1;i<Circles * 2;i++) {
|
||||||
auto radius = (double) i / Circles;
|
auto radius = (double) i / Circles;
|
||||||
drawArc(SmithChartArc(QPointF(1.0 - radius+dx, 0.0), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0 - radius+offset.x(), 0.0+offset.y()), radius, 0, 2*M_PI));
|
||||||
drawArc(SmithChartArc(QPointF(1.0 + radius+dx, 0.0), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0 + radius+offset.x(), 0.0+offset.y()), radius, 0, 2*M_PI));
|
||||||
}
|
}
|
||||||
|
|
||||||
p.drawLine(dataToPixel(complex<double>(edgeReflection,0)),dataToPixel(complex<double>(-edgeReflection,0)));
|
QPointF p1 = QPointF(-100, offset.y());
|
||||||
|
QPointF p2 = QPointF(100, offset.y());
|
||||||
|
if(TracePolar::constrainLineToCircle(p1, p2, QPointF(0,0), edgeReflection)) {
|
||||||
|
// center line visible
|
||||||
|
p.drawLine(dataToPixel(p1),dataToPixel(p2));
|
||||||
|
}
|
||||||
constexpr std::array<double, 5> impedanceLines = {10, 25, 50, 100, 250};
|
constexpr std::array<double, 5> impedanceLines = {10, 25, 50, 100, 250};
|
||||||
for(auto z : impedanceLines) {
|
for(auto z : impedanceLines) {
|
||||||
z /= Z0;
|
z /= Z0;
|
||||||
auto radius = 1.0/z;
|
auto radius = 1.0/z;
|
||||||
drawArc(SmithChartArc(QPointF(1.0+dx, radius), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0+offset.x(), radius+offset.y()), radius, 0, 2*M_PI));
|
||||||
drawArc(SmithChartArc(QPointF(1.0+dx, -radius), radius, 0, 2*M_PI));
|
drawArc(SmithChartArc(QPointF(1.0+offset.x(), -radius+offset.y()), radius, 0, 2*M_PI));
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw custom constant parameter lines
|
// draw custom constant parameter lines
|
||||||
@ -251,6 +262,7 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
for(auto arc : line.getArcs(Z0)) {
|
for(auto arc : line.getArcs(Z0)) {
|
||||||
|
arc.center += offset;
|
||||||
drawArc(arc);
|
drawArc(arc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,8 +301,8 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last = dataAddDx(last);
|
last = dataAddOffset(last);
|
||||||
now = dataAddDx(now);
|
now = dataAddOffset(now);
|
||||||
|
|
||||||
// scale to size of smith diagram
|
// scale to size of smith diagram
|
||||||
QPointF p1 = dataToPixel(last);
|
QPointF p1 = dataToPixel(last);
|
||||||
@ -325,7 +337,7 @@ void TraceSmithChart::draw(QPainter &p) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto coords = m->getData();
|
auto coords = m->getData();
|
||||||
coords = dataAddDx(coords);
|
coords = dataAddOffset(coords);
|
||||||
|
|
||||||
if (limitToEdge && abs(coords) > edgeReflection) {
|
if (limitToEdge && abs(coords) > edgeReflection) {
|
||||||
// outside of visible area
|
// outside of visible area
|
||||||
@ -388,7 +400,7 @@ QString TraceSmithChart::mouseText(QPoint pos)
|
|||||||
{
|
{
|
||||||
auto dataDx = pixelToData(pos);
|
auto dataDx = pixelToData(pos);
|
||||||
if(abs(dataDx) <= edgeReflection) {
|
if(abs(dataDx) <= edgeReflection) {
|
||||||
auto data = complex<double>(dataDx.real()-dx, dataDx.imag());
|
auto data = complex<double>(dataDx.real()-offset.x(), dataDx.imag()-offset.y());
|
||||||
data = Z0 * (1.0 + data) / (1.0 - data);
|
data = Z0 * (1.0 + data) / (1.0 - data);
|
||||||
auto ret = Unit::ToString(data.real(), "", " ", 3);
|
auto ret = Unit::ToString(data.real(), "", " ", 3);
|
||||||
if(data.imag() >= 0) {
|
if(data.imag() >= 0) {
|
||||||
|
@ -61,6 +61,38 @@ void TraceWaterfall::replot()
|
|||||||
TracePlot::replot();
|
TracePlot::replot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void TraceWaterfall::move(const QPoint &vect)
|
||||||
|
//{
|
||||||
|
// if(!xAxis.getLog()) {
|
||||||
|
// // can only move axis in linear mode
|
||||||
|
// // calculate amount of movement
|
||||||
|
// double distance = xAxis.inverseTransform(vect.x(), 0, plotAreaWidth) - xAxis.getRangeMin();
|
||||||
|
// xAxis.set(xAxis.getType(), false, false, xAxis.getRangeMin() - distance, xAxis.getRangeMax() - distance, xAxis.getRangeDiv());
|
||||||
|
// }
|
||||||
|
// replot();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void TraceWaterfall::zoom(const QPoint ¢er, double factor, bool horizontally, bool vertically)
|
||||||
|
//{
|
||||||
|
// if(horizontally && !xAxis.getLog()) {
|
||||||
|
// // can only zoom axis in linear mode
|
||||||
|
// // calculate center point
|
||||||
|
// double cp = xAxis.inverseTransform(center.x(), plotAreaLeft, plotAreaLeft + plotAreaWidth);
|
||||||
|
// double min = ((xAxis.getRangeMin() - cp) * factor) + cp;
|
||||||
|
// double max = ((xAxis.getRangeMax() - cp) * factor) + cp;
|
||||||
|
// xAxis.set(xAxis.getType(), false, false, min, max, xAxis.getRangeDiv() * factor);
|
||||||
|
// }
|
||||||
|
// replot();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//void TraceWaterfall::setAuto(bool horizontally, bool vertically)
|
||||||
|
//{
|
||||||
|
// if(horizontally) {
|
||||||
|
// xAxis.set(xAxis.getType(), xAxis.getLog(), true, xAxis.getRangeMin(), xAxis.getRangeMax(), xAxis.getRangeDiv());
|
||||||
|
// }
|
||||||
|
// replot();
|
||||||
|
//}
|
||||||
|
|
||||||
void TraceWaterfall::fromJSON(nlohmann::json j)
|
void TraceWaterfall::fromJSON(nlohmann::json j)
|
||||||
{
|
{
|
||||||
resetWaterfall();
|
resetWaterfall();
|
||||||
|
@ -17,6 +17,11 @@ public:
|
|||||||
virtual void enableTrace(Trace *t, bool enabled) override;
|
virtual void enableTrace(Trace *t, bool enabled) override;
|
||||||
|
|
||||||
void replot() override;
|
void replot() override;
|
||||||
|
|
||||||
|
// virtual void move(const QPoint &vect) override;
|
||||||
|
// virtual void zoom(const QPoint ¢er, double factor, bool horizontally, bool vertically) override;
|
||||||
|
// virtual void setAuto(bool horizontally, bool vertically) override;
|
||||||
|
|
||||||
virtual Type getType() override { return Type::Waterfall;}
|
virtual Type getType() override { return Type::Waterfall;}
|
||||||
|
|
||||||
void fromJSON(nlohmann::json j) override;
|
void fromJSON(nlohmann::json j) override;
|
||||||
|
@ -1223,7 +1223,11 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QSpinBox" name="GraphsSweepTriangleSize"/>
|
<widget class="QSpinBox" name="GraphsSweepTriangleSize">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_52">
|
<widget class="QLabel" name="label_52">
|
||||||
|
Loading…
Reference in New Issue
Block a user