📄 sunview.cpp
字号:
// sunView.cpp : implementation of the CSunView class
//
#include "stdafx.h"
#include "sun.h"
#include "sunDoc.h"
#include "sunView.h"
#include "complex.h"
#include <math.h>
#define PI_2 2*(double)3.14159265358979323846
#define PI (double)3.14159265358979323846
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSunView
IMPLEMENT_DYNCREATE(CSunView, CView)
BEGIN_MESSAGE_MAP(CSunView, CView)
//{{AFX_MSG_MAP(CSunView)
ON_COMMAND(ID_CHOSE, OnChose)
ON_COMMAND(ID_DOFIR, OnDofir)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSunView construction/destruction
CSunView::CSunView()
{
// TODO: add construction code here
}
CSunView::~CSunView()
{
}
BOOL CSunView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CSunView drawing
void CSunView::OnDraw(CDC* pDC)
{
CSunDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
if(cholg.flag==1)
{
int count;
count=pow(2,nn);
int dd=count;
complex * x;
double * ms;
double *phase;
x=new complex[count];
ms=new double[count];
phase=new double[count];
if(cholg.m_xuan==0)load(x,nn);
if(cholg.m_xuan==1)sanload(x,nn);
if(cholg.m_xuan==2)fangload(x,nn);
CString str;
int i;
// 创建画笔对象
CPen* pPenRed=new CPen;
// 红色画笔
pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));
// 创建画笔对象
CPen* pPenBlue=new CPen;
// 蓝色画笔
pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255));
//原序列垂直轴
pDC->MoveTo(50,10);
pDC->LineTo(50,230);
//原序列水平轴
pDC->MoveTo(50,110);
pDC->LineTo(350,110);
//绘制原序列X轴箭头
pDC->MoveTo(345,105);
pDC->LineTo(350,110);
pDC->LineTo(345,115);
//绘制原序列Y轴箭头
pDC->MoveTo(50,10);
pDC->LineTo(45,15);
pDC->MoveTo(50,10);
pDC->LineTo(55,15);
str.Format("原序列");
pDC->TextOut(70,10,str);
//FFT序列幅频垂直轴
pDC->MoveTo(400,10);
pDC->LineTo(400,180);
//FFT序列幅频水平轴
pDC->MoveTo(400,180);
pDC->LineTo(700,180);
//绘制FFT序列幅频X轴箭头
pDC->MoveTo(695,175);
pDC->LineTo(700,180);
pDC->LineTo(695,185);
//绘制FFT序列幅频Y轴箭头
pDC->MoveTo(400,10);
pDC->LineTo(395,15);
pDC->MoveTo(400,10);
pDC->LineTo(405,15);
str.Format("原序列经FFT所得的幅频特性");
pDC->TextOut(600,10,str);
//FFT序列相频垂直轴
pDC->MoveTo(400,250);
pDC->LineTo(400,450);
//FFT序列相频水平轴
pDC->MoveTo(400,350);
pDC->LineTo(700,350);
//绘制FFT序列相频X轴箭头
pDC->MoveTo(695,345);
pDC->LineTo(700,350);
pDC->LineTo(695,355);
//绘制FFT序列相频Y轴箭头
pDC->MoveTo(400,250);
pDC->LineTo(395,255);
pDC->MoveTo(400,250);
pDC->LineTo(405,255);
str.Format("原序列经FFT所得的相频特性");
pDC->TextOut(420,250,str);
//IFFT序列垂直轴
pDC->MoveTo(50,250);
pDC->LineTo(50,450);
//IFFT水平轴
pDC->MoveTo(50,350);
pDC->LineTo(350,350);
//绘制IFFT序列X轴箭头
pDC->MoveTo(345,345);
pDC->LineTo(350,350);
pDC->LineTo(345,355);
//绘制IFFT序列Y轴箭头
pDC->MoveTo(50,250);
pDC->LineTo(45,255);
pDC->MoveTo(50,250);
pDC->LineTo(55,255);
str.Format("原序列经FFT和IFFT所得序列");
pDC->TextOut(70,250,str);
// 选中当前蓝色画笔,并保存以前的画笔
CGdiObject* pOldPen = pDC->SelectObject(pPenBlue);
for(i=0;i<count;i++)
{
pDC->MoveTo(i+50,110);
pDC->LineTo(i+50,110-int(x[i].ShowReal()));
}
fft(x,nn);
for(i=0;i<count;i++){
ms[i]=x[i].abs();
}
pDC->SelectObject(pPenRed);
for(i=0;i<count;i++)
{
pDC->MoveTo(i+400,180);
pDC->LineTo(i+400,180-0.1*int(ms[i]));
}
for(i=0;i<count;i++){
phase[i]=x[i].arg();
}
for(i=0;i<count;i++)
{
pDC->MoveTo(i+400,350);
pDC->LineTo(i+400,350-int(50*phase[i]));
}
ifft(x,nn);
pDC->SelectObject(pPenBlue);
for(i=0;i<count;i++)
{
pDC->MoveTo(i+50,350);
pDC->LineTo(i+50,350-int(x[i].ShowReal())/dd);
}
delete[]ms;
delete[]x;
delete[]phase;
}
if(firolg.flag==1){
CString str;
int i;
// 创建画笔对象
CPen* pPenRed=new CPen;
// 红色画笔
pPenRed->CreatePen(PS_SOLID,1,RGB(255,0,0));
// 创建画笔对象
CPen* pPenBlue=new CPen;
// 蓝色画笔
pPenBlue->CreatePen(PS_SOLID,1,RGB(0,0, 255));
//原序列垂直轴
pDC->MoveTo(50,10);
pDC->LineTo(50,230);
//原序列水平轴
pDC->MoveTo(50,110);
pDC->LineTo(350,110);
//绘制原序列X轴箭头
pDC->MoveTo(345,105);
pDC->LineTo(350,110);
pDC->LineTo(345,115);
//绘制原序列Y轴箭头
pDC->MoveTo(50,10);
pDC->LineTo(45,15);
pDC->MoveTo(50,10);
pDC->LineTo(55,15);
str.Format("测试序列X(n)");
pDC->TextOut(70,10,str);
//FFT序列幅频垂直轴
pDC->MoveTo(400,10);
pDC->LineTo(400,180);
//FFT序列幅频水平轴
pDC->MoveTo(400,180);
pDC->LineTo(700,180);
//绘制FFT序列幅频X轴箭头
pDC->MoveTo(695,175);
pDC->LineTo(700,180);
pDC->LineTo(695,185);
//绘制FFT序列幅频Y轴箭头
pDC->MoveTo(400,10);
pDC->LineTo(395,15);
pDC->MoveTo(400,10);
pDC->LineTo(405,15);
str.Format("窗函数幅频特性|W(ejw)|");
pDC->TextOut(600,10,str);
//FFT序列相频垂直轴
pDC->MoveTo(400,250);
pDC->LineTo(400,450);
//FFT序列相频水平轴
pDC->MoveTo(400,450);
pDC->LineTo(700,450);
//绘制FFT序列相频X轴箭头
pDC->MoveTo(695,445);
pDC->LineTo(700,450);
pDC->LineTo(695,455);
//绘制FFT序列相频Y轴箭头
pDC->MoveTo(400,250);
pDC->LineTo(395,255);
pDC->MoveTo(400,250);
pDC->LineTo(405,255);
str.Format("滤波器衰减特性20lg(|H(ejw)|");
pDC->TextOut(420,250,str);
//IFFT序列垂直轴
pDC->MoveTo(50,250);
pDC->LineTo(50,450);
//IFFT水平轴
pDC->MoveTo(50,350);
pDC->LineTo(350,350);
//绘制IFFT序列X轴箭头
pDC->MoveTo(345,345);
pDC->LineTo(350,350);
pDC->LineTo(345,355);
//绘制IFFT序列Y轴箭头
pDC->MoveTo(50,250);
pDC->LineTo(45,255);
pDC->MoveTo(50,250);
pDC->LineTo(55,255);
str.Format("滤波后序列Y(n)");
pDC->TextOut(70,250,str);
// 选中当前蓝色画笔,并保存以前的画笔
CGdiObject* pOldPen = pDC->SelectObject(pPenBlue);
for(i=0;i<256;i++)
{
pDC->MoveTo(i+50,110);
pDC->LineTo(i+50,110-int(50*Xn[i]));
}
for(i=0;i<256;i++)
{
pDC->MoveTo(i+50,350);
pDC->LineTo(i+50,350-(50*I[i]));
}
pDC->SelectObject(pPenRed);
for(i=0;i<256;i++)
{
pDC->MoveTo(i+400,450);
pDC->LineTo(i+400,450+int(Hd[i]));
}
for(i=0;i<256;i++)
{
pDC->MoveTo(i+400,180);
pDC->LineTo(i+400,180-int(100*Hw[i]));
}
}
}
/////////////////////////////////////////////////////////////////////////////
// CSunView printing
BOOL CSunView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CSunView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CSunView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CSunView diagnostics
#ifdef _DEBUG
void CSunView::AssertValid() const
{
CView::AssertValid();
}
void CSunView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CSunDoc* CSunView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CSunDoc)));
return (CSunDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CSunView message handlers
void CSunView::fft(complex *x, int m)
{ complex *w;
float num=0;
int n=1;
complex u,temp,tm,wrecur,w_s;
complex *xi,*xj,*wptr;
int i,j,k,l,le,windex;
double arg;
if(m==0)return;
n=(int)pow(2,m);
le=n/2;
w=(complex*)calloc(le,sizeof(complex));
arg=PI/le;//计算pi/le
xj=w;
w_s.copy(cos(arg),-sin(arg));
wrecur.copy(1,0);
for (j=0;j<le;j++){
*xj=wrecur;
xj++;
wrecur=wrecur*w_s;
}
//反向调整数据//
j=0;
for(i=1;i<n;i++){
k=n;
for(int a=1;a<=m;a++){
k=k/2;
if(k<=j) j=j-k;
else{j=j+k;break;}
}
if(i<j){
xi=x+i;
xj=x+j;
temp =*xj;
*xj=*xi;
*xi=temp;
}
}
//fft计算//
le=1;
windex=n/2;
for(l=0;l<m;l++){
le=le*2;
wptr=w;
for(j=0;j<le/2;j++){
u=*wptr;
for(i=j;i<n;i=i+le){
xi=x+i;
xj=xi+le/2;
temp=*xi;
*xi=*xi+u*(*xj);
*xj=temp-u*(*xj);
}
wptr=wptr+windex;
}
windex=windex/2;
}
free(w);
}
void CSunView::load(complex *x,int n)
{int m=pow(2,n);
for(int i=0;i<m;i++){
x[i].copy(70*sin(i*PI/(m/2)),0);
}
}
void CSunView::sanload(complex *x,int n)
{int mm;
int m=1,g=0;
int d=0;
mm=pow(2,n);
for(int i=0;i<mm;i++){
g=g+m;
if(g==(mm/4)||g==0){
m=m*(-1);
}
d=20*g/(mm/16);
x[i].copy(d,0);
}
}
void CSunView::fangload(complex *x,int n)
{int m=0,g=1;
int mm;
mm=pow(2,n);
for(int i=0;i<mm;i++){
m++;
if(m<(mm/2)){
g=1;
}
if(m>(mm/2)){
g=-1;
}
x[i].copy(50*g,0);
}
}
void CSunView::OnChose()
{ if(cholg.DoModal()!=IDOK)
{
return;
}
// TODO: Add your command handler code here
if(cholg.m_jie==0)nn=4;
if(cholg.m_jie==1)nn=5;
if(cholg.m_jie==2)nn=6;
if(cholg.m_jie==3)nn=7;
if(cholg.m_jie==4)nn=8;
if(cholg.m_jie==5)nn=9;
cholg.flag=1;
Invalidate();
}
void CSunView::ifft(complex *x, int m)
{ complex *w;
float num=0;
int n=1;
complex u,temp,tm,wrecur,w_s;
complex *xi,*xj,*wptr;
int i,j,k,l,le,windex;
double arg;
if(m==0)return;
n=(int)pow(2,m);
le=n/2;
w=(complex*)calloc(le,sizeof(complex));
if(!w){
exit(1);
}
arg=PI/le;//计算pi/le
xj=w;
w_s.copy(cos(arg),sin(arg));
wrecur.copy(1,0);
for (j=0;j<le;j++){
*xj=wrecur;
xj++;
wrecur=wrecur*w_s;
}
//ifft计算//
le=n;
windex=1;
for(l=0;l<m;l++){
le=le/2;
wptr=w;
for(j=0;j<le;j++){
u=*wptr;
for(i=j;i<n;i=i+2*le){
xi=x+i;
xj=xi+le;
temp=*xi;
*xi=((*xi+(*xj)));
*xj=((temp-(*xj))*u);
}
wptr=wptr+windex;
}
windex=windex*2;
}
//反向调整数据//
j=0;
for(i=1;i<n;i++){
k=n;
for(int a=1;a<=m;a++){
k=k/2;
if(k<=j) j=j-k;
else{j=j+k;break;}
}
if(i<j){
xi=x+i;
xj=x+j;
temp =*xj;
*xj=*xi;
*xi=temp;
}
}
free(w);
}
void CSunView::OnDofir() {
if(firolg.DoModal()!=IDOK)
{
return;
}
UpdateData();
int i;
m_a=(firolg.m_nn-1)/2;
Wn=new double[firolg.m_nn];
Hd=new double[firolg.m_nn];
Hw=new double[256];
Hn=new double[256];
I=new double[256];
Xn=new double[256];
Hd=new double[256];
Ww=new double[256];
xy=new complex[256];
orig=new complex[256];
buf=new complex[256];
double Wc=PI*firolg.m_Wc;
for(i=0;i<256;i++){
Hn[i]=0; Xn[i]=0;
}
for(i=0;i<firolg.m_nn;i++){ //产生窗函数
switch(firolg.m_type){
case 0: Wn[i]=1.0; break;
case 1: Wn[i]=0.54-0.46*cos(PI_2*i/(firolg.m_nn-1)); break;
case 2: Wn[i]=0.5*(1-cos(PI_2*i/(firolg.m_nn-1))); break;
case 3: Wn[i]=0.42-0.5*cos(PI_2*i/(firolg.m_nn-1))+0.08*cos(4*PI*i/(firolg.m_nn-1)); break;
default: break;
}
// TODO: Add your command handler code here
if(i!=m_a)
Hd[i]=sin(Wc*(i-m_a))/(i-m_a)/PI;
else Hd[i]=Wc/PI;
Hn[i]=Wn[i]*Hd[i];
}
for(int j=0;j<256;j++){
xy[j].copy(Hn[j],0);
}
fft(xy,8);
for(i=0;i<256;i++){
Hw[i]=xy[i].abs();
}
double model;
model=Hw[0];
for(i=0;i<256;i++)
{Ww[i]=Hw[i]/model;
}
for(i=0;i<256;i++)
{ Hd[i]=20*log10(Ww[i]); }
double low=PI*firolg.m_low;//待测序列
double high=PI*firolg.m_high;
for(i=0;i<256;i++)
Xn[i]=cos(i*low)+cos(i*high);
for(i=0;i<256;i++){
orig[i].copy(Xn[i],0);
}
fft(orig,8);
for(i=0;i<256;i++){//由时域卷积定理:时域卷积==>频域乘积
buf[i]=orig[i]*xy[i];
}
ifft(buf,8);//用付里叶反变换求得结果序列Y(n)---存入I
for(i=0;i<256;i++){
I[i]=buf[i].ShowReal()/256;
}
firolg.flag=1;
Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -