We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › getting surrounding points in a matrix
Page Index Toggle Pages: 1
getting surrounding points in a matrix (Read 1562 times)
getting surrounding points in a matrix
Dec 31st, 2009, 6:20am
 
Hi, i have a matrix (30x30) that looks like this :
...

they are stored in an 1d array. So i can acess every point with one number in one loop.
so first line is 0-29, second is 30-59 and so on.

my question now is, if i got the number of the red point. How would i calculate the numbers of the surrounding yellow ones?
Must be some formula i just cant think of.

Thx
cedric
Re: getting surrounding points in a matrix
Reply #1 - Dec 31st, 2009, 7:31am
 
A useful start would be to able to calculate the position in the array (p) with its x/y position. If the grid width is 'w' then
Code:

// converting x/y > p
p = x + y * w;
// converting p > x/y
x = p % w;
y = p / w;


So next step
Code:

// Visit neighbours to p
x = p % w;
y = p / w;
for(int i = -2; i<=2; i++){
  for(int j = -2; j <= 2; j++){
      // ignore itself
      if(i != 0 && j != 0){
          // neighbour is at np
          np = (x+i) + (y+j)*w;
      }
  }
}


Of course you need to take care of the situation when the red point is close to one side.
Smiley
Re: getting surrounding points in a matrix
Reply #2 - Dec 31st, 2009, 9:28am
 
thank you! looks good. i tried to implement it in my simple grid example. But couldnt get it to work. So how, would i now color the surrounding points green?

just leave the "close to one side" beside...

Code:

int w = 10;

smooth();
strokeWeight(4);
for(int y = 0; y<w;y++){
 for(int x = 0; x<w;x++){
   int p = x + y * w;
   stroke(0);

   if(p==25)stroke(250,0,0); // turn no 25 red
   point(x*10,y*10);  


 }
}

//where to add this ?
   x = p % w;
   y = p / w;
   for(int i = -2; i<=2; i++){
for(int j = -2; j <= 2; j++){
 // ignore itself
 if(i != 0 && j != 0){
   // neighbour is at np
   int np = (x+i) + (y+j)*w;

   println(np);

 }
}
   }
Re: getting surrounding points in a matrix
Reply #3 - Dec 31st, 2009, 12:16pm
 
This should make it much clearer.
Code:


int w = 30, h = 30;
int[] g;

void setup(){
 size(400,400);
 g = new int[w*h];
 clearGrid(color(0));
 smooth();
 strokeWeight(4);
 cursor(CROSS);
}

void draw(){
 background(255);
 int x,y;
 for(int p = 0; p < g.length; p++){
   x = p % w;
   y = p / w;
   stroke(g[p]);
   point(10 + x* 10, 10+y*10);
 }
}

void mouseClicked(){
 int x = (mouseX - 10)/10;
 int y = (mouseY - 10)/10;
 // Ignore if outside grid
 if(x < w && y < h){
   clearGrid(color(0));
   selectGridLoc(x,y);
 }
}

void clearGrid(int col){
 for(int i = 0; i < g.length; i++)
   g[i] = col;
}

void selectGridLoc(int x, int y){
 int p = x + y * w;
 g[p] = color(255,0,0);
 for(int i = -2; i<=2; i++){
   for(int j = -2; j <= 2; j++){
     // ignore itself
     if(i != 0 || j != 0){
       // neighbour is at np
       int np = (x+i) + (y+j)*w;
       g[np] = color(0,255,0);
     }
   }
 }
}


Quote:
just leave the "close to one side" beside...

Ok I did try it and see what I mean.

Cheesy
Re: getting surrounding points in a matrix
Reply #4 - Jan 1st, 2010, 1:44pm
 
I would like to ignore the corner points (the ones that get green).
This in the selectGridLoc function.

Atm this are the values for i and j;

i  j
Quote:
-1 -1
-1 0
-1 1
0 -1
0 1
1 -1
1 0
1 1


The combinations that have to be ignored(cause they are for the corners) are the following:

Quote:
-1 -1
-1 1
1 -1
1 1


I tried something like:

Code:

// ignore itself
if(i != 0 || j != 0){
//ignore corners
if((i != -1) && (j != -1)){


Only that doesnt work cause a true false gets evaluated as false for examle. During typing this post i found a solution:

       if((i == -1 && j == 0) || (i == 0 && j == -1) || (i == 0 && j == 1) || (i == 1 && j == 0)){

Here i don't check for the corners but for the points i want.
But for the purpose of learning, is there a working way to check for the corners?

here's the code:

Code:

void selectGridLoc(int x, int y){
int p = x + (y * w);
g[p] = color(255,0,0);
for(int i = -1; i<=1; i++){
for(int j = -1; j <= 1; j++){
// ignore itself
if(i != 0 || j != 0){
//ignore corners
if((i == -1 && j == 0) || (i == 0 && j == -1) || (i == 0 && j == 1) || (i == 1 && j == 0)){
// neighbour is at np
println(i+" "+j);
int np = (x+i) + (y+j)*w;
g[np] = color(0,255,0);
}
}
}
}
}




Re: getting surrounding points in a matrix
Reply #5 - Jan 1st, 2010, 3:42pm
 
Since i need something simulair i worked on the edge problem.
So no crashing and no green dot on the extreme right on the grid if you select on the green left for example.

Code:
int w = 30, h = 30;
int[] g;

void setup(){
size(400,400);
g = new int[w*h];
clearGrid(color(0));
smooth();
strokeWeight(4);
cursor(CROSS);
}

void draw(){
background(255);
int x,y;
for(int p = 0; p < g.length; p++){
x = p % w;
//println("x = p % w;"+x);
y = p / w;
//println("y = p / w;"+y);
//println("y "+y+" x "+x);
//println(g[p]);
stroke(g[p]);

point(10 + x* 10, 10+y*10);
}
}

void mouseClicked(){
int x = (mouseX - 10)/10;
int y = (mouseY - 10)/10;
// Ignore if outside grid
if(x < w && y < h){
clearGrid(color(0));
selectGridLoc(x,y);
println("selectGridLoc(x,y); "+x+" "+y);
}
}

void clearGrid(int col){
for(int i = 0; i < g.length; i++)
g[i] = col;
}

void selectGridLoc(int x, int y){
int p = x + (y * w);
g[p] = color(255,0,0);
for(int i = -1; i<=1; i++){//x
for(int j = -1; j <= 1; j++){//y

if(y == 0)if(j == -1)j = 0;//top - avoid crash top
if(y == h-1)if(j == 1)break;//bottom - avoid crash top
if(x == 0)if(i == -1)i = 0;//left - avoid unwanted right when x == 0
if(x == w-1)if(i == 1)break;//right - avoid unwanted left when x == width

// ignore itself
if(i != 0 || j != 0){
//ignore corners
if((i == -1 && j == 0) || (i == 0 && j == -1) || (i == 0 && j == 1) || (i == 1 && j == 0)){
// neighbour is at np
println(i+" "+j);
int np = (x+i) + (y+j)*w;
g[np] = color(0,255,0);
}
}
}
}
}


For my preverious post, the anser is multiple if's right? Or is there still another solution?
Re: getting surrounding points in a matrix
Reply #6 - Jan 1st, 2010, 3:47pm
 
looks, good. could your code be changed so that you not only get the left,right,upper,lower points but also the ones in the corner (upper left, upper right lower left, lower right).

and how would you change the range, get not only the next but the 2,3,4 next points.
Re: getting surrounding points in a matrix
Reply #7 - Jan 4th, 2010, 5:30pm
 
Quote:
I would like to ignore the corner points (the ones that get green).
-1 -1
-1 1
1 -1
1 1


If you look at your cases you will see that you want to skip the cases when i & j are +/- 1. The easiest way to do this:

Code:

for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
// Ignore corners
if (abs(i)==1 && abs(j)==1)
continue;
if (i != 0 && j != 0) {
...
}
}
}


The abs function converts negative numbers to positive, and leaves positive numbers untouched.

The crashing problem you are experiencing is most likely because you are referencing invalid locations. The simple way to solve this is to compute x+i & y+j and then check if these values fall outside the limits 0 and width or height respectively.

HTH
Re: getting surrounding points in a matrix
Reply #8 - Jan 4th, 2010, 6:14pm
 
so how could this be implemented in the code posted by Quark in reply #3?
Re: getting surrounding points in a matrix
Reply #9 - Jan 5th, 2010, 10:01am
 
I believe that it's best to teach someone how to fish, rather than give them fish Smiley That said, I also appreciate the power of examples, so here we go:

Code:

void selectGridLoc(int x, int y){
 int p = x + y * w;
 g[p] = color(255,0,0);
 for(int i = -2; i<=2; i++){
   for(int j = -2; j <= 2; j++){
// skip corners
if (abs(i)==2 && abs(j)==2)
continue;

// ignore itself
if(i == 0 && j == 0)
continue;

int nx = x + i;
int ny = y + j;
// Skip out of range cells
if (nx < 0 || nx >= w)
continue;
if (ny < 0 || ny >= h)
continue;

// neighbour is at np
int np = nx + ny*w;
g[np] = color(0,255,0);
   }
 }
}


In this example there is a faster way to handle out of bounds cells without the additional predicates in the inner loop. Instead, you modify the range of i & j, so for example at the right edge of the screen i will only run in the range -2 to 0.

One other speed tip, re-arrange your loops so that x is in the inner loop and not y. Accessing the array in this order will give you better memory caching performance, a big deal on modern CPU's.
Page Index Toggle Pages: 1