⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fftview.cpp

📁 快速敷里叶变换算法 图形显示
💻 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 + -