本帖最后由 交响无际 于 2022-10-22 22:21 编辑
https://rtaylor.sites.tru.ca/2014/11/03/lateral-reflections-in-rectangular-rooms-code/
刚刚基于这个室内反射理论算了一下6x6m房间
按6ms设定,得到的计算结果是,建议两个音箱的距离是3.14米
音箱距离前墙大于1.75米,距离侧墙约1.5米,听音位距离后墙约1.5米
今天我已经不能上传图片了,明天再发上来吧
听音位距离后墙的距离参数,可以再微调一点,我试了1.2~2.1米,都是可以的,再小或再大的话,音箱间距就会减小了
挺简单的,把下面这个代码,粘贴到http://asymptote.ualberta.ca/网页中间的workspace.asy,点一下上面Run按钮,右边就出图了
/* relftime.asy
Richard Taylor 03.11.2014
An asymptote (asymptote.sourceforge.net) script.
This draws a rectangular room plan with superimposed contours that
show, for any given loudspeaker placement, the resulting arrival time
delay (for a fixed listening position) between the direct sound and
the first lateral reflection.
Additionally, for each of the four walls a red contour is drawn to
show the loudspeaker placements that give exactly 6ms delay for
reflection from that wall. The shaded region indicates speaker
placements for ≥6ms delay from all walls.
The listening position is marked with a green triangle. Dashed lines
are shown as a guide: a pair of loudspeaker speakers placed
symmetrically on these lines will form an equilateral triangle with
the listening position. */
import contour;
import graph;
unitsize(3cm);
// room dimensions [m]:
real Lx = 6;
real Ly = 6;
// listening position [m] (relative to back-left corner):
real ly = 1.5;
real lx = 0.5*Lx;
// target minimum delay [ms]:
real mindelay = 6.0;
pair listener = (lx,ly);
// function to calculate arrival time difference [ms] for direct and
// reflected sound.
// x1 = distance from source to wall [m]
// x2 = distance from listener to wall [m]
// y = source-listener lateral separation parallel to wall [m]
real rt(real x1, real x2, real y) {
real dd = sqrt( (x1-x2)^2 + y^2 ); // direct-sound path length
real dr = sqrt( (x1+x2)^2 + y^2 ); // reflected-sound path length
return (dr-dd)/0.343;
}
real rtT(real x, real y) { // refl. from top, source at (x,y)
return rt( Ly-y, Ly-ly, x-lx );
}
real rtB(real x, real y) { // refl. from bottom, source at (x,y)
return rt( y, ly, x-lx );
}
real rtR(real x, real y) { // refl. from right, source at (x,y)
return rt( Lx-x, Lx-lx, y-ly );
}
real rtL(real x, real y) { // refl. from right, source at (x,y)
return rt( x, lx, y-ly );
}
real rtmin(real x, real y) { // min. delay for all boundaries
return min( rtT(x,y), rtB(x,y), rtL(x,y), rtR(x,y) );
}
// shade region where delay is at least 6ms:
guide[][] g=contour(rtmin,(0,0),(Lx,Ly),new real[] {mindelay});
fill(g[0],mediumgrey);
// guide lines for equilateral loudspeaker placement:
picture equiguide=new picture;
real L=sqrt(Lx^2+Ly^2);
path equilateral = (listener+L*dir(120))--listener--(listener+L*dir(60));
draw(equiguide, equilateral, dashed );
clip(equiguide,(0,0)--(Lx,0)--(Lx,Ly)--(0,Ly)--cycle);
add(equiguide);
// mark listening position:
draw( listener, marker(scale(2mm)*polygon(3),FillDraw(green) ) );
// draw 6ms contour for each reflection:
draw( new Label[] {Label("FRONT WALL",Relative(0.6),Center,UnFill(1bp))},
contour(rtT,(0,0),(Lx,Ly),new real[] {mindelay}), red+linewidth(2) );
draw( new Label[] {Label("REAR WALL",Relative(0.4),Center,UnFill(1bp))},
contour(rtB,(0,0),(Lx,Ly),new real[] {mindelay}), red+linewidth(2) );
draw( new Label[] {Label("LEFT WALL",Relative(0.15),Center,UnFill(1bp))},
contour(rtL,(0,0),(Lx,Ly),new real[] {mindelay}), red+linewidth(2) );
draw( new Label[] {Label("RIGHT WALL",Relative(0.15),Center,UnFill(1bp))},
contour(rtR,(0,0),(Lx,Ly),new real[] {mindelay}), red+linewidth(2) );
// add contours for first-reflection delay times:
int n=5;
real[] c=new real[n];
for(int i=0; i < n; ++i) c=i+1; // contour levels
Label[] Labels=sequence(new Label(int i) {
return Label(c != 0 ? format("$%0.0f$\,ms" ,c) : "",
Relative(0.49 - 0.01*i/n),(0,0), UnFill(1bp));
},c.length);
draw( Labels, contour(rtmin,(0,0),(Lx,Ly),c, nx=100, ny=100) );
// draw room boundaries:
draw( (0,0)--(Lx,0)--(Lx,Ly)--(0,Ly)--cycle, blue+linewidth(2) );
// add some axes:
xaxis(Label("$x$ [meters]",Relative(0.5)),BottomTop,RightTicks,xmin=0);
yaxis(Label("$y$ [meters]",Relative(0.5)),LeftRight,LeftTicks,ymin=0);
// show max. stereo separation with equilateral placement and 6ms delay:
path contour6 = g[0][0];
pair[] furthestpoints = intersectionpoints(equilateral, contour6);
pair p1 = furthestpoints[0]; pair p2 = furthestpoints[1];
draw( Label(format("$%0.2f$\,m", length(p2-p1)), LeftSide),
p1--p2, dashed, Arrows );
|