如何生成具有函数模式的矩阵?

时间:2016-11-15 20:21:19

标签: algorithm matlab function math matrix

背景信息(可选阅读):

我正在模拟声波对边界的反射。使用矩阵设置空间中的点的介质条件。假设空间的维度为Complex N网格,我关注的声音有两种,Nc0

现在我正在使用如下代码生成屏障模式

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] 这样的弯曲图案,这似乎需要某种形式的Midpoint circle algorithm,用于绘制带像素的曲率。

f(x)=1/x

实际上,[ 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 ] 至少为128,因此手动为具有某种复杂程度的形状创建这些矩阵是不切实际的,我认为这是一个有趣的问题。

有没有人知道某种方法可以做到这一点,还是有其他方法的建议?

提前谢谢。

修改 我修改了Bresenham算法的this实现,以提供给定起点和终点的所需行的矩阵。

N

如此实施:

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

弯曲功能形状尚无进展。

2 个答案:

答案 0 :(得分:2)

这是一种稍微“肮脏”的方式来获得这样的东西,尽管我最好打赌Bresenham的算法。

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)标记。我认为,为了获得合理的结果,更复杂的功能可能会有所不同。

为了说明,我使用了imagescflipud仅用于在左下方而不是左上角设置(0,0)

imagesc(flipud(M));

修改

对于某些功能来说,这可能不是最好的。例如,对于y=x^2,您必须增加班次,但仍然看起来不太好。

bound1 = Y<X.^2;
bound2 = Y<X.^2+15;
M = xor(bound1,bound2);

答案 1 :(得分:2)

获得类似结果的方法:

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的离散化。