📄 plotdata.cpp
字号:
// PlotData.cpp: implementation of the CPlotData class.
//
//////////////////////////////////////////////////////////////////////
// Copyright 2000. Moe Wheatley AE4JY <ae4jy@mindspring.com>
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or 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 General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
////
#include "stdafx.h"
#include "pathsim.h"
#include "PlotData.h"
#include "PathsimView.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define FREQRANGE 972 //max range of the frequency display in FFT units
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CPlotData::CPlotData()
{
m_pDoc = NULL;
m_pIOCntrl = NULL;
//allocate memory space
m_pDispBuf = new INT[DISPBUF_SIZE+10];
ASSERT( m_pDispBuf );
//allocate FFT object
m_pPenR = new CPen; // create some colored pens for drawing
m_pPenG = new CPen;
m_pPenY = new CPen;
m_pPenW = new CPen;
m_pPenC = new CPen;
m_pPenB = new CPen;
m_pPenR->CreatePen( PS_SOLID,0, RGB(255,0,0) );
m_pPenG->CreatePen( PS_SOLID,0, RGB(0,255,0) );
m_pPenY->CreatePen( PS_DOT,0, RGB(255,255,0) );
m_pPenW->CreatePen( PS_SOLID,0, RGB(128,128,128) );
m_pPenC->CreatePen( PS_SOLID,0, RGB(0,255,255) );
m_pPenB->CreatePen( PS_SOLID,0, RGB(0,0,255) );
}
CPlotData::~CPlotData()
{
m_pPenR->DeleteObject(); delete m_pPenR;
m_pPenG->DeleteObject(); delete m_pPenG;
m_pPenY->DeleteObject(); delete m_pPenY;
m_pPenW->DeleteObject(); delete m_pPenW;
m_pPenC->DeleteObject(); delete m_pPenC;
m_pPenB->DeleteObject(); delete m_pPenB;
if(m_pDispBuf)
{
delete m_pDispBuf;
m_pDispBuf = NULL;
}
}
//////////////////////////////////////////////////////////////////////
// Called from the Windows view class when the window has changed
// and needs to update the screen coordinates.
//////////////////////////////////////////////////////////////////////
void CPlotData::OnDrawPlot(HWND hWnd, CFormView* pView, CPathSimDoc* pDoc, CIOCntrl* pIOCntrl)
{
CRect rScrn;
m_pDoc = pDoc;
m_hViewWnd = hWnd;
m_pIOCntrl = pIOCntrl;
//calculate new plot area coordinates
// Get pixel size of Freq plot area bitmap
ASSERT_VALID( pView );
CWnd* pWnd = pView->GetDlgItem( IDC_PLOTFREQ );
ASSERT_VALID( pWnd);
pWnd->GetWindowRect( m_rFreqPlot );
pView->GetWindowRect(rScrn);
m_rFreqPlot.top -= (rScrn.top+1);
m_rFreqPlot.left -= (rScrn.left+1);
m_rFreqPlot.bottom = m_rFreqPlot.top+m_rFreqPlotsize.bottom;
m_rFreqPlot.right = m_rFreqPlot.left+m_rFreqPlotsize.right;
// Get pixel size of Time plot area bitmap
pWnd = pView->GetDlgItem( IDC_PLOTTIME );
ASSERT_VALID( pWnd);
pWnd->GetWindowRect( m_rTimePlot );
pView->GetWindowRect(rScrn);
m_rTimePlot.top -= (rScrn.top+1);
m_rTimePlot.left -= (rScrn.left+1);
m_rTimePlot.bottom = m_rTimePlot.top+m_rTimePlotsize.bottom;
m_rTimePlot.right = m_rTimePlot.left+m_rTimePlotsize.right;
// The translate table is used to map DispBuf[] index's into
// Screen plot coordinates.
for(INT i=0; i<1023; i++)
{
m_TranslateTbl[i] = ( (i-0)*m_rFreqPlotsize.right )
/ (FREQRANGE - 0);
}
m_FFTSetupChanged = TRUE;
}
//////////////////////////////////////////////////////////////////////
// Called to clear plot surface, draw cursor, and call specific plot
// routine.
//////////////////////////////////////////////////////////////////////
void CPlotData::DrawPlot()
{
// erases plot surface
// plots data points
CDC MemDC;
CPen* pOldPen;
CClientDC ClientDC(CWnd::FromHandle(m_hViewWnd) );
if( m_bmFreqPlot.m_hObject != NULL ) // delete old bitmap objects
m_bmFreqPlot.DeleteObject();
if( m_bmTimePlot.m_hObject != NULL ) // delete old bitmap objects
m_bmTimePlot.DeleteObject();
//create a new bitmap with current screen DC settings
m_bmFreqPlot.CreateCompatibleBitmap( &ClientDC, m_rFreqPlot.Width(),
m_rFreqPlot.Height() );
m_bmTimePlot.CreateCompatibleBitmap( &ClientDC, m_rTimePlot.Width(),
m_rTimePlot.Height() );
//create memory DC pointer to the plot bitmap
MemDC.CreateCompatibleDC( &ClientDC );
//==========Plot Time domain plot============
CBitmap* pbmOld = MemDC.SelectObject( &m_bmTimePlot );
// set bitmap background to black using slightly faster ExtTextOut function
MemDC.SetBkColor( RGB(0, 0, 0) );
MemDC.ExtTextOut( 0, 0,ETO_OPAQUE, &m_rTimePlotsize,NULL,0,NULL);
MemDC.SelectObject(m_pPenG);
PlotTimeData( &MemDC );
// MemDC.SelectObject(m_pPenY);
// MemDC.MoveTo( 0, m_rTimePlotsize.bottom/2 );
// MemDC.LineTo( m_rFreqPlotsize.right, m_rTimePlotsize.bottom/2 );
// Copy memory bitmap into screen device context for flicker free update
ClientDC.BitBlt( m_rTimePlot.left, m_rTimePlot.top,
m_rTimePlotsize.right,
m_rTimePlotsize.bottom, &MemDC,
0,0,SRCCOPY);
//==========Plot Frequency plot============
MemDC.SelectObject( &m_bmFreqPlot );
// set bitmap background to black using slightly faster ExtTextOut function
MemDC.SetBkColor( RGB(0, 0, 0) );
MemDC.ExtTextOut( 0, 0,ETO_OPAQUE, &m_rFreqPlotsize,NULL,0,NULL);
MemDC.SelectObject(m_pPenG);
if(m_FFTSetupChanged)
{
m_pIOCntrl->SetFFTParams( 3, m_rFreqPlotsize.bottom, 1 );
m_FFTSetupChanged = FALSE;
}
PlotFFTData( &MemDC );
pOldPen = MemDC.SelectObject(m_pPenW); //save original pen.
for( INT i=10; i<100; i+=10 ) //draw 10dB tic marks
{
MemDC.MoveTo( 0, (m_rFreqPlotsize.bottom*i)/100 );
MemDC.LineTo( m_rFreqPlotsize.right, (m_rFreqPlotsize.bottom*i)/100 );
}// Copy memory bitmap into screen device context for flicker free update
ClientDC.BitBlt( m_rFreqPlot.left, m_rFreqPlot.top,
m_rFreqPlotsize.right,
m_rFreqPlotsize.bottom, &MemDC,
0,0,SRCCOPY);
/////////////////////////
MemDC.SelectObject(pOldPen); //deselect pens and bitmap
MemDC.SelectObject( pbmOld ); // from memory DC
}
//////////////////////////////////////////////////////////////////////
// Perform FFT and plot two dimensional results
//////////////////////////////////////////////////////////////////////
void CPlotData::PlotFFTData( CDC* pDC)
{
INT x,y,k1;
k1 = m_rFreqPlotsize.bottom; //y range
m_pIOCntrl->GetFFTData( (long*)m_pDispBuf,
1,
FREQRANGE );
pDC->MoveTo( 0, k1-m_pDispBuf[1]); //move to first position
for( x=2; x<FREQRANGE; x++ )
{
y = k1-m_pDispBuf[x];
pDC->LineTo( m_TranslateTbl[x], y ); //draw to the next pt.
}
}
//////////////////////////////////////////////////////////////////////
// Plots the input data directly in the time domain
//////////////////////////////////////////////////////////////////////
void CPlotData::PlotTimeData( CDC* pDC)
{
INT x,y,k1;
BOOL overload = FALSE;
k1 = m_rTimePlotsize.bottom/2; //center
pDC->MoveTo( 0, k1); //move to first position
overload = m_pIOCntrl->GetTimeData1( (long*)m_pDispBuf, 0, m_rTimePlotsize.right );
if(overload)
pDC->SelectObject(m_pPenR);
for( x=1; x<m_rTimePlotsize.right; x++ )
{
y = k1 + (k1*m_pDispBuf[x])/32767;
pDC->LineTo( x, y ); //draw to the next pt.
}
}
INT CPlotData::GetCursFreq(CPoint point)
{
INT range = 1023*(m_rFreqPlot.right -m_rFreqPlot.left);
return (FREQRANGE*4000*( point.x - m_rFreqPlot.left))/range;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -