声场可视化 (MATLAB)

能看到声场是很酷的,然而想要看到它同时也是很麻烦。我们需要一个立体的矩阵,记录空间中每一点的声场。
但从观察的角度,我们不需要看到空间中的每一个点,一般我们会在一个平面上来观察声场,或者在一个球面上观察声场(球坐标系在声学领域有着非常广泛的应用)。

SET UP

我们将声源放在水平面上 距离中心1.5m处,并且只关注最简单的情况,即我们只观察声源的一个特定的频率,以1000Hz为例。空间是free field,因而不存在反射,声音的传播符合格林函数。
% constant
c = 344;
% source position
rad = 1.5;
theta = pi/3;
phi = pi/2;
[src_x, src_y, src_z] = sph2cart(theta, pi/2-phi, rad);
freq=1000;
omega = 2*pi*freq;
k = omega/c;

平面上的声场可视化

要在平面上可视化声场,我们首先初始化一个grid作为坐标系,一般需要3个维度x,y,z,但也可以比较简单的认定z=0,因为我们关注的就是z=0的平面。之后用格林函数计算每个坐标的值。
lx = 3;
ly = 3;
[canvas_x, canvas_y, canvas_z] = meshgrid(-lx/2:0.01:lx/2, -ly/2:0.01:ly/2, 0);
dist_src = sqrt((src_x-canvas_x).^2+(src_y-canvas_y).^2+(src_z-canvas_z).^2);
p = real(exp(-1j*k*dist_src)./dist_src);
pcolor(p);
caxis([-1,1]);
shading interp;
axis image; axis xy
colorbar;

球面上的声场可视化

要在球面上进行声场可视化,主要的问题要选择一个grid,可以比较均匀的覆盖整个球面。我这里选择的是Maximun determinant grids。
一般采样点的个数由HOA的阶数决定。
ord = 20;
n_samples = (ord+1)^2;
file_name = ['md', sprintf('%03d', ord), '.', sprintf('%05d', n_samples)];
md = load(['./md/', file_name]);
rad_sph = 0.5;
xm = rad_sph*md(:, 1:3); % samples positions
weightm = md(:, 4)'; % quadrature weights
dist_src2 = sqrt((src_x-xm(:,1)).^2+(src_y-xm(:,2)).^2+(src_z-xm(:,3)).^2);
p2 = real(exp(-1j*k*dist_src2)./dist_src2);
msh=convhull(xm);
trisurf(msh,xm(:,1),xm(:,2),xm(:,3),p2);
caxis([-1,1]);
shading interp;
axis equal;
axis vis3d;
colorbar;
view([60 30])