Strokes as a class instances

edited October 2016 in Questions about Code

Hello. Here is my little drawing sketch again. Please, draw something on the screen. Every time you hold a mouse, there is a stroke of certain color and shade, and when you release a mouse, the stroke ends, and the next stroke will be another color and shade. So, the stroke is something that lasts from holding a mouse till release. My question is - how to make every single stroke become a class instance, so it may have its own coordinates (for example to move all the strokes up and down, left and right), and how to store all the strokes inside ArrayList (for example to have a possibility to delete the last stroke)?

int size;
color [] ccc;
float rotAngle = 0;
color colour;
color rand;
int x = 0;
int y = 0;


void setup()   
{
  size(1200, 900);
  background(0);
  frameRate (50);
  smooth();
  noStroke();

  size = 20;
  ccc = new color[size*size];
  colour = color(random(255), random(255), random(255));
  rand = color(random(-50, 50), random(-50, 50), random(-50, 50));

  for (int i = 0; i < size*size; i++)
  {
    rand = rand+int(random(-50,50));
    ccc[i] = colour+rand;
  }
} 


void draw()
{

  if (mousePressed)
  {
    brush01();
  }
}


void brush01()
{
  int i;
  float brush_X = 0;
  float brush_Y = 0;

  for (i =1; i<size*size; i++)
  {
    if (mouseX != pmouseX || mouseY != pmouseY)
    {
      rotAngle = atan2(mouseY - pmouseY, mouseX - pmouseX);
    }

    pushMatrix();
    rectMode(CENTER);
    translate(mouseX, mouseY);
    rotate(rotAngle);
    translate(0-size/2, 0-size/2);
    fill(ccc[i]);
    rect(brush_X, brush_Y, 1, 1);
    popMatrix();

    brush_X ++;
    if (brush_X > size)
    {
      brush_X = 0;
      brush_Y ++;
    }
  }
}


void mouseReleased()
{
  colour = color(random(255), random(255), random(255));
  rand = color(random(-50, 50), random(-50, 50), random(-50, 50));

  for (int i = 0; i < size*size; i++)
  {
    rand = rand+int(random(-50,50));
    ccc[i] = colour+rand;
  }
}

Answers

  • you draw rectangular particles

    make a class Particle with pos and angle

    make an ArrayList particles of that class

    in brush01 instead if drawing, store to particles

    in draw read and display this arraylist like in lines 54 to 61

  • two questions: - if i make an ArrayList and put every little particle in it, as an separate class instance, wouldn't it be too heavy, wouldn't that overload RAM? - what means "store to particles"?

  • edited October 2016

    You don't store the lines as such, just the single rects [you could do this to]

    Store means use add on particles - you create a new particle with new and add it to the ArrayList

  • I'll try to follow your advice, thanks. I will write as soon as I get some resault.

  • yeah, i can lead you through

  • Answer ✓

    Ok, this is an idea of how I would implement your program. If you want to create a class,go ahead as it is a good idea. Here I present a concept of how it works without a class. Something I find out is that your drawing operations are intensive, specially because you are drawing your rectangles of 20x20 pixels as 400 single rectangles of size 1x1. You have a very colorful effect, but computational expensive for my demonstration since I am redrawing the scene every time to keep track of traces done so far while at the same time I am showing what traces were removed (NOTICE: I am not moving any traces)

    In other words, if you want to actively add and remove or move traces, you need to change the way you draw your 20x20 rectangles. Either draw each as single color or create our unit rectangle representing your trace only once.

    In my example I created an additional class call brush00, in parallel to your already initial brush01 function. Here is how it works:

    When you start running the program, you are in drawing mode. You can add traces. The traces are not redrawn.

    If you press the space bar, you go back to drawing mode OFF. Space bar again and you go back to drawing mode ON meaning you can add traces again.

    In drawing mode OFF, you can click any previous traces. It will print the trace ID and it will remove it from your current sketch.

    How does the code works? I modified your brush01 so every time a trace is created and it is growing, it will store the center of each rectangle. Every trace gets an ID number assigned as well as its random color.

    In drawing mode off (meaning you cannot add traces), I am redrawing each of your traces again. When a click is detected, I compared the coordinates of the click to the centers of the rectangles stored in my IntList containers. Because rectangles have a dimension, I ensure the user click is within the center of the rectangle using the dist() function. I simulate each rectangle as a circle where its center is the center of the rectangle and the radius is the size of the rectangle.

    When working in a class, you need to reduce the number of translate,rotate calls as well as to come up with a faster way to draw a rectangle. My solution was to, instead of calling rect 400 times to draw a single rectangle, I am using the rectangle to draw a single rectangle of size 20x20. The SACRIFICE: I am loosing the color effect pattern that you are creating in your original code.

    I hope this helps and gives you an idea of how to structure you main >>trace<< class and to think about how to store multiple instances of this object.

    Kf


    int size;
    color [] ccc;
    float rotAngle = 0;
    color colour;
    color rand;
    int x = 0;
    int y = 0;
    
    IntList px;
    IntList py;
    IntList id;
    IntList cv; //color val
    int idTracker=0;
    
    boolean drawingNow=true;
    
    
    void setup()   
    {
      size(1200, 900);
      background(0);
      frameRate (50);
      smooth();
      noStroke();
      rectMode(CENTER);
    
      px = new IntList();
      py = new IntList();
      id = new IntList();
      cv = new IntList();
    
      size = 20;
      ccc = new color[size*size];
      colour = color(random(255), random(255), random(255));
      rand = color(random(-50, 50), random(-50, 50), random(-50, 50));
    
      for (int i = 0; i < size*size; i++)
      {
        rand = rand+int(random(-50, 50));
        ccc[i] = colour+rand;
      }
    } 
    
    
    void draw()
    {
      if (drawingNow==true) {
        if (mousePressed )
        {
          brush01();
        }
      } else {
    
        background(0);
        brush00();
      }//End of drawingNow
    }
    
    void keyPressed() {
      if (key==' ') {
        drawingNow=!drawingNow; //toggle
        println("Drawing mode: " + drawingNow);
      }
    }
    
    
    void brush00() {
    
      int prevX,prevY;
    
      if (px.size()==0)
        return;
    
      int currID=id.get(0);
      prevX=px.get(0);
      prevY=py.get(0);
      rand = color(random(-50, 50), random(-50, 50), random(-50, 50));
      for (int i = 0; i < size*size; i++)
      {
        rand = rand+int(random(-50, 50));
        ccc[i] = rand;//cv.get(0)+rand;
      }
    
    
      for (int k=0; k<px.size(); k++) {
    
        //UPDATE color
        if (id.get(k)!=currID) {
          //rand = color(random(-50, 50), random(-50, 50), random(-50, 50));
          //for (int i = 0; i < size*size; i++)
          //{
          //  rand = rand+int(random(-50, 50));
          //  ccc[i] = cv.get(k)+rand;
          //}
        }
    
        float brush_X = 0;
        float brush_Y = 0;
    
        int ax=px.get(k);
        int ay=py.get(k);
        //for (int i =1; i<size*size; i++)
        //{
          if (ax != prevX || ay != prevY)
          {
            rotAngle = atan2(ay - prevY, ax - prevX);
          }
    
          pushMatrix();
          translate(ax, ay);
          rotate(rotAngle);
          //translate(0-size/2, 0-size/2);
          fill(cv.get(k));//+ccc[i]);
          rect(0,0, size,size);
          popMatrix();
    
          //brush_X ++;
          //if (brush_X > size)
          //{
          //  brush_X = 0;
          //  brush_Y ++;
          //}
        }
    //  }
    }
    
    void brush01()
    {
      int i;
      float brush_X = 0;
      float brush_Y = 0;
    
      for (i =1; i<size*size; i++)
      {
        if (mouseX != pmouseX || mouseY != pmouseY)
        {
          rotAngle = atan2(mouseY - pmouseY, mouseX - pmouseX);
        }
    
        pushMatrix();
    
        px.append(mouseX);
        py.append(mouseY);
        id.append(idTracker);
        cv.append(colour);
    
        translate(mouseX, mouseY);
        rotate(rotAngle);
        translate(0-size/2, 0-size/2);
        fill(ccc[i]);
        rect(brush_X, brush_Y, 1, 1);
        popMatrix();
    
        brush_X ++;
        if (brush_X > size)
        {
          brush_X = 0;
          brush_Y ++;
        }
      }
    }
    
    
    void mouseReleased() {
    
      if (drawingNow==true) {
        idTracker++;
        colour = color(random(255), random(255), random(255));
        rand = color(random(-50, 50), random(-50, 50), random(-50, 50));
    
    
    
        for (int i = 0; i < size*size; i++)
        {
          rand = rand+int(random(-50, 50));
          ccc[i] = colour+rand;
        }
      } else {
    
    
        boolean foundMatch=false;
        int idVal=-1;
        for (int i=0; i<px.size() && foundMatch==false; i++) {
          if (dist(mouseX, mouseY, px.get(i), py.get(i))<10) {
            foundMatch=true;
            idVal=id.get(i);
            println("ID found: " + idVal);
          }
        }
    
        //Traversing the list backwards for effective item removal
        //This has to be done since I am traversing and modifying the list at the same time
        for (int i=px.size()-1; i>=0; i--) {
          if (id.get(i)==idVal) {
            px.remove(i);
            py.remove(i);
            id.remove(i);
            cv.remove(i);
          }
        }
      }
    }
    
  • kfrajer, thanks! I will try to understand this, "IntList" is new for me.

Sign In or Register to comment.