#include "echoplot.h" #include "commons.h" #include <math.h> #include <QPainter> #include <QPen> #include <QDebug> #include "moc_echoplot.cpp" #define MAX_SCREENSIZE 2048 EPlotter::EPlotter(QWidget *parent) : //EPlotter Constructor QFrame(parent) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setFocusPolicy(Qt::StrongFocus); setAttribute(Qt::WA_PaintOnScreen,false); setAutoFillBackground(false); setAttribute(Qt::WA_OpaquePaintEvent, false); setAttribute(Qt::WA_NoSystemBackground, true); m_StartFreq = -200; m_fftBinWidth=12000.0/32768.0; m_binsPerPixel=1; m_fSpan=1000.0; m_hdivs = HORZ_DIVS; m_Running = false; m_paintEventBusy=false; m_2DPixmap = QPixmap(0,0); m_ScalePixmap = QPixmap(0,0); m_OverlayPixmap = QPixmap(0,0); m_Size = QSize(0,0); m_TxFreq = 1500; m_line = 0; m_dBStepSize=10; } EPlotter::~EPlotter() { } // Destructor QSize EPlotter::minimumSizeHint() const { return QSize(50, 50); } QSize EPlotter::sizeHint() const { return QSize(180, 180); } void EPlotter::resizeEvent(QResizeEvent* ) //resizeEvent() { if(!size().isValid()) return; if( m_Size != size() ) { //if changed, resize pixmaps to new screensize m_Size = size(); m_w = m_Size.width(); m_h = m_Size.height(); m_h1=30; m_h2=m_h-m_h1; m_2DPixmap = QPixmap(m_Size.width(), m_h2); m_2DPixmap.fill(Qt::black); m_OverlayPixmap = QPixmap(m_Size.width(), m_h2); m_ScalePixmap = QPixmap(m_w,30); m_ScalePixmap.fill(Qt::white); m_fSpan=m_w*m_fftBinWidth*m_binsPerPixel; m_StartFreq=50 * int((-0.5*m_fSpan)/50.0 - 0.5); } DrawOverlay(); draw(); } void EPlotter::paintEvent(QPaintEvent *) // paintEvent() { if(m_paintEventBusy) return; m_paintEventBusy=true; QPainter painter(this); painter.drawPixmap(0,0,m_ScalePixmap); painter.drawPixmap(0,m_h1,m_2DPixmap); m_paintEventBusy=false; } void EPlotter::draw() //draw() { int i,j,y; float blue[4096],red[4096]; float gain = pow(10.0,(m_plotGain/20.0)); QPen penBlue(QColor(0,255,255),1); QPen penRed(Qt::red,1); QPen penRed2(Qt::red,2); QPen penBlack(Qt::black,1); QPen penBlack2(Qt::black,2); if(m_2DPixmap.size().width()==0) return; QPainter painter2D(&m_2DPixmap); QRect tmp(0,0,m_w,m_h2); if(m_nColor < 2) { painter2D.fillRect(tmp,Qt::black); } else { painter2D.fillRect(tmp,Qt::white); painter2D.setPen(penBlack); painter2D.drawLine(0,0,m_w,0); } QPoint LineBuf[MAX_SCREENSIZE]; if(m_binsPerPixel==0) m_binsPerPixel=1; j=0; for(i=0; i<4096/m_binsPerPixel; i++) { blue[i]=0.0; red[i]=0.0; for(int k=0; k<m_binsPerPixel; k++) { blue[i]+=echocom_.blue[j]; red[i]+=echocom_.red[j]; j++; } } if(m_smooth>0) { for(i=0; i<m_smooth; i++) { int n4096=4096; smo121_(blue,&n4096); smo121_(red,&n4096); } } // check i0 value! ... int i0=2048/m_binsPerPixel + int(m_StartFreq/(m_fftBinWidth*m_binsPerPixel)); if(m_blue) { painter2D.setPen(penBlue); j=0; for(i=0; i<m_w; i++) { y = 0.9*m_h2 - gain*(m_h/10.0)*(blue[i0+i]-1.0) - 0.01*m_h2*m_plotZero; LineBuf[j].setX(i); LineBuf[j].setY(y); j++; } painter2D.drawPolyline(LineBuf,j); } switch (m_nColor) { case 0: painter2D.setPen(penRed); break; case 1: painter2D.setPen(penRed2); break; case 2: painter2D.setPen(penRed); break; case 3: painter2D.setPen(penRed2); break; case 4: painter2D.setPen(penBlack); break; case 5: painter2D.setPen(penBlack2); break; } j=0; for(int i=0; i<m_w; i++) { y = 0.9*m_h2 - gain*(m_h/10.0)*(red[i0+i]-1.0) - 0.01*m_h2*m_plotZero; LineBuf[j].setX(i); LineBuf[j].setY(y); j++; } painter2D.drawPolyline(LineBuf,j); update(); //trigger a new paintEvent } void EPlotter::DrawOverlay() //DrawOverlay() { if(m_OverlayPixmap.isNull() or m_2DPixmap.isNull()) return; // int w = m_WaterfallPixmap.width(); int x,y; QPainter painter(&m_OverlayPixmap); painter.setBackground (palette ().brush (backgroundRole ())); QLinearGradient gradient(0, 0, 0 ,m_h2); //fill background with gradient gradient.setColorAt(1, Qt::black); gradient.setColorAt(0, Qt::darkBlue); painter.setBrush(gradient); painter.drawRect(0, 0, m_w, m_h2); painter.setBrush(Qt::SolidPattern); m_fSpan = m_w*m_fftBinWidth*m_binsPerPixel; m_freqPerDiv=20; if(m_fSpan>250) m_freqPerDiv=50; if(m_fSpan>500) m_freqPerDiv=100; if(m_fSpan>1000) m_freqPerDiv=200; if(m_fSpan>2000) m_freqPerDiv=500; // m_StartFreq=50 * int((-0.5*m_fSpan)/50.0 - 0.5); m_StartFreq=m_freqPerDiv * int((-0.5*m_fSpan)/m_freqPerDiv - 0.5); float pixPerHdiv = m_freqPerDiv/(m_fftBinWidth*m_binsPerPixel); float pixPerVdiv = float(m_h2)/float(VERT_DIVS); m_hdivs = m_w*m_fftBinWidth*m_binsPerPixel/m_freqPerDiv + 0.9999; painter.setPen(QPen(Qt::white, 1,Qt::DotLine)); for( int i=1; i<m_hdivs; i++) //draw vertical grids { x=int(i*pixPerHdiv); painter.drawLine(x,0,x,m_h2); } for( int i=1; i<VERT_DIVS; i++) //draw horizontal grids { y = (int)( (float)i*pixPerVdiv ); painter.drawLine(0,y,m_w,y); } QRect rect0; QPainter painter0(&m_ScalePixmap); painter0.setBackground (palette ().brush (backgroundRole ())); //create Font to use for scales QFont Font("Arial"); Font.setPointSize(12); QFontMetrics metrics(Font); Font.setWeight(QFont::Normal); painter0.setFont(Font); painter0.setPen(Qt::black); m_ScalePixmap.fill(Qt::white); painter0.drawRect(0, 0, m_w, 30); //draw tick marks on upper scale for( int i=1; i<m_hdivs; i++) { //major ticks x = (int)( (float)i*pixPerHdiv ); painter0.drawLine(x,18,x,30); } int minor=5; if(m_freqPerDiv==200) minor=4; for( int i=1; i<minor*m_hdivs; i++) { //minor ticks x = i*pixPerHdiv/minor; painter0.drawLine(x,24,x,30); } //draw frequency values MakeFrequencyStrs(); for( int i=0; i<=m_hdivs; i++) { if(0==i) { //left justify the leftmost text x = (int)( (float)i*pixPerHdiv); rect0.setRect(x,0, (int)pixPerHdiv, 20); painter0.drawText(rect0, Qt::AlignLeft|Qt::AlignVCenter, m_HDivText[i]); } else if(m_hdivs == i) { //right justify the rightmost text x = (int)( (float)i*pixPerHdiv - pixPerHdiv); rect0.setRect(x,0, (int)pixPerHdiv, 20); painter0.drawText(rect0, Qt::AlignRight|Qt::AlignVCenter, m_HDivText[i]); } else { //center justify the rest of the text x = (int)( (float)i*pixPerHdiv - pixPerHdiv/2); rect0.setRect(x,0, (int)pixPerHdiv, 20); painter0.drawText(rect0, Qt::AlignHCenter|Qt::AlignVCenter, m_HDivText[i]); } } /* QPen pen1(Qt::red, 3); //Mark Tx Freq with red tick painter0.setPen(pen1); x = XfromFreq(m_TxFreq); painter0.drawLine(x,17,x,30); */ } void EPlotter::MakeFrequencyStrs() //MakeFrequencyStrs { float freq; for(int i=0; i<=m_hdivs; i++) { freq=m_StartFreq + i*m_freqPerDiv; m_HDivText[i].setNum((int)freq); } } int EPlotter::XfromFreq(float f) //XfromFreq() { int x = (int) m_w * (f - m_StartFreq)/m_fSpan; if(x<0 ) return 0; if(x>m_w) return m_w; return x; } float EPlotter::FreqfromX(int x) //FreqfromX() { return float(m_StartFreq + x*m_fftBinWidth*m_binsPerPixel); } void EPlotter::SetRunningState(bool running) //SetRunningState() { m_Running = running; } void EPlotter::setPlotZero(int plotZero) //setPlotZero() { m_plotZero=plotZero; } int EPlotter::getPlotZero() //getPlotZero() { return m_plotZero; } void EPlotter::setPlotGain(int plotGain) //setPlotGain() { m_plotGain=plotGain; } int EPlotter::getPlotGain() //getPlotGain() { return m_plotGain; } void EPlotter::setSmooth(int n) //setSmooth() { m_smooth=n; } int EPlotter::getSmooth() //getSmooth() { return m_smooth; } void EPlotter::setColors(qint32 n) //setSmooth() { m_nColor=n; draw(); } int EPlotter::plotWidth(){return m_2DPixmap.width();} void EPlotter::UpdateOverlay() {DrawOverlay();}