Matlab - 表面的周期性平铺

时间:2015-11-26 15:11:27

标签: matlab

我有一个表示藤壶分布(随机生成)的表面,但是某些点是在所需区域之外生成的。我希望从表面生成的任何点重新出现在另一侧。

这样,如果你把这个表面想象成一个'瓦片',当无限瓦片放下时没有跳跃或间隙,它是周期性的。

clear

n_gaussians=20;         % number of barnacles
gaussians=0;            
sigma=1;                % std deviation
mindist=0.8*sigma;      % if distance is smaller than this gaussians "collide" and are not plotted
height=0.3;             % height of the barnacle

[x,y]= meshgrid(-5:0.05:5,-5:0.05:5);
used=[];
Z=zeros(size(x));
while gaussians<n_gaussians

    xm=(rand(1)-0.5)*10;
    ym=(rand(1)-0.5)*10;
    notvalid=0;

        for ii=1:size(used,2)
        % if we are too close to any point.
       if norm([xm-used(1,ii),ym-used(2,ii)])<mindist
           notvalid=1; % do not add this gauusian
       end
    end
    if notvalid
        continue
    end
    used(:,end+1)=[xm;ym];
    Zaux = height/sigma*exp(-5*((x-xm).^2+(y-ym).^2)/sigma.^2)-0.1;
    Zaux(Zaux<0)=0;
    Z=Z+Zaux;
    gaussians=gaussians+1;
end

surf(x,y,Z);
axis equal
shading interp

这张照片有希望解释所需要的内容:

enter image description here

我还需要保持间距,所以如果xm,ym在图的另一侧的高斯分布的距离内,则需要打折。

我试图让这个工作,但我似乎找不到办法。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:5)

我们的想法是通过mod将轴包裹在边缘值周围。有了你的默许:-)我冒昧地重写你的代码:

n_gauss = 20;
k_gauss = 0;            
sigma   = 1;
mindist = 0.8*sigma;
height  = 0.3;
L       = 5;
dL      = 0.05;

[x,y] = meshgrid(-L:dL:L, -L:dL:L);
used  = NaN(2,n_gauss);
Z     = zeros(size(x));
while k_gauss < n_gauss
        xm = (rand-0.5)*2*L;
        ym = (rand-0.5)*2*L;

        valid = true;
        for k = 1:k_gauss
                Dx = mod(abs(used(1,k)-xm),2*L);
                Dy = mod(abs(used(2,k)-ym),2*L);
                if norm([Dx;Dy]) < mindist
                        valid = false;
                        break;
                end;
        end;

        if valid
                Dx = mod(x-xm,2*L)-L;
                Dy = mod(y-ym,2*L)-L;
                Zaux = height/sigma ...
                     * exp(-5*(Dx.^2 + Dy.^2)/sigma.^2) - 0.1;
                Zaux(Zaux<0) = 0;
                Z = Z + Zaux;

                k_gauss = k_gauss+1;
                used(:,k_gauss) = [xm;ym];
        end;
end

surf(x,y,Z);
axis equal;
shading interp;