从点到矩阵的螺旋环 [英] Spiral loop on a matrix from a point

查看:107
本文介绍了从点到矩阵的螺旋环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下的2D网格,想从X,Y开始并保存窗口的角(W)和(OP)的重叠.我已经尝试过这些代码,但都不适合我的目的.

如所示,我想从一个随机点(黑色单元格)开始,并以螺旋循环的方式保存每个新窗口的角位置(以黑色圆圈显示).该算法应用于任何网格尺寸(不一定是正方形)和任何起点位置.

Matlab还具有与我想要的功能类似的功能(螺旋),但它不需要网格,窗口大小和重叠(OP).

我希望该图具有以下输出:(8,12) (11,12) (11,9) (8,9) (4,9) (4,12) (4,15) ...

我正在使用以下代码,这些代码从一个角开始,并使用定义的W,OP和矩阵大小逐步填充矩阵:

W = [10 12];
OP = [4 3];

M = zeros(100,110);

for i=[1:W(1)-OP(1):size(M,1)-W(1), size(M,1)-W(1)+1]
  for j=[1:W(2)-OP(2):size(M,2)-W(2), size(M,2)-W(2)+1]
      block = rand(W(1),W(2));
      M(i:i+W(1)-1, j:j+W(2)-1) = block;
      imagesc(M); axis equal tight xy
      pause(.1)
  end;
end;

因此,以一种更清晰的方式,我应该如何更改上方"代码,以便从位置(x,y)开始并根据W,OP和size(M)螺旋填充整个矩阵. /p>

谢谢!

解决方案

这是一段可产生预期输出的代码.在那里,只需对spiral_generic进行较小的更改即可满足您的要求:

function demo()
spiral_generic([10,11],[3,4])
W = [10 12];
OP = [4 3];
%make sure your start point is really on the grid of r and c, this is not checked!
start = [19,28];
M = zeros(100,110);
r=[1:W(1)-OP(1):size(M,1)-W(1), size(M,1)-W(1)+1];
c=[1:W(2)-OP(2):size(M,2)-W(2), size(M,2)-W(2)+1];
startindex=[find(r==start(1),1,'first'),find(c==start(2),1,'first')];
A=spiral_generic([numel(r),numel(c)],startindex);
[~,idx]=sort(A(:));
[ridx,cidx]=ind2sub(size(A),idx);
%blocks contains the lower left corners in order of processing.
blocks=[r(ridx);c(cidx)];
for blockindex=blocks
       block = rand(W(1),W(2));
       M(blockindex(1):blockindex(1)+W(1)-1, blockindex(2):blockindex(2)+W(2)-1) = block;
       imagesc(M);
       pause(.1)
end

end
function A = spiral_generic(n, P)
% Makes NxN matrix filled up spirally starting with point P
  r = max([P - 1, n - P]);              % Radius of the bigger matrix
  M = spiral(2 * r + 1);                % Bigger matrix itself
  M = permute(M,[2,1]);                 % changing start direction of the spiral
  M = M(:,end:-1:1);                    % chaning spin orientation
  C = r + 1 - (P - 1);                  % Top-left corner of A in M
  A = M(C(1):C(1)+n(1)-1, C(2):C(2)+n(2)-1);  % Get the submatrix
  [~, order] = sort(A(:));              % Get elements' order
  A(order) = 1:(n(1)*n(2));                     % Fill with continous values
end

I have a 2D grid as follow and want to start from X, Y and save the corner of a window (W) and overlap of (OP). I have tried these codes, but non of them are fit to my purpose.

As it is demonstrated, I want to start from a random point (black cell) and save the corner locations (shown by black circles) of each new window in a spiral loop. The algorithm should be used for any grid sizes (not square necessarily) and any start point locations.

Matlab also has a function (spiral) that is similar to what I want, but it does not take a grid, window size and overlap (OP).

I expect to have the following output for this figure: (8,12) (11,12) (11,9) (8,9) (4,9) (4,12) (4,15) ...

I am using the following codes which starts from a corner and fill the matrix step-by-step using the defined W, OP and Matrix size:

W = [10 12];
OP = [4 3];

M = zeros(100,110);

for i=[1:W(1)-OP(1):size(M,1)-W(1), size(M,1)-W(1)+1]
  for j=[1:W(2)-OP(2):size(M,2)-W(2), size(M,2)-W(2)+1]
      block = rand(W(1),W(2));
      M(i:i+W(1)-1, j:j+W(2)-1) = block;
      imagesc(M); axis equal tight xy
      pause(.1)
  end;
end;

So, in a more clear way, how should I change the "above" code in order to start from a location(x,y) and spirally fill the whole matrix according to W, OP and size(M).

Thanks!

解决方案

Here is a piece of code which produces the expected output. There where only minor changes to the spiral_generic necessary to match your requirements:

function demo()
spiral_generic([10,11],[3,4])
W = [10 12];
OP = [4 3];
%make sure your start point is really on the grid of r and c, this is not checked!
start = [19,28];
M = zeros(100,110);
r=[1:W(1)-OP(1):size(M,1)-W(1), size(M,1)-W(1)+1];
c=[1:W(2)-OP(2):size(M,2)-W(2), size(M,2)-W(2)+1];
startindex=[find(r==start(1),1,'first'),find(c==start(2),1,'first')];
A=spiral_generic([numel(r),numel(c)],startindex);
[~,idx]=sort(A(:));
[ridx,cidx]=ind2sub(size(A),idx);
%blocks contains the lower left corners in order of processing.
blocks=[r(ridx);c(cidx)];
for blockindex=blocks
       block = rand(W(1),W(2));
       M(blockindex(1):blockindex(1)+W(1)-1, blockindex(2):blockindex(2)+W(2)-1) = block;
       imagesc(M);
       pause(.1)
end

end
function A = spiral_generic(n, P)
% Makes NxN matrix filled up spirally starting with point P
  r = max([P - 1, n - P]);              % Radius of the bigger matrix
  M = spiral(2 * r + 1);                % Bigger matrix itself
  M = permute(M,[2,1]);                 % changing start direction of the spiral
  M = M(:,end:-1:1);                    % chaning spin orientation
  C = r + 1 - (P - 1);                  % Top-left corner of A in M
  A = M(C(1):C(1)+n(1)-1, C(2):C(2)+n(2)-1);  % Get the submatrix
  [~, order] = sort(A(:));              % Get elements' order
  A(order) = 1:(n(1)*n(2));                     % Fill with continous values
end

这篇关于从点到矩阵的螺旋环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆