For each new object, the same color is being returned from the color array

I have a class, in which I am storing a group of colors. When each object is initialized, I want a random color from that array to be chosen, but currently, it is returning the same color for all objects. What could be going on here?

//
/**
Rotor draws circle for random period of time, then moves
in a straight direction for a random period of time, beginning a 
new circle
*/
//

Rotor[] r;
float timer = 0;
int number = 0;
boolean freeze = true;

void setup() {
  //regular resolution
  //size(1280,720);
  //300 dpi
  size(5333,3000);

  noFill();
  frameRate(30);
  background(65,5,17);

  timeLimit();
  r = new Rotor[50];

  for(int i=0; i<r.length; i++){
    r[i] = new Rotor(random(width),random(height),random(200));
  }
}

void draw() {
  timer = timer + frameRate/1000;

  if(timer > timeLimit()){
    timer = 0;
    timeLimit();

    if(freeze == true){ 
      for(int i = 0; i < r.length; i++)
        r[i].drawNewRotor();
      freeze = false;
      //r.pointSpeed = r.pointSpeed * -1;
    }else{
      for(int i = 0; i < r.length; i++)
        r[i].calcTangent();

      freeze = true;
    }
  }

  if(!freeze){
    for(int i = 0; i < r.length; i++)
      r[i].drawRotor(); 
  }else{
    for(int i = 0; i < r.length; i++)
      r[i].holdSteady();
  }
}

float timeLimit(){
  float timeLimit = random(200); 
  return timeLimit;
}

void keyPressed(){
  if(key=='s') {
    String s = "screen_" + nf(number, 3) +".jpg";
    save(s);
    number++;
  } 
}



/*
assuming you are taking derivatives with respect to the theta: 
dx/d(theta)=-cos(theta) and dy/d(theta)= sin(theta)...
dx/d(theta) and dy/d(theta) 
just says "derivative of x (or y) with respect to (theta)" 
*/

class Rotor {

  color[] colors = new color[5];
  int thickness;
  float xPoint = random(width);
  float yPoint = random(height);
  float nXPoint;
  float nYPoint;
  float radius;
  float theta = 0;
  float centerX;
  float centerY;
  float yLine;
  float pointSpeed = 0.02;
  float deltaX;
  float deltaY;

  Rotor(float cX, float cY, float rad) {
    colors[0] = color(119,216,197);
    colors[1] = color(99,56,53);
    colors[2] = color(176,51,40);
    colors[3] = color(232,131,123);
    colors[4] = color(199,58,46);

    thickness = 2;

    noStroke();
    stroke(colors[int(random(colors.length))]);
    strokeWeight(thickness);

    centerX = cX;
    centerY = cY;
    radius = rad;
    theta = 0.0;
  } 

  void drawRotor() {
    theta = theta + pointSpeed;
    xPoint = centerX + cos(theta) * radius;
    yPoint = centerY + sin(theta) * radius;
    ellipse(xPoint, yPoint,thickness,thickness);
    //ellipse(centerX,centerY,5,5);//center point
  }

  void holdSteady() {
    xPoint = xPoint + deltaX/50;//speed /100
    yPoint = yPoint + deltaY/50;
    ellipse(xPoint,yPoint,thickness,thickness);
  }

  void calcTangent() {
    deltaX = radius * -sin(theta);
    deltaY = radius * cos(theta);
  }

  void drawNewRotor() {
    radius = random(200);

    centerX = xPoint + radius * cos(theta);
    centerY = yPoint + radius * sin(theta);

    theta = (theta + PI)%(2*PI);
  }
}
Tagged:

Answers

  • edited January 2016

    Both stroke() & fill() are "global" & "permanent".
    That is, the last color used on each of them becomes active for all subsequent drawings afterwards.
    Of course, until they're changed again. ;;)

    When you create your 50 Rotor objects, the last stroke() issued inside the 50th Rotor's constructor becomes the active color for all drawings.

    B/c no stroke() command is issued afterwards anymore in your sketch program. :-B

  • edited January 2016 Answer ✓

    You have the list of colors inside the class. So each object has it's own copy of the list. This is overkill! Each object only needs to know the index into the list of colors that it should use. It also needs to start using that color before drawing anything! Example:

    class Dot {
      int color_index;
      int x, y;
      Dot( int icolor_index, int ix, int iy) {
        color_index = icolor_index;
        x = ix;
        y = iy;
      }
      void draw() {
        fill(colors[color_index]);
        ellipse(x, y, 20, 20);
      }
    }
    
    color[] colors = { 
      color(255), color(255, 0, 0), color(0, 255, 0), color(0, 0, 255)
    };
    
    Dot[] dots = new Dot[4];
    
    void setup() {
      size(200, 200);
      dots[0] = new Dot(3, 20, 20);
      dots[1] = new Dot(2, 60, 20);
      dots[2] = new Dot(1, 20, 60);
      dots[3] = new Dot(0, 60, 60);
    }
    
    void draw() {
      background(0);
      dots[0].draw();  
      dots[1].draw();  
      dots[2].draw();  
      dots[3].draw();
    }
    
  • But the big problem, as gotoloop points out, is the way you're assigning colours in the constructor, it won't work.

    A better way would be to assign and store a random integer, the colour index, in the constructor and move the stroke() to your drawRotor and holdSteady methods.

  • Another tip, for free...

    for(int i = 0; i < r.length; i++)
        r[i].drawNewRotor();
    freeze = false;
    

    Brackets around code blocks, even if they are single lines, is always a good idea. It's only two more characters to type and will save you from pulling your hair out sooner or later. Never rely solely on whitespace to give your code meaning. It's especially important when posting to forums where you never quite know how whitespace is going to be treated.

Sign In or Register to comment.