Guy Wald
Guy Wald

Reputation: 599

Matlab: Get neighboring coordinate values - && Operand

I'm trying to extract from a 2-D matrix with id values the neighboring ids of each element on the board.

I have a list of of IDs and their coordinates (of n elements), and I'm creating the following: (Example for left neighbor only).

%Left:
leftIndex = (currentLocationIndex - bSize);
hasLeft = leftIndex >= 1; %If element on first col, value will be 0 or negative
hasLeft = hasLeft(:) & board(leftIndex)==0;

I get: Subscript indices must either be real positive integers or logicals.

I want to use the pricipal of && operand or some other logic. the leftIndex contains all the indices left to a current index in the table. Some are legal some arn't. If hasLeft vector is true then the leftIndex vector value is legal in the 'board'.

How can I check for a neighbor in a certain value of the vector only if the hasLeft is true?

Thanks!

Upvotes: 0

Views: 1229

Answers (3)

user3709529
user3709529

Reputation: 11

my approach for solving this issue was using the “try” statement to determent if an index is legal and then assign it, if it is.

this is the closest thing I found to a straightforward check index legality command.

here is a code to illustrate

initialization

M=4;  N=5;             
Mat=rand(M,N);
m=2; n=1;              

the code: try to access this element... assign the element as a legal Neighbor only if Succeeded

near= [m,n-1;m,n+1;m+1,n;m-1,n]; 
Neibs=[];          

for i =1:4
    try
        Mat(near(i,1),near(i,2));  
        Neibs=[Neibs;[near(i,1),near(i,2)]]; 
    catch
    end
end

results presentation

BW=zeros(M,N);
if ~isempty(Neibs)
    for i =1:length(Neibs(:,1))
        BW(Neibs(i,1),Neibs(i,2))=true;
    end
end

of course once the point is made, changing the size, dimensions, or neighborhood metrica is not a problem

Upvotes: 1

Floris
Floris

Reputation: 46405

Reading your question more carefully, and answering only what you asked for (which became clearer after I had read some of your other recent questions...):

The first problem you run into is the fact that your array leftIndex may contain values < 1, and therefore cannot legally be used in the expression hasLeft = hasLeft(:) & board(leftIndex)==0;

To get around this, you neeed to index board with only "valid" indices, which you can get by changing the previous line to

hasLeft = find(leftIndex >= 1);

Note that your original, hasLeft = leftIndex >= 0; generates a logical array of "true" and "false" values of the same size as leftIndex. By contrast, the find command returns only the indices of the elements that meet the criteria. Now we need to do two more things: 1) find the elements in board with a valid index and a value >=0; and 2) map these back to the index of the "whole thing" (not the index in the subarray). Here is how you do it:

interestingSquare = (board(hasLeft)==0);
hasLeft = hasLeft(interestingSquare);

This last line takes you back from "position of an interesting square in the sub-array 'hasLeft'" to "position relative to the original leftIndex array.

I do wonder whether you really meant to test for board == 0 but I'm sure that if that was a typo, you would figure it out...

Upvotes: 1

Floris
Floris

Reputation: 46405

I would do two things:

First, find "all the neighbors" including the "illegal" ones. For example, if the indices are n, m then all "potential neighbors" are [pn pm]= meshgrid(n+(-1:1), m+(-1:1));. Note this also includes the point itself.

Second, mask out only "legal" neighbors by testing their value against the limits of the array. If you have a 2D array with size N by M, you could use

legal = find(pn>0 && pn <= N && pm > 0 && pm <= M && ~(pn==n && pm==m));

That should give you (up to 8) all legal neighbors. Obviously if you don't want the "kitty corner" neighbors you change the statement that created pn and pm. I hope you get the idea.

Upvotes: 2

Related Questions