我有一个如下所示的 2D 网格,想要从 X、Y 开始并保存窗口 (W) 的角和 (OP) 的重叠。我试过these代码,但没有一个符合我的目的。
正如演示的那样,我想从一个随机点(黑色单元格)开始,并在螺旋循环中保存每个新窗口的角位置(由黑色圆圈显示)。该算法应用于任何网格大小(不一定是正方形)和任何起点位置。
Matlab还有一个函数(spiral)和我想要的类似,但是它不需要网格,窗口大小和重叠(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 和大小(M)螺旋填充整个矩阵。
谢谢!
最佳答案
基本问题
让数据定义为:
step = 3; %// step size
x0 = 8; %// x coordinate of origin
y0 = 12; %// y coordinate of origin
N = 32; %// number of steps
然后螺旋的坐标可以作为复平面中的值获得如下†:
z = x0+1j*y0 + step*cumsum([0 -1j.^(-floor(sqrt(4*(0:N)+1))-1)]);
当然,x 和y 坐标就是
x = real(z);
y = imag(z);
使用上面给出的示例值,plot(z,'o-')
(或 plot(x,y,'o-')
)生成图形
† 关键是生成序列 1,2,3,3,4,4,5,5,5,6,6,6,7, 7,7,7,8,8,8,8...
我感谢 OEIS solving that part .该序列结果是 4n+1 的平方根的整数部分,对于 n=1,2,3,...
如何包含重叠和窗口大小
考虑到重叠,遵循 Daniel's suggestion , 从 step
中减去它的值。
要考虑窗口大小,N
应该足够大,以便螺旋线到达窗口边界外的某个点;然后只保留前面的点。
由于预先计算N
应该有多大是很困难的,一种可能的方法是指数在一个循环中增加N
直到它足够大。指数增长确保循环迭代的次数会很少。下面的代码对 N
使用 2 的幂。
%// Data
step = 3; %// step size
overlap = 1; %// overlap
x0 = 20; %// x coordinate of origin
y0 = 15; %// y coordinate of origin
xmin = 0; %// window boundary: min x
xmax = 40; %// window boundary: max x
ymax = 30; %// window boundary: min y
ymin = 0; %// window boundary: max y
%// Computations
stepov = step-overlap;
N = 8; %// Initial value. Will be increased as needed
done = false;
while ~done
z = x0+1j*y0 + stepov*cumsum([0 -1j.^(-floor(sqrt(4*(0:N)+1))-1)]);
%// compute coordinates of N points
ind = find(real(z)<xmin | real(z)>xmax | imag(z)<ymin | imag(z)>ymax, 1);
%// find index of first z out of boundary, if any
done = ~isempty(ind); %// exit if we have reached outside window boundary
N = N*2; %// increase number of steps for next try
end
z = z(1:ind-1); %// only keep values that are within the boundary
x = real(z);
y = imag(z);
根据代码中的数据,得到的图如下。请注意,最后一点是 (38,0)。下一个点是 (38,-2),它位于窗口边界之外。
关于arrays - 从一点在矩阵上的螺旋循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29466058/