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

📄 form1.java

📁 切比雪夫滤波器设计,JAVA编写,VJ编译
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;
import com.ms.wfc.html.*;
import com.ms.wfc.io.*;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Toolkit;

public class Form1 extends Form
{
	
	public Form1()
	{
		
		super();
		initForm();	
		new iirtwo_explain().showDialog(this);
		
	}

	
	public void dispose()
	{
		super.dispose();
		components.dispose();
		
	}

		
//定义变量//画图显示类:public int keepleft=50,keepright=50,keepup=50,keepdown=50;//绘图区位置设定public float steppelix=2;//绘图时每两个点之间的象素距离(均匀绘图,引用时转为整数)
public double ysize=100;//绘图的纵向幅度public Color backcolor=Color.BLACK;//默认背景颜色;public Color zbcolor=Color.WHITE;//默认坐标颜色;public Color drawcolor=Color.GREEN;//默认绘图颜色;public Color textcolor=Color.CYAN;//默认字符颜色;//控制变量类:public boolean Xinputed=false,Yinputed=false;//输入序列X【】以及滤波器特性是否已经被定义;public boolean solved=false;//在输入序列已经定义的情况下,是否已经经过处理;public boolean isfft=true;//是否是用快速算法计算
public int displaywhichdata=-1;
//控制显示内容:0时:输入x【】;1:输入h【】;2:输出序列y【】;3:幅频特性;4:相频特性;5:极点位置;//处理数据对象类:
public int MaxLength=4096;//最多可以输入的数据点数public int totallength,current=0;//数组总长度,当前屏幕起始点public int displaynum;//一屏幕可以显示的点数public int N;//基2_fft的N值public int bitlength;
public double x[],y[];//输入序列,单位取样响应;输出序列;(没有扩充成2的N次方,记录原始数据);注意:从1开始定义public complex X[],Y[];//待处理序列;注意:从1开始定义
public int rank,rankMAX=20;//数字滤波器的阶数,以及允许的最大阶数
public double Qc;//数字滤波器的截至频率
public double omiga;
public complex P[],A[];//(从序号0开始)//记录极点位置;记录系统函数Ha(S)部分分式形式的分解系数;
public complex Br[],Ak[];//标准差分方程的系数参数(从0开始定义)
public double K0;//归一化常数


iirfilterset myframe=new iirfilterset();

public double complexabs(complex x){
	return Math.sqrt(x.Re*x.Re+x.Im*x.Im);
}

public complex complexadd(complex x,complex y){
	complex a=new complex();
	a.Re=x.Re+y.Re;
	a.Im=x.Im+y.Im;
	return a;	
}

public complex complexsub(complex x,complex y){
	complex a=new complex();
	a.Re=x.Re-y.Re;
	a.Im=x.Im-y.Im;
	return a;	
}

public complex complexmult(complex x,complex y){
	complex a=new complex();
	a.Re=x.Re*y.Re-x.Im*y.Im;
	a.Im=x.Im*y.Re+x.Re*y.Im;
	return a;	
}
public complex complexdiv(complex x,complex y){
	complex a=new complex();
	complex b=new complex();
	b.Re=y.Re;b.Im=-y.Im;
	a=complexmult(x,b);
	a.Re/=complexabs(y)*complexabs(y);
	a.Im/=complexabs(y)*complexabs(y);
	return a;
}

public double arch(double x){
	return Math.log(x+Math.sqrt(x*x-1))/Math.log(Math.E);	
}
public double arsh(double x){	return Math.log(x+Math.sqrt(x*x+1))/Math.log(Math.E);
}public double sh(double x){	return Math.exp(x)/2-Math.exp(-x)/2;
}public double ch(double x){	return Math.exp(x)/2+Math.exp(-x)/2;
}
public int getN(int processlength){//获得基2_fft的N值
	for(int i=1;;i++){
		if((int)Math.pow(2,i)==processlength){bitlength=i;break;}
		if((int)Math.pow(2,i)<processlength&&(int)Math.pow(2,i+1)>processlength){
			bitlength=i+1;break;}
		}//for
	return (int)Math.pow(2,bitlength);
	}public void fft(){//fft核心算法
	//注:本程序数组从1开始定义,运行此程序之前将要处理的数据存入复数数组X【】;
	int NV2,NM1,K,L;
	int I,J,IP,LE,LE1;
	double tr,ti,ur,ui,wr,wi,mid;
	complex T=new complex();
	//重新排序
	NV2=N/2;NM1=N-1;
	J=1;I=1;
	do{
		if(I<J){
			T.Re=X[J].Re;T.Im=X[J].Im;//T=X[J];
			X[J].Re=X[I].Re;X[J].Im=X[I].Im;//X[J]=X[I];
			X[I].Re=T.Re;X[I].Im=T.Im;//X[I]=T;
			}
		K=NV2;
		while(K<J){
			J-=K;K=K/2;}
		J+=K;I+=1;
		}while(I<=NM1);
	//重新排序结束
	//fft核心算法开始
	L=1;
	do{
		LE=(int)Math.pow(2,L);
		LE1=LE/2;
		ur=1;ui=0;
		wr=Math.cos(Math.PI/(double)(LE1));wi=-Math.sin(Math.PI/(double)(LE1));
		J=1;
		do{
			I=J;
			do{
				IP=I+LE1;
				tr=X[IP].Re*ur-X[IP].Im*ui;
				ti=X[IP].Re*ui+X[IP].Im*ur;//T=X[IP]*U;
				X[IP].Re=X[I].Re-tr;
				X[IP].Im=X[I].Im-ti;//X[IP]=X[I]-T;
				X[I].Re+=tr;
				X[I].Im+=ti;//X[I]=X[I]+T;
				I=I+LE;
				}while(I<=N);
			mid=ur;
			ur=ur*wr-ui*wi;
			ui=mid*wi+ui*wr;//U=U*W;
			J=J+1;
			}while(J<=LE1);
		L=L+1;
		}while(L<=bitlength);
	//fft核心算法结束
	}

public void panel_paint(Object source, PaintEvent e)//这里用的坐标系是panel的坐标,即panel的左上角为(0,0)
{ 
	//一屏可以显示的点数
	if(this.displaywhichdata==0||this.displaywhichdata==2||this.displaywhichdata==6||this.displaywhichdata==7){
	this.displaynum=(int)((this.panel.getWidth()-1)/this.steppelix);
	if(totallength<=displaynum){
		scroll.setEnabled(false);this.current=0;		this.lastlabel.setText("");		}
	else{
		scroll.setEnabled(true);
		scroll.setMaximum(totallength-displaynum);
		this.lastlabel.setText(String.valueOf(this.current+this.displaynum));
		}
	}
	else this.scroll.setEnabled(false);
	//设置背景色
	panel.setBackColor(backcolor);
	
	if(this.displaywhichdata==0){//显示输入序列x【】
		this.currentlabel.setText(String.valueOf(this.current+1));
		//绘制坐标	
		e.graphics.setPen(new Pen(zbcolor,PenStyle.SOLID,3));
		e.graphics.drawLine(0,panel.getHeight()/2,panel.getWidth(),panel.getHeight()/2);
		//绘制数据
		e.graphics.setPen(new Pen(drawcolor,PenStyle.SOLID,1));
		for(int i=0;i<=((this.totallength<displaynum)?(this.totallength-1):(displaynum-1));i++){
			e.graphics.drawLine((int)(steppelix*i),panel.getHeight()/2,(int)(steppelix*i),panel.getHeight()/2-(int)(this.ysize*x[i+current+1]));
		}
		}//显示输入序列x【】
	
	if(this.displaywhichdata==2){//显示输出序列y【】
		this.currentlabel.setText(String.valueOf(this.current+1));
		//绘制坐标	
		e.graphics.setPen(new Pen(zbcolor,PenStyle.SOLID,3));
		e.graphics.drawLine(0,panel.getHeight()/2,panel.getWidth(),panel.getHeight()/2);
		//绘制数据
		e.graphics.setPen(new Pen(drawcolor,PenStyle.SOLID,1));
		
		for(int i=0;i<=((this.totallength<displaynum)?(this.totallength-1):(displaynum-1));i++){
			e.graphics.drawLine((int)(steppelix*i),panel.getHeight()/2,(int)(steppelix*i),panel.getHeight()/2-(int)(this.ysize*y[i+current]));
		}
		
		
		}//显示输入序列y【】
	if(this.displaywhichdata==3){//显示幅频特性
		this.scroll.setEnabled(false);
		int x0=40;
		int y0=this.panel.getHeight()-20;
		int height=y0-10;
		int width=this.panel.getWidth()-x0-10;
		//绘制坐标	
		e.graphics.setPen(new Pen(zbcolor,PenStyle.SOLID,2));
		for(int i=0;i<=10;i++){//横向10格纵向10格
			e.graphics.drawLine(x0,y0-height*i/10,x0+width,y0-height*i/10);//横向
			e.graphics.drawLine(x0+width*i/10,y0-height,x0+width*i/10,y0);//纵向
		}
		//绘制文字
		e.graphics.setTextColor(zbcolor);
		for(int i=0;i<=5;i++){//纵向写6个
			e.graphics.drawString(String.valueOf(-i*20)+"dB",5,5+height*i/5);
		}
		e.graphics.drawString("0",x0-5,y0+5);//纵向写6个
		for(int i=1;i<5;i++){
			e.graphics.drawString(String.valueOf((float)(0.2*i))+"π",x0+width*i/5-10,5+y0);
		}
		e.graphics.drawString("π",x0+width-5,y0+5);
		//画数据
		e.graphics.setPen(new Pen(drawcolor,PenStyle.SOLID,2));
		for(double w=0;w<=Math.PI;w+=0.01){
			double xx=K0;
			double nextxx=K0;
			for(int i=0;i<P.length;i++){
				xx/=Math.sqrt(P[i].Re*P[i].Re+(w-P[i].Im)*(w-P[i].Im));
				//if(i<P.length-1){
				nextxx/=Math.sqrt(P[i].Re*P[i].Re+((w+0.01)-P[i].Im)*(w+0.01-P[i].Im));
				//}
			}//for
			e.graphics.drawLine(x0+(int)(width*w/Math.PI),10-(int)(10*Math.log(xx)*height/100),x0+(int)(width*(w+0.01)/Math.PI),10-(int)(10*Math.log(nextxx)*height/100));
		}//for
		double xx=K0;
		for(int i=0;i<P.length;i++)	xx/=Math.sqrt(P[i].Re*P[i].Re+(Qc-P[i].Im)*(Qc-P[i].Im));
		//e.graphics.
		//e.graphics.setPixel(x0+(int)(width*Qc/Math.PI),10-(int)(10*Math.log(xx)*height/100),Color.RED);
		e.graphics.setPen(new Pen(Color.RED,PenStyle.SOLID,2));
		e.graphics.drawLine(x0+(int)(width*Qc/Math.PI)-2,10-(int)(10*Math.log(xx)*height/100)-2,x0+(int)(width*Qc/Math.PI)+2,10-(int)(10*Math.log(xx)*height/100)+2);
		e.graphics.drawLine(x0+(int)(width*Qc/Math.PI)-2,10-(int)(10*Math.log(xx)*height/100)+2,x0+(int)(width*Qc/Math.PI)+2,10-(int)(10*Math.log(xx)*height/100)-2);
		}//显示幅频特性
	
	if(this.displaywhichdata==4){//显示相频特性
		this.scroll.setEnabled(false);
		int x0=40;
		int y0=this.panel.getHeight()-20;
		int height=y0-10;
		int width=this.panel.getWidth()-x0-10;
		//绘制坐标	
		e.graphics.setPen(new Pen(zbcolor,PenStyle.SOLID,2));
		for(int i=0;i<=10;i++){//横向10格纵向10格
			e.graphics.drawLine(x0,y0-height*i/10,x0+width,y0-height*i/10);//横向
			e.graphics.drawLine(x0+width*i/10,y0-height,x0+width*i/10,y0);//纵向
		}
		//绘制文字
		e.graphics.setTextColor(zbcolor);
		for(int i=0;i<=5;i++){//纵向写6个
			e.graphics.drawString(String.valueOf(180-i*72)+"°",2,5+height*i/5);
		}
		e.graphics.drawString("0°",2,5+height/2);
		
		e.graphics.drawString("0",x0-5,y0+5);//纵向写6个
		for(int i=1;i<5;i++){
			e.graphics.drawString(String.valueOf((float)(0.2*i))+"π",x0+width*i/5-10,5+y0);
		}
		e.graphics.drawString("π",x0+width-5,y0+5);
		//画数据
		e.graphics.setPen(new Pen(drawcolor,PenStyle.SOLID,2));
		for(double w=0;w<=Math.PI;w+=0.01){
			double xx=0;
			double nextxx=0;
			for(int i=0;i<P.length;i++){
				xx-=Math.atan((w-P[i].Im)/(-P[i].Re));
				nextxx-=Math.atan((w+0.01-P[i].Im)/(-P[i].Re));
				}//for
			while(xx<-Math.PI)xx+=2*Math.PI;
			//if(xx>Math.PI)xx-=2*Math.PI;
			while(nextxx<-Math.PI)nextxx+=2*Math.PI;
			//if(nextxx>Math.PI)nextxx-=2*Math.PI;				
			//e.graphics.drawLine(x0+(int)(width*w/Math.PI),10+height/2-(int)(((xx<Math.PI)?(xx+2*Math.PI):(xx))*height/Math.PI),x0+(int)(width*(w+0.01)/Math.PI),10+height/2-(int)(((nextxx<Math.PI)?(nextxx+2*Math.PI):(nextxx))*height/Math.PI));
			e.graphics.drawLine(x0+(int)(width*w/Math.PI),10+height/2-(int)(xx*height/Math.PI/2),x0+(int)(width*(w+0.01)/Math.PI),10+height/2-(int)(nextxx*height/Math.PI/2));
		}//for
		
		}//显示相频特性
	if(this.displaywhichdata==5){//S域数字滤波器的极点位置
		this.scroll.setEnabled(false);
		int x0=panel.getWidth()/2;
		int y0=panel.getHeight()/2;
		//int r=(int)(this.panel.getHeight()/2/Qc);//半径
		//绘制坐标	
		e.graphics.setPen(new Pen(zbcolor,PenStyle.SOLID,3));
		e.graphics.drawLine(0,y0,2*x0,y0);//横轴
		e.graphics.drawLine(x0,0,x0,2*y0);//纵轴
		e.graphics.setTextColor(zbcolor);
		e.graphics.drawString("jΩ",x0+5,5);
		e.graphics.drawString("σ",2*x0-10,y0+5);
		e.graphics.drawString("0",x0+5,y0+5);
		//e.graphics.drawString("Ωc",x0+this.panel.getHeight()/2,y0-15);
		e.graphics.drawString("滤波器阶数N="+String.valueOf(rank),300,30);
		e.graphics.drawString("截止频率Ωc="+String.valueOf(Qc),300,50);
		e.graphics.drawString("通带波动ε="+String.valueOf(omiga),300,70);
		
		double alpha=1/omiga+Math.sqrt(1/omiga/omiga+1);
		double a=(Math.pow(alpha,1/(double)rank)-Math.pow(alpha,-1/(double)rank))/2;
		double b=(Math.pow(alpha,1/(double)rank)+Math.pow(alpha,-1/(double)rank))/2;
		int r=(int)(this.panel.getHeight()/2/Qc/b);//半径
		//绘制单位椭圆
		e.graphics.setPen(new Pen(zbcolor,PenStyle.DOT,1));
		for(double i=0;i<=360;i+=1.5){//i为角度参数
			//e.graphics.drawLine(x0+(int)(r*Math.cos(i*Math.PI/180)),y0-(int)(r*Math.sin(i*Math.PI/180)),x0+1+(int)(r*Math.cos((i)*Math.PI/180)),y0+1-(int)(r*Math.sin((i)*Math.PI/180)));
			e.graphics.setPixel(x0+(int)(r*a*Qc*Math.cos(i*Math.PI/180)),y0-(int)(r*b*Qc*Math.sin(i*Math.PI/180)));
		}
		e.graphics.setPen(new Pen(drawcolor,PenStyle.SOLID,2));
		for(int i=0;i<P.length;i++){//花极点
			e.graphics.drawLine(x0+(int)(r*P[i].Re-2),y0-(int)(r*P[i].Im-2),x0+(int)(r*P[i].Re+2),y0-(int)(r*P[i].Im+2));
			e.graphics.drawLine(x0+(int)(r*P[i].Re-2),y0-(int)(r*P[i].Im+2),x0+(int)(r*P[i].Re+2),y0-(int)(r*P[i].Im-2));
		}
		}//S域数字滤波器的极点位置
	if(this.displaywhichdata==6||this.displaywhichdata==7){
		this.currentlabel.setText(String.valueOf(this.current+1));
		//绘制坐标	
		e.graphics.setPen(new Pen(zbcolor,PenStyle.SOLID,3));
		e.graphics.drawLine(0,panel.getHeight()/2,panel.getWidth(),panel.getHeight()/2);
		//绘制数据
		e.graphics.setPen(new Pen(drawcolor,PenStyle.SOLID,1));
		for(int i=0;i<=((this.totallength<displaynum)?(this.totallength-1):(displaynum-1));i++){
			e.graphics.drawLine((int)(steppelix*i),panel.getHeight()/2,(int)(steppelix*i),panel.getHeight()/2-(int)(this.ysize*Math.sqrt(X[i+current+1].Re*X[i+current+1].Re+X[i+current+1].Im*X[i+current+1].Im)));
			}
	}
	}//画图结束

private void menusavefile_click(Object source, Event e)//保存当前数据到文件
{  
	if(this.displaywhichdata==-1){//当前没有显示任何数据
		MessageBox.show("当前没有任何数据可供保存!","警告!",MessageBox.OK+MessageBox.ICONWARNING);
		}
	else if(this.displaywhichdata==3||this.displaywhichdata==4||this.displaywhichdata==5){//滤波器的频率特性(模拟信号不能保存)
		MessageBox.show("当前数据不能保存为离散序列信号!","警告!",MessageBox.OK+MessageBox.ICONWARNING);
	}
	else{//当前有文件可供保存
		SaveFileDialog sfd = new SaveFileDialog();
		sfd.setTitle("保存当前数据");
		sfd.setFilter("数据文件(*.mydata)|*.mydata");
		int result = sfd.showDialog();  
		if (result == DialogResult.OK) { 
			File mydata;
			mydata=File.create(sfd.getFileName());
			if(this.displaywhichdata==0){//如果当前数据是输入序列x【】
				mydata.writeInt(this.totallength);//数据长度
				for(int i=1;i<=this.totallength;i++){
					mydata.writeDouble(x[i]);
				}
				}
			
			if(this.displaywhichdata==2){//如果当前数据是输出序列y【】
				mydata.writeInt(this.totallength);//数据长度
				for(int i=0;i<this.totallength;i++){
					mydata.writeDouble(y[i]);	
				}
				}
			if(this.displaywhichdata==6||this.displaywhichdata==7){
				mydata.writeInt(this.totallength);//数据长度
				for(int i=1;i<=this.totallength;i++){
					mydata.writeDouble(Math.sqrt(X[i].Re*X[i].Re+X[i].Im*X[i].Im));	
				}
				
			}
			mydata.close();//关闭文件
			}
	}//else:当前有文件可供保存
}

private void menuexit_click(Object source, Event e)
{
	this.dispose();
}

private void scroll_valueChanged(Object source, Event e)//拖动滚动条
{
	this.current=this.scroll.getValue();
	this.panel.invalidate();
}

private void inputXdefault_click(Object source, Event e)//定义x[]:输入典型波形
{
	inputdefaultdata myframe=new inputdefaultdata();//从1开始定义的
	myframe.max=this.MaxLength;
	int result=myframe.showDialog(this);
	if(result==DialogResult.YES){//点击确认按钮后,将数据初始化给x[]
		x=new  double[myframe.data.length];
		for(int i=1;i<=x.length-1;i++){//注意!因为数组从1开始初始化,所以序列长度为myframe.data.length-1
			x[i]=myframe.data[i];
			}
		Xinputed=true;//数据初始化完成!
		this.displaywhichdata=0;
		this.totallength=x.length-1;
		this.label1.setText("当前显示数据:输入序列x[]");
		this.label3.setText("数据总长度:"+this.totallength+"");
		this.timelabel.setText("");
		this.ysize=100;
		this.steppelix=2;
		this.scroll.setValue(0);
		this.current=0;
		this.panel.invalidate();
		solved=false;//尚未处理;
		}
}

private void inputXonebyone_click(Object source, Event e)//定义x[]:逐点定义
{
	inputonebyone myframe=new inputonebyone();
	myframe.max=this.MaxLength;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -