Simple ArrayIndex problem

Hi!
I`ve a simple problem, but i couldnt find a solution.
Im building a function that generate points, and i want to draw a line between those points, building a triangle:

float size = 200;
ArrayList<PVector>positions;
float angle = 120;

void setup(){
  size(1000, 1000);
  positions = new ArrayList<PVector>();
  
    for(int i = 0; i < 3; i++){
        float x = size*sin(radians(120)*i);
        float y = size*cos(radians(120)*i);      
        positions.add(new PVector(x, y));
    }
}


void draw(){
  
  
translate(500, 500);
for(int i = 0; i < positions.size(); i++){
  PVector a = positions.get(i);
  PVector b = positions.get(i+1);  // NEXT POINT - here is the problem-
  
   line(a.x ,a.y, b.x, b.y);
  ellipse(a.x, a.y, 10, 10);
}
}

i understand that i+1 eventually goes to exceed the array size. How can i get a index+1 position in array without go more that the size in the array?

1 Like

Hello,

Examine this very closely and you will understand:

PVector a = new PVector(0,0);
PVector b = new PVector(0,0);
  
translate(500, 500);
for(int i = 0; i < positions.size()-1; i++)
  {
  a = positions.get(i);
  b = positions.get(i+1);  // NEXT POINT - here is the problem-
  
  strokeWeight(2);
  line(a.x ,a.y, b.x, b.y);
  ellipse(a.x, a.y, 10, 10);
  }

ellipse(b.x, b.y, 10, 10);

:)

1 Like

Hi!, thanks for the answer. Your example is work fine, but if i want to draw a triangle like in my example, the segment from index 2 to index 0 is miss

ing:

float size = 200;
ArrayList<PVector>positions;
float angle = 120;
PVector a;
PVector b;

void setup() {
  size(1000, 1000);
  positions = new ArrayList<PVector>();

  for (int i = 0; i < 3; i++) {
    float x = size*sin(radians(120)*i);
    float y = size*cos(radians(120)*i);      
    positions.add(new PVector(x, y));
  }
}


void draw() {


  translate(500, 500);
  for (int i = 0; i < positions.size()-1; i++) {
    a = positions.get(i);

    b = positions.get(i+1);

    line(a.x, a.y, b.x, b.y);
    ellipse(a.x, a.y, 10, 10);
  }
}
1 Like

Hello,

Same idea… at the end of and after the loop finish things off.

void draw() 
  {
  translate(500, 500);

  for (int i = 0; i < positions.size()-1; i++) 
    {
    a = positions.get(i);
    b = positions.get(i+1);

    strokeWeight(2);
    ellipse(a.x, a.y, 10, 10);
    line(a.x, a.y, b.x, b.y);
    }

    a = positions.get(?);
    line(?);
    ellipse(?);
    }
1 Like

Ok, you are drawing the line outside the loop.
The problem still exist, because in fact i only want the pair of points (0-1, 1-2, 2-0)

Hello,

There is no problem on this end…
You have complete control over what your code does and the order that you place the shapes.
You have to choose the correct closing co-ordinates.

void draw() 
  {
  background(255);
  translate(500/2, 500/2);
  strokeWeight(2);

  for (int i = 0; i < positions.size()-1; i++) 
    {
    a = positions.get(i);
    b = positions.get(i+1);

    line(a.x, a.y, b.x, b.y);
    ellipse(a.x, a.y, 10, 10);
    }

    a = positions.get(?);
    b = positions.get(?);
    line(?);
    ellipse(?);
    ellipse(?); // This was an extra finishing touch so circle was on top of line.
    }

:)

I leave this with you.

1 Like

If you want to iterate over pairs of vertices in a closed shape, you can also use modulo %.

for (int i=0; i<pos.size(); i++) {
   a = pos.get(i);
   b = pos.get( (i+1)%pos.size() );
}

This works for any size. For a size of 3, this will generate:

0,1 – 1,2 – 2,0

2 Likes

I think there is nothing wrong with that

1 Like

Keep in mind that, if you are safely converting each index with %, you can access more than the next point – you can access three points, or every tenth point, and at any offset.

Here is an example that draws a series of triangles based on a ring of points, constantly changing its starting points and offsets. As frameCount and step both increase, code is eventually using i values like:

1270 1292 1314

but instead of getting index errors, with modulo they access safe indices in the ArrayList of size 24 – points:

22, 20, 18

/**
 * Accessing points like a circular array
 * 2020-04-14 Processing 3.4 
 */
ArrayList<PVector> points;
int num = 24;
int step = 1;

void setup() {
  size(600,600);
  points = new ArrayList<PVector>();
  // circle of points
  for (int i=0; i<num; i++) {
    float x = width * 4/9.0 * sin(TWO_PI*i/(float)num);
    float y = height * 4/9.0 * cos(TWO_PI*i/(float)num);
    points.add(new PVector(x, y));
  }
}

void draw(){
  background(128);
  translate(width/2,height/2);
  PVector p1, p2, p3;
  // count from anywhere
  for (int i=frameCount; i<frameCount+points.size(); i++) {
    // access points 
    p1 = points.get(i%points.size());
    p2 = points.get((i+step)%points.size());
    p3 = points.get((i+2*step)%points.size());
    triangle(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
  }
  println(frameCount, frameCount+step, frameCount+2*step);
  if(frameCount%60==0) step++;
}

CircularArrayAccess--screenshot--small

2 Likes