Reputation: 45
Suppose the array is:
A = a b c
d e f
g h i
I want to copy the diamond arrangement, i.e. the elements d,b,f,h,e into a new 1D array. The above array is just an example, the matrix could be any size rectangular matrix and the location of the diamond can be anywhere within the array.
Upvotes: 2
Views: 553
Reputation: 13945
Here is a solution that could work if you have the Image Processing Toolbox.
When performing morphological operations, there is a structuring element in the shape of a diamond that you can use (check here). Now if we play around with it we can extract the elements from a matrix like so. Note that since you have strings in A I use a cell array:
clear
clc
A = {'a' 'b' 'c';'d' 'e' 'f'; 'g' 'h' 'i'}
SE = strel('diamond', 1)
Matlab tells us that SE
has the following attributes (actually it might not be an attribute...I don't know the right terminology sorry :P):
SE =
Flat STREL object containing 5 neighbors.
Neighborhood:
0 1 0
1 1 1
0 1 0
Therefore, we can use the getnhood
method of STREL as logical indices to fetch the appropriates values in A:
NewMatrix = transpose(A(SE.getnhood()))
NewMatrix =
'd' 'b' 'e' 'h' 'f'
Here the transpose is used to get the values in the order from top to bottom, left to right.
So the whole code actually looks like this:
A = {'a' 'b' 'c';'d' 'e' 'f'; 'g' 'h' 'i'}
DSize = 1; %// Assign size to diamond.
SE = strel('diamond', DSize)
NewMatrix = transpose(A(SE.getnhood()))
If you need to move the diamond in the array to get its center somewhere else, you can translate the structuring element before using the last line. The function is appropriately named called translate
Hope that helps!
Upvotes: 1
Reputation: 112699
This works by building a mask (logical index) with the desired diamond shape and a specified center. The mask is obtained by computing the L1 (or taxicab) distance from each entry to the diamond center and comparing to the appropriate threshold:
A = rand(7,9); %// example matrix
pos_row = 3; %// row index of diamond center
pos_col = 5; %// col index of diamond center
[n_rows, n_cols] = size(A);
d = min([pos_row-1 pos_col-1 n_rows-pos_row n_cols-pos_col]); %// distance threshold
%// to be used for mask. Obtained by extending until some matrix border is found
ind = bsxfun(@plus, abs((1:n_rows).'-pos_row), abs((1:n_cols)-pos_col))<=d; %'// mask
result = A(ind); %// get entries defined by mask
Upvotes: 1
Reputation: 5188
Assuming that you are looking only for 5-elements diamonds, in the order you specified, you could do:
% Previously locate the position of the middle element (e)
% and store it in variable IND
[i, j] = ind2sub(size(A), IND);
J = sub2ind(size(A), i+[0 -1 0 1 0], j+[-1 0 +1 0 0]);
% Get diamond-linearized vector
dia = A(J);
Upvotes: 0