Send value to a object

edited June 2018 in Library Questions

Hello everybody. I`ve a problem:

I`ve a array of ellipse Objects. Every object has his variable of size in the constructor. In a second screen, via controlP5, a slider that change the size of every ellipse. What i want is change the size of an ellipse object when isClicked is true, and in that particular object, and store that value. But i cant, and i dont know exaclty why. I think that when i change the size in the constructor every object take the same value.

here the code, sorry for my very bad english, hope you understand:

(in resume: click the object, change it value, store the value. click in another object, and change it value (different of object 1)…etc.)

import controlP5.*;

ArrayList<Sphere>s;
PWindow controller;


void settings() {
  size(500, 500, P3D);
}


void setup() {
  controller = new PWindow();

  s = new ArrayList<Sphere>();
  s.add(new Sphere(new PVector(random(width), random(height)), 255, 50, 0));
}

void draw() {
  background(0);
  pushMatrix();
  select();

  for (Sphere s : s) {
    s.display();
    s.isOver(mouseX, mouseY);
  }
  popMatrix();
}

void select() {
  for (Sphere s : s) {
    if (s.isClick) {
      println(s.id, "HOLA");
      s.c = 25;
      println("");
    }
  }
}

void mousePressed() {

  if (mouseButton==RIGHT) s.add(new Sphere(new PVector(mouseX, mouseY), 255, 50, s.size()+1));

  for (Sphere s : s) {
    if (mouseButton==LEFT && s.over) {
      s.isClick = true;
    } else {
      s.isClick = false;
    }
  }
}

class Sphere {

  float c, size;
  float x, y;
  ArrayList<PVector> p = new ArrayList<PVector>();
  boolean over = false;
  boolean isClick = false;
  int id;
  int initialValue = 50;

  Sphere(PVector pos, float _color, float _size, int _id) {
    p.add(pos);
    c = _color;
    size = _size;
    id = _id;
  }

  void display() {
    for (PVector pos : p) {
      pushMatrix();
      translate(pos.x, pos.y);
      fill(c);  
      ellipse(0, 0, size, size);
      popMatrix();
    }
  }

  boolean isOver(float px, float py) {
    ellipseMode(RADIUS);
    for (PVector pos : p) {
      float d = dist(px, py, pos.x, pos.y);
      if (d < size) {
        over = true;
        c = 150;
        return true;
      } else {
        over = false;
        c = 255;
        return false;
      }
    }
    return false;
  }
}
public class PWindow extends PApplet {  

  PWindow() {
    super();
    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
  }

  ControlP5 cp5;

  int vertices = 50;
  float ss;


  Slider abc;


  void settings() {
    size(500, 250, P2D);
  }

  void setup() {
    cp5 = new ControlP5(this);
    background(0);


    cp5.addSlider("vertices")
      .setPosition(25, 50)
      .setSize(200, 20)
      .setRange(0, 50)
      ;
  }

  void draw() {
    background(0);

    for (int i = s.size()-1; i >= 0; i--) {
      Sphere obj = s.get(i); 
      ss = vertices;

      if (obj.isClick==true) {
        fill(255);
        stroke(255);
        textSize(13);
        text(i, width/2, 150);
        println(i);
        obj.size = vertices;
      }
    }
  }

}

Answers

  • edited June 2018

    ArrayList p

    in class Sphere:

    ArrayList<PVector> p = new ArrayList<PVector>();

    makes no sense.

    use PVector p; instead

    (Each sphere can only have ONE position.)

    Color

    float c... is your color !?

    why not use color c; instead?

    Naming

    this looks confusing: for (Sphere s : s) {

    consider for (Sphere currentSphere : s) {

    or even for (Sphere currentSphere : spheres) {

    ==true

    if (obj.isClick==true) {

    same as

    if (obj.isClick) {

    store the ID

    instead of marking one sphere as isClicked in mousePressed, you can store its ID as cID.

    Then you can use cID to access the sphere directly (s.get(cID)) without a for loop in class PWindow | draw()

  • edited June 2018 Answer ✓

    Also, instead of reading the slider throughout, it's better to use slider event

    see

    http://www.sojamo.de/libraries/controlP5/examples/controllers/ControlP5slider/ControlP5slider.pde

    Using size as ID

    here you had

          s.add(new Sphere(new PVector(mouseX, mouseY), 255, 50, s.size()+1));
    

    (s.size()+1)

    better

     s.add(new Sphere(new PVector(mouseX, mouseY), 255, 50, s.size()));
    

    s.size()

    New version

    (lots of other changes too)

    import controlP5.*;
    
    ArrayList<Sphere> s;
    PWindow controller;
    int cID=-1;  
    
    void settings() {
      size(500, 500, P3D);
    }
    
    void setup() {
      controller = new PWindow();
    
      s = new ArrayList<Sphere>();
    
      // add one sphere (optional)
      float size1 = 50; 
      Sphere newSphere = new Sphere(
        new PVector(random(size1, width-size1), random(size1, height-size1)), 
        255, 
        size1, 
        0); 
      s.add(newSphere);
    }
    
    void draw() {
      background(0);
      for (Sphere s : s) {
        s.display();
        s.isOver(mouseX, mouseY);
      }
    }
    
    //void select() {
    //  for (Sphere currentSphere : s) {
    //    if (currentSphere.isClick) {
    //      // println(currentSphere.id, "HOLA");
    //      currentSphere.c = 25; // color
    //      // println("");
    //    }
    //  }
    //}
    
    void mousePressed() {
      if (mouseButton==RIGHT) { 
        s.add(new Sphere(new PVector(mouseX, mouseY), 255, 50, s.size()));
        return; // leave here
      }
    
      //reset 
      cID=-1; 
    
      if (mouseButton==LEFT) {
        for (Sphere currentSphere : s) {
          if (currentSphere.over) {
            currentSphere.isClick = true;
            cID = currentSphere.id;
          } else {
            currentSphere.isClick = false;
          }
        }
      }
    }
    
    // ===========================================================
    
    class Sphere {
    
      color c; 
      float size;
      float x, y;
      PVector p = new PVector(0, 0);
      boolean over = false;
      boolean isClick = false;
      int id;
      int initialValue = 50;
    
      Sphere(PVector pos, 
        color _color, 
        float _size, 
        int _id) {
        // 
        p=pos.copy();
        c = _color;
        size = _size;
        id = _id;
      }//constr
    
      void display() {
        fill(c);  
        ellipse(p.x, p.y, 
          size, size);
      }
    
      boolean isOver(float px, float py) {
    
        ellipseMode(RADIUS);
    
        float d = dist(px, py, p.x, p.y);
        if (d < size) {
          over = true;
          c = 150;
          if (isClick) 
            c = 25; // color
          return true;
        } else {
          over = false;
          c = 255;
          if (isClick) 
            c = 25; // color
          return false;
        }
      }//func
    }//class
    
    // ===========================================================
    
    public class PWindow extends PApplet {  
    
      PWindow() {
        super();
        PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
      }
    
      ControlP5 cp5;
    
      int vertices = 50;
      float ss;
    
    
      Slider abc;
    
    
      void settings() {
        size(500, 250, P2D);
      }
    
      void setup() {
        cp5 = new ControlP5(this);
        background(0);
    
        cp5.addSlider("vertices")
          .setPosition(25, 50)
          .setSize(200, 20)
          .setRange(0, 50)
          ;
      }
    
      void draw() {
        background(0);
    
        if (cID>-1) {
          fill(255);
          stroke(255);
          textSize(13);
          text(cID, width/2, 150);
        }
      }
    
      void vertices(float c) {
    
        if (cID==-1) 
          return; 
    
        Sphere obj = s.get(cID); 
        obj.size = c;
        println("a slider event. ");
      }
    }//class 
    //
    
  • thanks for make me better!!!_

  • edited June 2018

    Oh, im in a new trouble... In fact this piece of code is a reduction of a bigger program. What i really want is a "interface" to control another object. Now, we change the Sphere.size with a slider. but what i want to change when a Sphere.isclick is the size of another Obj...

    i try this, but it doesnt work. I try others variations without a result. I think you can help appying your cID logic...

    I thinks that is a really easy way.. Every Sphere on the screen represent an Obj when i click on that ellipse, i want change with a slider the "total" value for this Obj.

    (in the real code, the variable "total" represent the detail of a sphere)

    import controlP5.*;
    
    ArrayList<Sphere> s;
    ArrayList<Obj> obj;
    
    PWindow controller;
    int cID=-1;  
    
    void settings() {
      size(500, 500, P3D);
    }
    
    void setup() {
      controller = new PWindow();
    
      s = new ArrayList<Sphere>();
      obj = new ArrayList<Obj>();
    
      // add one sphere (optional)
      float size1 = 50; 
      Sphere newSphere = new Sphere(
        new PVector(random(size1, width-size1), random(size1, height-size1)), 
        255, 
        size1, 
        0); 
      s.add(newSphere);
    }
    
    void draw() {
      background(0);
      for (Sphere ss : s) {   
        ss.display();
        ss.isOver(mouseX, mouseY);
      }
    
      println(obj.size());
    }
    
    
    
    void mousePressed() {
      if (mouseButton==RIGHT) { 
        s.add(new Sphere(new PVector(mouseX, mouseY), 255, 50, s.size()));
        obj.add(new Obj(int(random(50)), s.size()));
        return; // leave here
      }
    
      //reset 
      cID=-1; 
    
      if (mouseButton==LEFT) {
    
    
    
    
        for (Sphere currentSphere : s) {
          if (currentSphere.over) {
    
            for (Obj o : obj) {
              o.printt();
              cID = currentSphere.id;
            }
    
            currentSphere.isClick = true;
            cID = currentSphere.id;
          } else {
            currentSphere.isClick = false;
          }
        }
      }
    }
    
    // ===========================================================
    
    class Sphere {
    
      color c; 
      float size;
      float x, y;
      PVector p = new PVector(0, 0);
      boolean over = false;
      boolean isClick = false;
      int id;
      int initialValue = 50;
    
      Sphere(PVector pos, 
        color _color, 
        float _size, 
        int _id) {
        // 
        p=pos.copy();
        c = _color;
        size = _size;
        id = _id;
      }//constr
    
      void display() {
        fill(c);  
        ellipse(p.x, p.y, 
          size, size);
      }
    
      boolean isOver(float px, float py) {
    
        ellipseMode(RADIUS);
    
        float d = dist(px, py, p.x, p.y);
        if (d < size) {
          over = true;
          c = 150;
          if (isClick) 
            c = 25; // color
          return true;
        } else {
          over = false;
          c = 255;
          if (isClick) 
            c = 25; // color
          return false;
        }
      }//func
    }//class
    
    // ===========================================================
    
    class Obj {
      int total;
      int id;
      Obj(int _total, int _id) {
        total = _total;
        id = _id;
      }
    
      void printt() {
        println(total);
      }
    }
    
    public class PWindow extends PApplet {  
    
      PWindow() {
        super();
        PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
      }
    
      ControlP5 cp5;
    
      int vertices = 50;
      float ss;
    
    
      Slider abc;
    
    
      void settings() {
        size(500, 250, P2D);
      }
    
      void setup() {
        cp5 = new ControlP5(this);
        background(0);
    
        cp5.addSlider("vertices")
          .setPosition(25, 50)
          .setSize(200, 20)
          .setRange(0, 50)
          ;
      }
    
      void draw() {
        background(0);
    
        if (cID>-1) {
          fill(255);
          stroke(255);
          textSize(13);
          text(cID, width/2, 150);
        }
      }
    
      void vertices(int c) {
    
        if (cID==-1) 
          return; 
    
        Obj o = obj.get(cID); 
        o.total = c;
        println("a slider event. ");
      }
    }//class 
    //
    
  • im sorry. silly question. solved:

      void vertices(int c) {
    
        if (controller.cID==-1) 
          return;   
    
        Obj o = s.o.get(controller.cID);
        o.total = c;
      }
    
  • and how can i actualize the slider value when i click in a object?

  • See the reference of controlP5 - could be something like setValue

  • cp5.getController("vertices").setValue(40);

  • thanks, i try with cp5.getController("vertices").setValue(obj.total); but it doesnt work, i`ll keep trying. i need some kind of data structure to store the current value of obj.total and when i click in one of them the value of slider jump to that value. otherwise the slider always show me the last value i pick, and is not very comfortable when i use a lot of differents objects

  • Look at the documentation

  • this doesn't make too much sense - at least to me:

    Every Sphere on the screen represent an Obj when i click on that ellipse, i want change with a slider the "total" value for this Obj.

    When you want the ellipses to symbolize your objects, why then additionally put in objects??

    Either ellipses / Spheres OR obj.

    This

    this is really bad:

        for (Sphere currentSphere : s) {
          if (currentSphere.over) {
    
            for (Obj o : obj) {
              o.printt();
              cID = currentSphere.id;
            }
    

    it takes a lot of processor time to check for each sphere ALL objects!!!

    A nested for loop only makes sense when you have a structure like a grid where each line has many cells.

    New version

    New version without obj but with:

    • slider takes the value from clicked ellipse!!!

    Chrisir ;-)

    import controlP5.*;
    
    ArrayList<Sphere> s;
    
    PWindow controller;
    
    int cID=-1;  
    
    // ------------------------------------------------------------
    
    void settings() {
      size(500, 500, P3D);
    }
    
    void setup() {
      controller = new PWindow();
    
      s = new ArrayList<Sphere>();
    
      // add one sphere (optional)
      float size1 = 50; 
      Sphere newSphere = new Sphere(
        new PVector(random(size1, width-size1), random(size1, height-size1)), 
        255, 
        size1, 
        0); 
      s.add(newSphere);
    }
    
    void draw() {
      background(0);
    
      for (Sphere ss : s) {   
        ss.display();
        ss.isOver(mouseX, mouseY);
      }
    }
    
    // ------------------------------------------------------------
    // Inputs 
    
    void mousePressed() {
    
      if (mouseButton==RIGHT) { 
        s.add(new Sphere(new PVector(mouseX, mouseY), 255, 50, s.size()));
        return; // leave here
      }
    
      //reset 
      cID=-1; 
    
      if (mouseButton==LEFT) {
        for (Sphere currentSphere : s) {
          if (currentSphere.over) {
            currentSphere.isClick = true;
            cID = currentSphere.id;
            float currentSize = s.get(cID).size; 
            controller.cp5.getController("vertices").setValue(currentSize);
          } else {
            currentSphere.isClick = false;
          }
        }//for
      }//if
      //
    } //func 
    
    // ===========================================================
    
    class Sphere {
    
      color c; 
      float size;
      float x, y;
      PVector p = new PVector(0, 0);
      boolean over = false;
      boolean isClick = false;
      int id;
      int initialValue = 50;
    
      //constr 
      Sphere(PVector _pos, 
        color _color, 
        float _size, 
        int _id) {
        // 
        p=_pos.copy();
        c = _color;
        size = _size;
        id = _id;
      }//constr
    
      void display() {
        fill(c);
        ellipseMode(RADIUS);
        ellipse(p.x, p.y, 
          size, size);
      }
    
      boolean isOver(float px, float py) {
        float d = dist(px, py, p.x, p.y);
        if (d < size) {
          over = true;
          c = 150;
          if (isClick) 
            c = 25; // color
          return true;
        } else {
          over = false;
          c = 255;
          if (isClick) 
            c = 25; // color
          return false;
        }
      }//func
    }//class
    
    // ===========================================================
    
    public class PWindow extends PApplet {  
    
      PWindow() {
        super();
        PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
      }
    
      ControlP5 cp5;
    
      void settings() {
        size(500, 250, P2D);
      }
    
      void setup() {
        cp5 = new ControlP5(this);
        background(0);
    
        cp5.addSlider("vertices")
          .setPosition(25, 50)
          .setSize(200, 20)
          .setRange(0, 50);
      }
    
      void draw() {
        background(0);
    
        if (cID>-1) {
          fill(255);
          stroke(255);
          textSize(13);
          text(cID, width/2, 150);
        }
      }
    
      void vertices(int c) {
    
        if (cID==-1) 
          return; 
    
        Sphere s1 = s.get(cID); 
        s1.size = c;
        println("a slider event. ");
      }
      //
    } //class 
    //
    
  • Also note I got rid of this:

      // int vertices = 50;  // ???????????????????????
      //  float ss;
      // Slider abc;
    

    at start of public class PWindow

  • here is the slider line almost as we discussed it

    controller.cp5.getController("vertices").setValue(currentSize); 
    
  • Thanks a lot! you really helped me in my project, and also made me learn how to be a better coder! cheeeers!

Sign In or Register to comment.