📄 fftview.cpp
字号:
// FFTView.cpp : implementation of the CFFTView class
//
#include "stdafx.h"
#include "FFT.h"
#include "FFTDoc.h"
#include "FFTView.h"
#include "InDialog.h"
#include "math.h"
#define PI 3.141592653589793
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFFTView
IMPLEMENT_DYNCREATE(CFFTView, CScrollView)
BEGIN_MESSAGE_MAP(CFFTView, CScrollView)
//{{AFX_MSG_MAP(CFFTView)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
ON_COMMAND(ID_131, On131)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFFTView construction/destruction
CFFTView::CFFTView()
{
// TODO: add construction code here
}
CFFTView::~CFFTView()
{
}
BOOL CFFTView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CScrollView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CFFTView drawing
void CFFTView::OnDraw(CDC* pDC)
{
CFFTDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
struct complex
{
double re;
double im;
};
complex T;
// complex u,w;
// int M=0,fix=1,LE,LEI,l;
int p,add,bot;
// TODO: add draw code for native data here
//////采样:
if(pDoc->m_zero==TRUE)
{
for(int x=0;x<2*(pDoc->m_N);x++)
{
if(x>=pDoc->m_N)
{
pDoc->re[x]=pDoc->im[x]=0;
pDoc->re1[x]=pDoc->re[x];
pDoc->im1[x]=pDoc->im[x];
}
else
{
pDoc->re[x]=sin(2*PI*pDoc->m_F*pDoc->m_T*x);
pDoc->im[x]=0;
pDoc->re1[x]=pDoc->re[x];
pDoc->im1[x]=pDoc->im[x];
}
}
pDoc->m_N*=2;
}
else
{
for(int x=0;x<pDoc->m_N;x++)
{
pDoc->re[x]=sin(2*PI*pDoc->m_F*pDoc->m_T*x);
pDoc->im[x]=0;
pDoc->re1[x]=pDoc->re[x];
pDoc->im1[x]=pDoc->im[x];
}
}
int j=1,i=0,k;
CRect rectclient;
GetClientRect(&rectclient);
CString s;
////////////变址运算:
int n2,n1;
n2=pDoc->m_N/2;
n1=pDoc->m_N-1;
if(n1<0)
MessageBox("采样长应该为一大于零的整数!","没有输出",MB_OK);
else
{
for(;;)
{
i=i+1;
int p;
if(i>=j)
p=1;
else
p=0;
switch(p)
{
case 0:
T.re=pDoc->re[j-1];
T.im=pDoc->im[j-1];
pDoc->re[j-1]=pDoc->re[i-1];
pDoc->im[j-1]=pDoc->im[i-1];
pDoc->re[i-1]=T.re;
pDoc->im[i-1]=T.im;
case 1:
k=n2;
while(k<j)
{
j=j-k;
k=k/2;
}
j=j+k;
break;
}
if(i>=n1)
break;
}
///////////FFT运算算法:
p=pDoc->m_N;i=0;
while(p!=1) /*求出所需运算级数--p*/
{p/=2;i++;}
p=i;
for(i=1;i<=p;i++) /*进行p级运算*/
{
for(j=0;j<pDoc->m_N/pow(2,i);j++) /*将数据分为N/2^i个小组,分组运算;例: 第一级时分为4组进行计算*/
{
for(k=j*pow(2,i);k<=j*pow(2,i)+pow(2,i-1)-1;k++) /*蝶形运算,第一级时:k=0 */
{
double a,b,x,y;
int m,n;
a=pDoc->re[k];/*k=0*/
b=pDoc->im[k];
m=k+pow(2,i-1);
x=pDoc->re[m];/*m=1,对应x(0),x(4)的运算,因为已经码位倒置了,所以此时x(1)对应的是输入x(4)的内容*/
y=pDoc->im[m];
n=k-j*pow(2,i);/*n=0*/
pDoc->re[k]=a+x*cos(2*PI*n/pow(2,i))+y*sin(2*PI*n/pow(2,i));/*蝶形运算*/
pDoc->im[k]=b-x*sin(2*PI*n/pow(2,i))+y*cos(2*PI*n/pow(2,i));
pDoc->re[m]=a-x*cos(2*PI*n/pow(2,i))-y*sin(2*PI*n/pow(2,i));
pDoc->im[m]=b+x*sin(2*PI*n/pow(2,i))-y*cos(2*PI*n/pow(2,i));
} /*数据实部存入re,虚部存入im*/
}
}
/* for(;;M++)
{
fix*=2;
if(fix==pDoc->m_N)
break;
}
for(l=1;l<=M;l++)
{
for(i=0;i<l;)
{
LE*=2;
}
LEI=LE/2;
u.re=1.0;
u.im=0.0;
w.re=cos(PI/(double)LEI);
w.im=-sin(PI/(double)LEI);
for(j=1;j<=LEI;j++)
{
for(i=j;i<=pDoc->m_N;i++)
{
int ip=i+LEI;
T.re=pDoc->re[ip]*u.re-pDoc->im[ip]*u.im;
T.im=pDoc->im[ip]*u.re+pDoc->re[ip]*u.im;
pDoc->re[ip]=pDoc->re[i]-T.re;
pDoc->im[ip]=pDoc->im[i]-T.im;
pDoc->re[i]+=T.re;
pDoc->im[i]+=T.im;
}
u.re=u.re*w.re-u.im*w.im;
u.im=u.re*w.im+u.im*w.re;
}
}*/
///////////////////
add=rectclient.right/(4*pDoc->m_N);
CFont newfont,*poldfont;;
newfont.CreateFont(12,6,0.0,0.0,500,0,0,0,1,0,0,0,0,"宋体");
poldfont=pDC->SelectObject(&newfont);
for(i=0,j=0;i<pDoc->m_N;i++)
{
if(pDoc->im[i]>=0)
{
s.Format("X[%d]=%f+j%f",i,pDoc->re[i],pDoc->im[i]);
}
else
{
s.Format("X[%d]=%f-j%f",i,pDoc->re[i],-pDoc->im[i]);
}
if(i>=pDoc->m_N)
break;
pDC->TextOut(i%4*rectclient.right/4,j,s);
if(i%4==3)
j+=15;
}
pDC->SelectObject(poldfont);
bot=(j+rectclient.bottom)/2+50;
CRect rect1(30,bot-100,rectclient.right/4+50,bot+45),rect2;
rect2.SetRect(rectclient.right/2,bot-100,rectclient.right*3/4+50,bot+45);
CPen *poldpen,newpen;
newpen.CreatePen(PS_SOLID,4,RGB(255,0,0));
poldpen=pDC->SelectObject(&newpen);
pDC->Rectangle(rect1);
pDC->Rectangle(rect2);
pDC->SelectObject(poldpen);
pDC->MoveTo(rectclient.right/2+50,bot);
pDC->LineTo(rectclient.right*3/4+20,bot);
// pDC->MoveTo(rectclient.right/2+50,bot);
// pDC->LineTo(rectclient.right/2+50,bot-150);
for(i=0;i<pDoc->m_N;i++)
{
pDC->MoveTo(rectclient.right/2+50+i*add,bot);
pDC->LineTo(rectclient.right/2+50+i*add,bot-5*(sqrt(pow(pDoc->im[i],2)+pow(pDoc->re[i],2))));
pDC->TextOut(rectclient.right/2+100,bot-80,"X[K]");
}
pDC->MoveTo(50,bot);
pDC->LineTo(rectclient.right/4+20,bot);
// pDC->MoveTo(rectclient.right/2+50,bot);
// pDC->LineTo(rectclient.right/2+50,bot-150);
if(pDoc->m_zero==TRUE)
add*=2;
for(i=0;i<pDoc->m_N;i++)
{
pDC->MoveTo(50+i*add,bot);
pDC->LineTo(50+i*add,bot-40*pDoc->re1[i]);
pDC->TextOut(100,bot-80,"x(n)");
}
if(pDoc->m_zero==TRUE)
pDoc->m_N/=2;
}
}
void CFFTView::OnInitialUpdate()
{
CFFTDoc *pDoc=GetDocument();
CInDialog dlg;
if(dlg.DoModal()==IDOK)
{
UpdateData(TRUE);
pDoc->m_F=dlg.m_nF;
pDoc->m_N=dlg.m_nN;
pDoc->m_T=dlg.m_nT;
pDoc->m_zero=dlg.m_nzero;
}
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}
/////////////////////////////////////////////////////////////////////////////
// CFFTView diagnostics
#ifdef _DEBUG
void CFFTView::AssertValid() const
{
CScrollView::AssertValid();
}
void CFFTView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
CFFTDoc* CFFTView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFFTDoc)));
return (CFFTDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CFFTView message handlers
void CFFTView::On131()
{
// TODO: 在此添加命令处理程序代码
CFFTDoc *pDoc=GetDocument();
CInDialog dlg;
if(dlg.DoModal()==IDOK)
{
UpdateData(TRUE);
pDoc->m_F=dlg.m_nF;
pDoc->m_N=dlg.m_nN;
pDoc->m_T=dlg.m_nT;
pDoc->m_zero=dlg.m_nzero;
}
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -