how to use ArrayList in Processing?

2019-07-27 06:22发布

问题:

The official explanation is here: ArrayList

However, it uses iteration and confuses me.

I am trying to make a drawing pen but something is wrong here:

drawings.get(i) = drawing.get(i-1);

   ArrayList <Drawing> drawings = new ArrayList <Drawing>();

   void setup(){
    size(400,400);
    background(255);
    colorMode(HSB);
   }

   void draw(){}

   void mouseDragged(){

     drawings.add(new Drawing(mouseX,mouseY));

     for(int i = drawings.size()-1;i>0;i--){
       drawings.get(i) = drawing.get(i-1);
      }

     for(int i=0;i<drawings.size;i++){
       fill(c,100);
       drawings.get(i).display();}
  }


  class Drawing{
     float x,y,r;
     color c;

   Drawing(float ax,float ay){
     x=as;
     y=ay;
     r=random(2,20);
     c=color(random(100,200),255,255);
    }  

   void display(){
     fill(c,100);
     ellipse(drawing[i],r,r);}

  }

I still don't know how to use ArrayList. Does anyone know?

Thank you.

回答1:

You mentioned iteration confuses you. It's a simple for loop. In case you're having trouble understanding those, they look harder compared to other statements, but that's just because a loop does 3 things at once:

  1. Initialize a counter
  2. Compare the current counter value to a limit (boolean expression)
  3. Increments a counter

In your code, there are two loops:

 for(int i = drawings.size()-1;i>0;i--)

and

for(int i=0;i<drawings.size();i++)

The first loop counts backwards, therefore:

  1. the counter is initialized with the highest value (i = drawings.size())
  2. the limit is 1 (i>0)
  3. the counter is decremented (i--) (or incremented by -1 if you like)

drawings.size() simply retrieves the size of the array list (similar to the length property of an array). So in simple terms, the first loop starts with the last element added to the list (the most recent), who's index is equal to the list size -1 and it stops at the 2nd element, who's index is 1 (since arrays/array lists start indexing from 0).

The second loop is simpler, since is counts from 0 to the size of the array list, basically all the elements of the list in the order they were stored (oldest to newest).

In the first loop, it looks like you're shifting all the elements except the first by one. You should try it like so:

  for (int i = drawings.size()-1;i>0;i--) {
    Drawing current  = drawings.get(i);//store the current drawing
    Drawing previous = drawings.get(i-1);//store the previous drawing
    current  = previous;//point the current to the previous
  }

And here is your code listing with the errors fixed:

ArrayList <Drawing> drawings = new ArrayList <Drawing>();
color c = color(0,0,192);

void setup() {
  size(400, 400);
  background(255);
  colorMode(HSB);
}

void draw() {
}

void mouseDragged() {

  drawings.add(new Drawing(mouseX, mouseY));

  for (int i = drawings.size()-1;i>0;i--) {
    Drawing current  = drawings.get(i);//store the current drawing
    Drawing previous = drawings.get(i-1);//store the previous drawing
    current  = previous;//point the current to the previous
    //drawings.get(i) = drawing.get(i-1);
  }

  for (int i=0;i<drawings.size();i++) {
    fill(c, 100);
    drawings.get(i).display();
  }
}


class Drawing {
  float x, y, r;
  color c;

  Drawing(float ax, float ay) {
    x=ax;
    y=ay;
    r=random(2, 20);
    c=color(random(100, 200), 255, 255);
  }  

  void display() {
    fill(c, 100);
//    ellipse(drawing[i], r, r);
    ellipse(x,y,r,r);
  }
}

UPDATE

Because of the reverse loop I assumed you needed to store a list of drawing and offset it, like so:

ArrayList <Drawing> drawings = new ArrayList <Drawing>();

void setup() {
  size(400, 400);
  smooth();
  noStroke();
  colorMode(HSB);
}

void draw() {
  background(0,0,255);
  for (int i=0;i<drawings.size();i++){
    drawings.get(i).display();
  }
}

void mouseDragged() {

  for (int i = drawings.size()-1;i>0;i--) {
    drawings.get(i).copy(drawings.get(i-1));
  }
  drawings.add(0,new Drawing(mouseX, mouseY));

}


class Drawing {
  float x, y, r;
  color c;

  void copy(Drawing copyFrom){
    x = copyFrom.x;
    y = copyFrom.y;
    r = copyFrom.r;
    c = copyFrom.c;
  }

  Drawing(float ax, float ay) {
    x=ax;
    y=ay;
    r=random(2, 20);
    c=color(random(100, 200), 255, 255);
  }  

  void display() {
    fill(c, 100);
    ellipse(x,y,r,r);
  }
}

If you simply want to draw a line between Drawing objects based on distance, you can do it without the reverse loop:

ArrayList <Drawing> drawings = new ArrayList <Drawing>();

void setup() {
  size(400, 400);
  background(255);
  colorMode(HSB);
}

void draw() {
}

void mouseDragged() {

  drawings.add(new Drawing(mouseX, mouseY));

  for (int i=0;i<drawings.size();i++) {
    Drawing curr  = drawings.get(i);
    if(i > 0){                                    //if the current index is greather than 0
      Drawing prev = drawings.get(i-1);           //we can access the previous
      if(dist(curr.x,curr.y,prev.x,prev.y) < 20) {//check the distance, if it's within a certain threshold
        line(curr.x,curr.y,prev.x,prev.y);        //draw the line
      }
    }
    curr.display();
  }
}


class Drawing {
  float x, y, r;
  color c;

  Drawing(float ax, float ay) {
    x=ax;
    y=ay;
    r=random(2, 20);
    c=color(random(100, 200), 255, 255);
  }  

  void display() {
    fill(c, 100);
    ellipse(x,y,r,r);
  }
}

In fact, since you're not clearing the background, you don't need a list at all. All you need is a reference to the previous Drawing object so you can check the distance and draw a line:

Drawing prev;//variable to store the previous drawing

void setup() {
  size(400, 400);
  background(255);
  colorMode(HSB);
}

void draw() {
}

void mouseDragged() {

  Drawing curr = new Drawing(mouseX, mouseY);//create a new drawing
  curr.display();//display it
  if(prev != null){//check if there was a previous one
    if(dist(curr.x,curr.y,prev.x,prev.y) < 20) {//if so, check if the distance is within the threshold
       line(curr.x,curr.y,prev.x,prev.y);//then simply draw a line
    }
  }
  prev = curr;

}


class Drawing {
  float x, y, r;
  color c;

  Drawing(float ax, float ay) {
    x=ax;
    y=ay;
    r=random(2, 20);
    c=color(random(100, 200), 255, 255);
  }  

  void display() {
    fill(c, 100);
    ellipse(x,y,r,r);
  }
}

HTH