[英]How to generate a matrix with a function pattern?
背景信息 (可選閱讀):
我正在模擬聲波在邊界上的反射。 使用矩陣設置空間點的介質條件。 假設空間的尺寸是N
× N
網格,並且我關心的是兩種音速, c0
和c1
。
現在,我正在使用類似以下的代碼來生成屏障模式
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
要么
% 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);
但是,我無法生成具有不同曲率的更復雜的邊界。
題
我想以編程方式創建具有反映功能的模式的矩陣。 例如,我想輸入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 ]
或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]
我還能夠生成類似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 ]
實際上, N
至少為128,因此為具有某種程度復雜性的形狀手動創建這些矩陣是不切實際的,我認為這是一個有趣的問題。
有人知道這樣做的方法嗎,或者對替代方法的建議?
先感謝您。
編輯:我修改這個實現布氏算法,以提供給定的起點和終點所需的行的矩陣。
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
像這樣實現:
c1 = 0;
M = bresenham_line([1 1 Nx/2+1 Ny+1]);
medium.sound_speed = c0*ones(Nx,Ny) - (c0*M) + c1*M;
彎曲函數形狀尚無進展。
盡管這樣最好,但我最好打賭布雷森漢姆的算法可能會有點“骯臟”。
N = 128;
[X,Y] = meshgrid(1:N,1:N);
bound1 = Y<2*X;
bound2 = Y<2*X+1;
M = xor(bound1,bound2);
bound1
可以定義任何函數y=f(x)
,並標記其下的區域。 使用bound2
您選擇的區域會稍高一些(向上移動)。 一旦你把和xor
兩個區域的,你得到的只是所需的y=f(x)
標記。 我認為,為了獲得合理的結果,對於更復雜的功能而言,移位可能有所不同。
為了說明起見,我使用了imagesc
( flipud
僅用於使(0,0)
位於左下角,而不是左上角):
imagesc(flipud(M));
編輯
確實,對於某些功能,這可能不是最好的。 例如,對於y=x^2
,您必須增加偏移量,但看起來仍然不太好。
bound1 = Y<X.^2;
bound2 = Y<X.^2+15;
M = xor(bound1,bound2);
一種獲得類似結果的方法:
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)
因此,您可以選擇函數,然后矩陣中的結果將看起來像是正態plot
的離散化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.