[英]How to generate a matrix with a function pattern?
Background info (Optional reading): 背景信息 (可选阅读):
I'm running simulations of reflections of sound waves in against boundaries. 我正在模拟声波在边界上的反射。 The medium conditions for the points in space are set using a matrix.
使用矩阵设置空间点的介质条件。 Let's say the dimensions of the space is an
N
by N
grid, and there are two speeds of sound I care about, c0
and c1
. 假设空间的尺寸是
N
× N
网格,并且我关心的是两种音速, c0
和c1
。
Right now I'm using code like the following to generate barrier patterns 现在,我正在使用类似以下的代码来生成屏障模式
medium.sound_speed = c0*ones(N,N); % set the speed of sound to be c0 everywhere
medium.sound_speed(:, N/2:N) = c1; % set the right half of the grid to a different speed
medium.sound_speed(50:70, 50:70) = c1; % set a box to have a different speed
Or 要么
% set all speeds to c0 except set the diagonal to c1
medium.sound_speed = c0*ones(N,N)-(c0*eye(N,N))+c1*eye(N,N);
However, I can't generate more complex boundaries with different curvatures. 但是,我无法生成具有不同曲率的更复杂的边界。
Question 题
I want to programmatically create matrices with patterns reflecting functions. 我想以编程方式创建具有反映功能的模式的矩阵。 For instance, I want to enter
f(x)=2
and for that to create a matrix that looked something like this, assuming N=6
. 例如,我想输入
f(x)=2
并为此创建一个看起来像这样的矩阵,假设N=6
。
[ 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
1 1 1 1 1 1
0 0 0 0 0 0
0 0 0 0 0 0 ]
Or f(x)=0.5*x+1
或
f(x)=0.5*x+1
[ 0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 1 1
0 0 1 1 0 0
1 1 0 0 0 0
0 0 0 0 0 0]
I would also be able to generate curved patterns like f(x)=1/x
, which seems to require some form of the Midpoint circle algorithm , used for drawing curvatures with pixels. 我还能够生成类似
f(x)=1/x
弯曲图案,这似乎需要某种形式的Midpoint圆算法 ,用于绘制带有像素的曲率。
[ 1 0 0 0 0 0
1 0 0 0 0 0
0 1 0 0 0 0
0 0 1 1 0 0
0 0 0 0 1 1
0 0 0 0 0 0 ]
In reality, N
is at least 128, so manually creating these matrices for shapes with some level of complexity is impractical, and I thought this was an interesting problem. 实际上,
N
至少为128,因此为具有某种程度复杂性的形状手动创建这些矩阵是不切实际的,我认为这是一个有趣的问题。
Does anyone know of some way to do this, or suggestions for alternative approaches? 有人知道这样做的方法吗,或者对替代方法的建议?
Thank you in advance. 先感谢您。
Edit: I modified this implementation of Bresenham's algorithm to provide a matrix with the desired line given an origin and an ending point. 编辑:我修改这个实现布氏算法,以提供给定的起点和终点所需的行的矩阵。
function M=bresenham_line(point)
if (abs(point(4)-point(2)) > abs(point(3)-point(1))) % If the line is steep
x0 = point(2);y0 = point(1); x1 = point(4);y1=point(3);% then it would be converted to
token =1; % non steep by changing coordinate
else
x0 = point(1);y0 = point(2); x1 = point(3);y1=point(4);
token = 0;
end
if(x0 >x1)
temp1 = x0; x0 = x1; x1 = temp1;
temp2 = y0; y0 = y1; y1 = temp2;
end
dx = abs(x1 - x0) ; % Distance to travel in x-direction
dy = abs(y1 - y0); % Distance to travel in y-direction
sx = sign(x1 - x0); % sx indicates direction of travel in X-dir
sy = sign(y1 - y0); % Ensures positive slope line
x = x0; y = y0; % Initialization of line
param = 2*dy - dx ; % Initialization of error parameter
for i = 0:dx-1 % FOR loop to travel along X
x_coord(i+1) = x; % Saving in matrix form for plot
y_coord(i+1) = y;
param = param + 2*dy; % parameter value is modified
if (param >0) % if parameter value is exceeded
y = y +1*sy; % then y coordinate is increased
param = param - 2*(dx ); % and parameter value is decreased
end
x = x + 1*sx; % X-coordinate is increased for next point
end
M = zeros(size(x_coord,2), size(y_coord,2));
for i=1:1:size(x_coord,2)
x = x_coord(i);
y = y_coord(i);
M(x,y) = 1;
end
M
Implemented like so: 像这样实现:
c1 = 0;
M = bresenham_line([1 1 Nx/2+1 Ny+1]);
medium.sound_speed = c0*ones(Nx,Ny) - (c0*M) + c1*M;
No progress on curved function shapes yet. 弯曲函数形状尚无进展。
This is a slightly 'dirty' way of getting something like this, although I you best bet might Bresenham's algorithm. 尽管这样最好,但我最好打赌布雷森汉姆的算法可能会有点“肮脏”。
N = 128;
[X,Y] = meshgrid(1:N,1:N);
bound1 = Y<2*X;
bound2 = Y<2*X+1;
M = xor(bound1,bound2);
bound1
you can define any function y=f(x)
, and mark the area under it. bound1
可以定义任何函数y=f(x)
,并标记其下的区域。 with bound2
you select and area that is slightly higher (shifted up). 使用
bound2
您选择的区域会稍高一些(向上移动)。 Once you take and xor
of the two area you get just the desired y=f(x)
marked. 一旦你把和
xor
两个区域的,你得到的只是所需的y=f(x)
标记。 I think that in order to get reasonable results the shift might be different for more complicated function. 我认为,为了获得合理的结果,对于更复杂的功能而言,移位可能有所不同。
For illustration I used imagesc
(the flipud
is just for make the (0,0)
in the bottom left, instead of the top left): 为了说明起见,我使用了
imagesc
( flipud
仅用于使(0,0)
位于左下角,而不是左上角):
imagesc(flipud(M));
Edit 编辑
Indeed for some function this might not be the best. 确实,对于某些功能,这可能不是最好的。 For example for
y=x^2
, you have to increase the shift and still does not look great. 例如,对于
y=x^2
,您必须增加偏移量,但看起来仍然不太好。
bound1 = Y<X.^2;
bound2 = Y<X.^2+15;
M = xor(bound1,bound2);
A way to get some similar results: 一种获得类似结果的方法:
f = @(x)0.5*x; %create the function (x should be written even if the function doesn't depend on x: @(x) 0*x + 2)
N = 6; %choose the size of the atrix
M = zeros(N,N); %create an empty matrix
x = (1:N);
y = round(f(x-1)); %discretization
x(y>N-1|y<0) = [];
y(y>N-1|y<0) = [];
M(sub2ind(size(M),y+1,x)) = 1;
M = flipud(M)
So you can choose your function, then the result in your matrix will look like a discretization of a normal plot
. 因此,您可以选择函数,然后矩阵中的结果将看起来像是正态
plot
的离散化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.