/* -*- C++ -*- This file is part of ViPEC Copyright (C) 1991-2000 Johan Rossouw (jrossouw@alcatel.altech.co.za) This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #define sqr(x) x*x using namespace std; //---------------------------------------------------------------------------- SmithView::SmithView( const char* name, WFlags f ) : GraphView( GraphView::smithView, name, f ) { setCursorLabel("Cursor %d:\n\tR=%3.3f\n\tX=%3.3f"); } //---------------------------------------------------------------------------- SmithView::~SmithView() {} //---------------------------------------------------------------------------- bool SmithView::isInsideView(const QPoint& p) { int s = sqr(p.x() - xOrigin_) + sqr(p.y() - yOrigin_); return (s <= sqr(radius_)); } //---------------------------------------------------------------------------- void SmithView::setDefaults() { GraphView::setDefaults(); setOrigin(TComplex(0.0,0.0)); } //---------------------------------------------------------------------------- void SmithView::setOrigin(TComplex value) { reOrigin_ = value.real(); imOrigin_ = value.imag(); } //---------------------------------------------------------------------------- void SmithView::rCircle(QPainter *p, double r ) { int xc = xOrigin_ + (int) floor(radius_ * (r/(1+r))); int rd = (int) floor(radius_ / (1+r)); p->drawEllipse(xc - rd, yOrigin_ - rd, 2 * rd, 2 * rd); } //---------------------------------------------------------------------------- void SmithView::xCircle(QPainter *p, double x) { int rd = (int)floor(radius_/x); int yc = xOrigin_+radius_-rd; int rd2 = rd*2; p->drawEllipse(yc, yOrigin_ , rd2, rd2); p->drawEllipse(yc, yOrigin_-rd2, rd2, rd2); } //---------------------------------------------------------------------------- QPoint SmithView::toClient( TReal xValue, TReal yValue ) { int x, y; x = xOrigin_ + (int) floor(radius_ * xValue); y = yOrigin_ - (int) floor(radius_ * yValue); QPoint clientPos(x,y); return clientPos; } //---------------------------------------------------------------------------- TComplex SmithView::fromClient( int x, int y ) { TReal xValue, yValue; xValue = (TReal) (x - xOrigin_) / radius_; yValue = (TReal) (yOrigin_ - y) / radius_; TComplex value(xValue, yValue); return value; } //---------------------------------------------------------------------------- TComplex SmithView::transformCoordinates( TComplex coord ) { TReal x = real(coord); TReal y = imag(coord); TReal z = x*x + y*y; TReal a = z-2*x+1; TReal re = (1-z)/a; TReal im = (2*y)/a; TComplex value(re, im); return value; } //---------------------------------------------------------------------------- void SmithView::drawCursors(QPainter* p) { GraphView::drawCursors(p, cursorLegendRect_); } //---------------------------------------------------------------------------- void SmithView::print(QPainter *p) { draw(p); GraphView::drawCursors(p, cursorLegendRect_); frame_->reDraw(); } //---------------------------------------------------------------------------- void SmithView::draw( QPainter *p ) { //Get the window size QRect rect = p->window(); computeScaling(p); QFont titleFont = getTitleFont(p->device()); QFont labelFont = getLabelFont(p->device()); p->setPen( black ); // black pen outline //Draw title p->setFont( titleFont ); p->drawText(gap_, gap_, width_, height_, AlignLeft | AlignTop, getTitle() ); //Legend settings int legendPos = p->fontMetrics().lineSpacing() + 2*gap_; p->setFont( labelFont ); int lineSpacing = p->fontMetrics().lineSpacing(); int legendGap = (int) floor(10*scale_); //Draw frame p->setPen( lightGray ); //Define clipping regions QRegion clipRegion1(xOrigin_-radius_-1, yOrigin_-radius_-1, radius_*2+2, radius_*2+2, QRegion::Ellipse); QRegion clipRegion2(rect, QRegion::Rectangle); p->setClipRegion(clipRegion1); drawGrid(p); int rowNo = 0; int colorCount = 0; int markerSize = (int) floor(3*scale_); p->setClipRegion(clipRegion2); //Plot each series SeriesMap::Iterator it; for( it = seriesMap_.begin(); it != seriesMap_.end(); ++it ) { DataVector& vector = it.data(); // Update pen color p->setPen( GraphUtils::getColor(colorCount) ); // Plot data bool firstPoint = true; int markerSpace = vector.getSize() / 10; int x = gap_; int y = legendPos; if (showMarkers()) { GraphUtils::drawMarker(p, colorCount, x, y+(lineSpacing/2), markerSize); } p->drawText(x+legendGap, y, xOrigin_ - radius_, y+lineSpacing, AlignLeft | AlignTop, it.key()); legendPos += lineSpacing; for (uint index=0; indexmoveTo(pos); firstPoint = false; } else p->lineTo(pos); // Draw markers if ( ((index % markerSpace) == 0) && showMarkers() ) { GraphUtils::drawMarker(p, colorCount, x, y, markerSize); } } //for // Draw last marker if ( showMarkers() ) { GraphUtils::drawMarker(p, colorCount, x, y, markerSize); } colorCount++; rowNo++; } //while //Plot each series int x = gap_; int y = legendPos; int w = xOrigin_ - radius_ - x; int h = height_ - legendPos; cursorLegendRect_.setRect(x, y, w, h); } //---------------------------------------------------------------------------- void SmithView::computeScaling(QPainter* p) { //Get the window size QRect rect = p->window(); //Calculate boundaries width_ = rect.width(); height_ = rect.height(); gap_ = (int)(0.05*height_); if (width_ > height_) { radius_ = (height_ - 2*gap_)/2; } else { radius_ = (width_ - 2*gap_)/2; } xOrigin_ = width_ - radius_ - 10; yOrigin_ = height_/2; scale_ = radius_ / 130.0; } //---------------------------------------------------------------------------- void SmithView::drawGrid(QPainter* p) { p->moveTo(xOrigin_ - radius_, yOrigin_); p->lineTo(xOrigin_ + radius_, yOrigin_); rCircle(p, 0.0); rCircle(p, 0.5); rCircle(p, 1.0); rCircle(p, 2.0); xCircle(p, 0.5); xCircle(p, 1.0); xCircle(p, 2.0); }