1,复习一下三角函数的基本知识
2,生成一段模拟信号(模拟仪器采样)
/**
* 生成一段模拟信号,模拟采样
* @param fs 采样频率
* @param n 采样点数
* 模拟的这段信号包括的频率有10hz, 15hz, 20hz, 26.5hz,这段信号包括直流信号15
* 注意:根据采样定理,采样频率必须大于信号频率的2倍
* 因此,传递过来的采样频率务必要大于26.5 * 2
*/
private double[] generateWaveNormal(float fs, int n) {
double pi = Math.PI;
double[] res = new double[n];
float interval = 1 / fs;//采样间隔,单位是s
for (int i = 0; i < n; i++) {
double t = interval * i;
res[i] = 15 + 1 * Math.cos(2 * pi * 10 * t) + 2 * Math.sin(2 * pi * 15 * t + Math.toRadians(30))
+ 3 * Math.cos(2 * pi * 20 * t + Math.toRadians(-30)) + 4 * Math.sin(2 * pi * 26.5 * t + Math.toRadians(60));
}
return res;
}
3,对采集的信号生成频谱
/**
* 正常的输出波形,正常的傅里叶变换,没有补零的操作
* 频率分辨率 = 采样频率 / 参与傅里叶变换的点数,注意是参与傅里叶变换的点数而非采样点数,因为可能补零
* 傅里叶变换结果的频率计算,第n个点的频率 = 频率分辨率 * (n - 1)
* 所谓频谱,横轴是频率,纵轴是振幅,也就是频率振幅谱
*/
@Test
public void test1(){
//模拟采样
int Fs = 100;//采样频率
int N = 256;//采样点数
double[] wave = generateWaveNormal(Fs, N);
log(Arrays.toString(wave));
//对采样结果进行傅里叶变换,使用commons-math包
FastFourierTransformer fft = new FastFourierTransformer(DftNormalization.STANDARD);
Complex[] result = fft.transform(wave, TransformType.FORWARD);
log(Arrays.toString(result));
//计算第一个傅里叶变换结果的振幅
Complex complex0 = result[0];
double amp0 = Math.sqrt(Math.abs(complex0.getReal()) * Math.abs(complex0.getReal())
+ Math.abs(complex0.getImaginary()) * Math.abs(complex0.getImaginary())) * 1.0 / N;
log(amp0);
//计算剩余傅里叶变换结果的振幅,正式应用中只用计算到N / 2即可,因为是堆成
for(int i = 1; i < N; i++){
Complex complex = result[i];
double amp = Math.sqrt(Math.abs(complex.getReal()) * Math.abs(complex.getReal())
+ Math.abs(complex.getImaginary()) * Math.abs(complex.getImaginary())) * 2.0 / N;
log(amp);
}
}
4,使用excel画图
分析:频率分辨率 = 100 / 256;第27个点的频率 = 26 * 100 / 256 = 10.15,正好对应的是原始信号里面的1 * cos(2 * pi * 10 * t)。其他3个点类推即可,比如第39个点的频率 = (39 - 1) * 100 / 256 = 14.84,正好对应的原始信号里面2 * Math.sin(2 * pi * 15 * t + Math.toRadians(30))