We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › raining circles (blended circles)
Page Index Toggle Pages: 1
raining circles (blended circles) (Read 2166 times)
raining circles (blended circles)
Dec 27th, 2009, 10:58am
 
I am trying to make raining circles that respond to mouse or camera input.

These are the circles:(cannot post a link as i'm a new user)
openprocessing.org/visuals/?visualID=6712

But they are different sizes as here:
colorisrelative.com/color

The end piece will be used as an interactive projected piece. The input (which I have already figured out) is using a wii remote and an infrared led. (although i'd like to set up my video camera to read negative space of people behind the screen).

I need:
1. to make blends (right now the circles are each coded bringing in rgb values from illustrator by hand).
2. make the circles vary in size and randomly generate at the top of the screen and fall slowly at various sizes, perhaps inverse to their size
3. i'd love to have an input that allowed users to stand behind the screen and have their shadow be the body that the falling circles avoided (bounced or rolled off)
4. i'd also like the hue to change occasionally, at random or based on user input

I know this is alot to ask, but I thought maybe there would be some open source examples to work with and combine...

thanks  Smiley


p.s. thanks for correcting my post cedric
Re: raining circles (blended circles)
Reply #1 - Dec 28th, 2009, 2:25am
 
Creating a circle object would definitely be a good place to start - the multiple constructors example might be a handy template.  It's really just a matter of adding a colour property, direction and adding movement to the display method:

Code:
Spot foo[] = new Spot[10];  // Since you'll want more than one spot create an array to store multiple spots

void setup(){
 size(300,400);
 
 // Whenever you want to do something to all your spots you need to iterate through the array:
 for(int i=0;i<foo.length;i++) {
   // create a random colour.  By limiting r and g and setting a minimum for b we should get a selection of blues
   int r = (int) random(100);
   int g = (int) random(100);
   int b = 155 + (int) random(100);
   color colour = color(r,g,b);
   // create the Spot objects:
   foo[i] = new Spot(random(width),0,10+random(20), colour);
 }
 
}


void draw(){
 // display the spots:
 for(int i=0;i<foo.length;i++) {
   foo[i].display();
 }
}

class Spot {
 float x, y, radius;
 float vx,vy; // to store velocities
 color colour;

 Spot(float xpos, float ypos, float r, color c) {
   x = xpos;
   y = ypos;
   vx = random(-1,1);  // create small random horizontal velocity
   vy = 1 + random(3);  // set a vertical velocity
   radius = r;
   colour = c;
 }
 
 void display() {
   stroke(255);
   fill(colour);
   ellipse(x, y, radius*2, radius*2);
   // Make them move:  add the velocity to the position each frame
   x += vx;
   y += vy;
   
   // If they go beyond the bottom of the screen one option is to simply place them back at the top:
   if(y > height+ 30) {
     // by resetting all these it will look like a different ball ;)
     int r = (int) random(100);
     int g = (int) random(100);
     int b = 155 + (int) random(100);
     colour = color(r,g,b);
     radius = 10+random(20);
     vx = random(-1,1);  // create small random horizontal velocity
     vy = 1 + random(3);  // set a vertical velocity
     x = random(width);
     y = 0;
   }
 }
}


There's obviously a lot that can be improved here.  In response to your questions:

1.  You may find that switching from RGB to HSB colorMode might make it easier to shift colours the way you want.  You may want to look into 'bitwise operators' to find out how to shift colours quickly (in terms of performance).
2. I think is more or less covered in the above code.
3.  This is fairly tricky: there are libraries to handle video input, but the hard bit is figuring out when a circle hits a shadow; you then have to build in appropriate behaviour (physics) to the circle class
4.  See #1

If you want to save yourself some work have a look at the Libraries as they will almost certainly contain much of what you need - it's just then a matter of figuring out how to implement them.  One thing is certain: incorporating the required behaviour into a Circle class will make the whole process a lot simpler...
Re: raining circles (blended circles)
Reply #2 - Dec 28th, 2009, 8:06pm
 
Thank you very much blindfish. i'm working with your code and thought I would just post where i am so far today although it is extremely unfinished. i was able to put in the blends for the circles so I was happy with the look. Then I tried to add some color control-- mousing over the bottom changes the background and touching the color rects on the side sets the Red and Green values of the inner and outer circles for live blending.

I'm going to add blue controls at the top...

It obviously needs to be cleaned up AND--
1. i'd like to have the circles change one at a time so that the color changes just the newest circle and it is amongst other color circles. Maybe this requires getting the fills up into the array section.
2. I'd still like to pull from the library to have the circles respond to shadow input but that sounds like it may be biting off too much-- for now, perhaps there is a simpler way-- maybe just have it respond to mouse location-- perhaps influencing direction of circles?

//thanks to code from blindfish

Spot foo[] = new Spot[20];  // Since you'll want more than one spot create an array to store multiple spots

float r1 = 170;
float g1 = 211;
int b1 = 126;
float r2 = 91;
float g2 = 105;
int b2 = 176;
int a = 200;
int backc = 255;

void setup(){
 size(800,600);
 
 fill(255,0,0);
 rect(0,0,0.02*width, 0.5*height);
 
 // Whenever you want to do something to all your spots you need to iterate through the array:
for(int i=0;i<foo.length;i++) {
   // create a random colour.  By limiting r and g and setting a minimum for b we should get a selection of blues
   // while I adjusted color for the circles later, i couldn't delete this area without losing it all
 
  int r = (int) random(100);
  int g = (int) random(100);
   int b = 155 + (int) random(100);
  color colour = color(r,g,b);
   // create the Spot objects:
   foo[i] = new Spot(random(width),0,10+random(20), colour);
 }
 
}


void draw(){
   background(backc);
   //outer blend color control gauges
   fill(255,0,0); //red box on left to gauge red value
   rect(0,0,0.01*width, 0.5*height); //line to guage red value
   stroke(255-backc);
   line(0,(r1*0.5*height)/255,15,(r1*0.5*height)/255);
   noStroke();  
   fill(0,255,0); //green box on left to gauge green value
   rect(0,0.5*height,0.01*width, 0.5*height);  
   stroke(255-backc);
   line(0,(g1*0.5*height)/255+(0.5*height),15,(g1*0.5*height)/255+(0.5*height)); //line to tell green value
   
   //inner blend color control gauges
   fill(255,0,0); //red box on RIGHT to gauge red value of inner circle
   noStroke();
   rect(0.99*width,0,0.01*width, 0.5*height); //line to guage red value of inner circle
   stroke(255-backc);
   line(width-15,(r2*0.5*height)/255,width,(r2*0.5*height)/255);
   noStroke();  
   fill(0,255,0); //green box on RIGHT to gauge green value of inner circle
   rect(0.99*width,0.5*height,0.01*width, 0.5*height);
   stroke(255-backc);
   line(width-15,(g2*0.5*height)/255+(0.5*height),width,(g2*0.5*height)/255+(0.5*h
eight));  //line to tell green value
   
   
     
 // display the spots:
 for(int i=0;i<foo.length;i++) {
   foo[i].display();
 }
 
}

class Spot {
 float x, y, radius;
 float vx,vy; // to store velocities
 color colour;

 Spot(float xpos, float ypos, float r, color c) {
   x = xpos;
   y = ypos;
   vx = random(-1,1);  // create small random horizontal velocity
   vy = 1 + random(3);  // set a vertical velocity
   radius = r;
   colour = c;
 }
 
 void display() {
   color from = color(r1,g1,b1,a);
   color to = color(r2,g2,b2,a);
   color interA = lerpColor(from, to, .25);
   color interB = lerpColor(from, to, .5);
   color interC = lerpColor(from, to, .75);
   
   noStroke();
   
   fill(from);
   ellipse(x, y, radius*5, radius*5);
   // Make them move:  add the velocity to the position each frame
//   x += vx;
//   y += vy;

   fill(interA);
   ellipse(x, y, radius*4, radius*4);
   // Make them move:  add the velocity to the position each frame
//   x += vx;
//   y += vy;    
   
   fill(interB);
   ellipse(x, y, radius*3, radius*3);
//   x += vx;
//   y += vy;
 
   fill(interC);
   ellipse(x, y, radius*2, radius*2);
//   x += vx;
//   y += vy;
   
   fill(to);
   ellipse(x, y, radius*1, radius*1);
   x += vx;
   y += vy;
   
   
   // If they go beyond the bottom of the screen one option is to simply place them back at the top:
   if(y > height+ 30) {
     // by resetting all these it will look like a different ball Wink
     int r = (int) random(100);
     int g = (int) random(100);
     int b = 155 + (int) random(100);
     colour = color(r,g,b);
     radius = 1+random(30);
     vx = random(-1,1);  // create small random horizontal velocity
     vy = 1 + random(3);  // set a vertical velocity
     x = random(width);
     y = 0;
   }
   
   if (mouseY > (0.98*height)) {
     backc = ((255*mouseX)/width);
   }
   
   if (mouseX > 1 && mouseX < (0.02*width) && mouseY < (0.5*height)) {
     r1 = ((255*mouseY)/(0.5*height));
   }
   if (mouseX > 1 && mouseX < (0.02*width) && mouseY > (0.5*height)) {
     g1 = ((255*mouseY)/(0.5*height)-255);
   }
   if (mouseX > 0.98*width && mouseY < (0.5*height)) {
     r2 = ((255*mouseY)/(0.5*height));
   }
   if (mouseX > (0.98*width) && mouseY > (0.5*height)) {
     g2 = ((255*mouseY)/(0.5*height)-255);
   }
   
 }

}







Re: raining circles (blended circles)
Reply #3 - Dec 29th, 2009, 2:16am
 
A few suggestions:

1.  Try and avoid magic numbers or repeated calculations.  For example, because the code I posted was for demo purposes I didn't bother defining a variable to use in the 'falling off the bottom' test: in actual fact this should be (5*maximum possible radius).  So you could create a 'maxRadius' variable and use this when creating the Circles and in the test.  Since you use 'height*0.5' and other such calculations repeatedly it's worth creating variables to store these in setup and avoid the need to calculate them in every frame.

2.  Don't forget that most input devices have buttons.  It's easy enough to use mousePressed so that the colours are adjusted only when intended.  You could also hide the colour change interface unless the mouse is pressed (though a better option would be to hide it unless moused-over as this would potentially avoid the need to document its existence).  One benefit of hiding it is that you could then afford to make it bigger and less fiddly.

3.  Avoid repeated calculations (ok I'm repeating myself here).  You use lerpColor() every frame in your class display() method when in actual fact these values only change when the colour is changed using the interface (so the calculations only need to occur when the interface is used).  'from', 'to', 'interA/B/C' should all be properties of the class and changed only when the interface is used (though you will of course have to calculate their initial values, but that can be done in the constructor).

I'll post some code with #1 and #2 above implemented after this post.

As for your questions.  Changing individual circle colours might be tricky as you'd need to find a way to select the ball to adjust.  I'd be tempted to do this by checking for mousePressed on the circle, pop up your interface and then have a confirm button to set the colour (or maybe do away with the interface and use mouse position in relation to the circle to set the colour).  Reacting to the mouse is simple enough: just check if the circle is within range of the current mouse position and adjust its motion appropriately (though note that this could interfere with any mouse-controlled colour change interface you may implement).
Re: raining circles (blended circles)
Reply #4 - Dec 29th, 2009, 2:17am
 
Code:
Spot foo[] = new Spot[20];  // Since you'll want more than one spot create an array to store multiple spots

float r1 = 170;
float g1 = 211;
int b1 = 126;
float r2 = 91;
float g2 = 105;
int b2 = 176;
int a = 200;
int backc = 255;

int maxRadius;
float interfaceW;
float interfaceH;

void setup(){
size(800,600);
interfaceW = 0.05*width;
interfaceH = 0.5*height;
maxRadius = 20;

fill(255,0,0);
rect(0,0,0.02*width, interfaceH);

// Whenever you want to do something to all your spots you need to iterate through the array:
for(int i=0;i<foo.length;i++) {
// create a random colour. By limiting r and g and setting a minimum for b we should get a selection of blues
// while I adjusted color for the circles later, i couldn't delete this area without losing it all

int r = (int) random(100);
int g = (int) random(100);
int b = 155 + (int) random(100);
color colour = color(r,g,b);
// create the Spot objects:
foo[i] = new Spot(random(width),0,10+random(maxRadius), colour);
}
smooth();

}


void draw(){
background(backc);

if(mousePressed){
//outer blend color control gauges
fill(r1,0,0); //red box on left to gauge red value
rect(0,0,interfaceW, interfaceH); //line to guage red value
stroke(255-backc);
line(0,(r1*interfaceH)/255,interfaceW,(r1*interfaceH)/255);
noStroke();
fill(0,g1,0); //green box on left to gauge green value
rect(0,interfaceH,interfaceW, interfaceH);
stroke(255-backc);
line(0,(g1*interfaceH)/255+(interfaceH),interfaceW,(g1*interfaceH)/255+(interfaceH)); //line to tell green value

//inner blend color control gauges
fill(r2,0,0); //red box on RIGHT to gauge red value of inner circle
noStroke();
rect(width-interfaceW,0,interfaceW, interfaceH); //line to guage red value of inner circle
stroke(255-backc);
line(width-interfaceW,(r2*interfaceH)/255,width,(r2*interfaceH)/255);
noStroke();
fill(0,g2,0); //green box on RIGHT to gauge green value of inner circle
rect(width-interfaceW,interfaceH,interfaceW, interfaceH);
stroke(255-backc);
line(width-interfaceW,(g2*interfaceH)/255+(interfaceH),width,(g2*interfaceH)/255+(interfaceH)); //line to tell green value
}



// display the spots:
for(int i=0;i<foo.length;i++) {
foo[i].display();
}

}

class Spot {
float x, y, radius;
float vx,vy; // to store velocities
color colour;

Spot(float xpos, float ypos, float r, color c) {
x = xpos;
y = ypos;
vx = random(-1,1); // create small random horizontal velocity
vy = 1 + random(3); // set a vertical velocity
radius = r;
colour = c;
}

void display() {
color from = color(r1,g1,b1,a);
color to = color(r2,g2,b2,a);
color interA = lerpColor(from, to, .25);
color interB = lerpColor(from, to, .5);
color interC = lerpColor(from, to, .75);

noStroke();

fill(from);
ellipse(x, y, radius*5, radius*5);

fill(interA);
ellipse(x, y, radius*4, radius*4);

fill(interB);
ellipse(x, y, radius*3, radius*3);

fill(interC);
ellipse(x, y, radius*2, radius*2);

fill(to);
ellipse(x, y, radius, radius);
x += vx;
y += vy;


// If they go beyond the bottom of the screen one option is to simply place them back at the top:
if(y > height + (maxRadius * 5)) {
// by resetting all these it will look like a different ball
int r = (int) random(100);
int g = (int) random(100);
int b = 155 + (int) random(100);
colour = color(r,g,b);
radius = 1+random(30);
vx = random(-1,1); // create small random horizontal velocity
vy = 1 + random(3); // set a vertical velocity
x = random(width);
y = -(maxRadius * 5);
}

if(mousePressed){
if (mouseY > (0.98*height)) {
backc = ((255*mouseX)/width);
}

if (mouseX > 1 && mouseX < interfaceW && mouseY < (interfaceH)) {
r1 = ((255*mouseY)/(interfaceH));
}
if (mouseX > 1 && mouseX < interfaceW && mouseY > (interfaceH)) {
g1 = ((255*mouseY)/(interfaceH)-255);
}
if (mouseX > width-interfaceW && mouseY < (interfaceH)) {
r2 = ((255*mouseY)/(interfaceH));
}
if (mouseX > width-interfaceW && mouseY > (interfaceH)) {
g2 = ((255*mouseY)/(interfaceH)-255);
}
}
}

}
Re: raining circles (blended circles)
Reply #5 - Dec 29th, 2009, 11:34am
 
Much cleaner. Thank you. One thing to know is that my output will be primarily on a projector with a wii remote and a led infrared light (wii whiteboard) -- (until I can figure out the shadow stuff) -- but this essentially makes mouse clicks challenging. Thus, if possible, all mouse movements -- no clicks no keyboard... Somewhat limiting for sure.
OK, now I dig in to try to learn how made the changes. Thank you.
Re: raining circles (blended circles)
Reply #6 - Dec 29th, 2009, 11:37am
 
I'm going to work on trying this:
Quote:
Reacting to the mouse is simple enough: just check if the circle is within range of the current mouse position and adjust its motion appropriately (though note that this could interfere with any mouse-controlled colour change interface you may implement).
Re: raining circles (blended circles)
Reply #7 - Feb 10th, 2010, 3:42am
 
any suggestions on how to create an area of the screen that when mouseover increases the balls by a count of one and a separate area of the screen that when mouseover decreases the balls by a count of one?

Spot foo[] = new Spot[20];  // Since you'll want more than one spot create an array to store multiple spots

float r1 = 170;
float g1 = 211;
float b1 = 126;
float r2 = 91;
float g2 = 105;
float b2 = 176;
int a = 150;
int backc = 255;

int maxRadius;
float interfaceW;
float interfaceH;
float barwidth;
float barheight;
float topbarW;
float topbarH;
float speed;


void setup(){
size(900,700);
barwidth = 0.04;
barheight = 0.5;
interfaceW = barwidth*width;
interfaceH = barheight*height;
topbarW = barheight*width;
topbarH = barwidth*height;
maxRadius = 30;
speed = 0.5; // from 0-1, 0 is slowest

// fill(255,0,0);
// rect(0,0,0.02*width, interfaceH);

// Whenever you want to do something to all your spots you need to iterate through the array:
for(int i=0;i<foo.length;i++) {
  // create a random colour.  By limiting r and g and setting a minimum for b we should get a selection of blues
  // while I adjusted color for the circles later, i couldn't delete this area without losing it all

 int r = (int) random(100);
 int g = (int) random(100);
  int b = 155 + (int) random(100);
 color colour = color(r,g,b);
  // create the Spot objects:
  foo[i] = new Spot(random(width),0,10+random(maxRadius), colour);
}
smooth();

}


void draw(){
  background(backc);
   //begin "if mouse gets near edges do controls of inner and outer circles
   
   if(mousePressed){
       r1 = 170;
       g1 = 211;
       b1 = 126;
       r2 = 91;
       g2 = 105;
       b2 = 176;
       a = 150;
       backc = 255;
     }

   
    if (mouseY > (0.97*height)) {
      backc = ((255*mouseX)/width); //change background shade
        fill(255-backc);
        rect(0,height*0.97,width,height);  //black bar on bottom
        stroke(255-backc);
        line(mouseX,0.96*height, mouseX, height);
    }
    //left OUTER circle
    if (mouseX > 1 && mouseX < interfaceW && mouseY < (interfaceH)) { //outer circle, red control
      r1 = ((255*mouseY)/(interfaceH)); //red
        noStroke();  
        fill(r1,100,100); //red box on left to gauge red value
        rect(0,0,interfaceW, interfaceH); //line to guage red value
        stroke(255-backc);
        line(0,(r1*interfaceH)/255,interfaceW,(r1*interfaceH)/255);
    }
    if (mouseX > 1 && mouseX < interfaceW && mouseY > (interfaceH)) {
      g1 = ((255*mouseY)/(interfaceH)-255); //green
        noStroke();  
        fill(100,g1,100); //green box on left to gauge green value
        rect(0,interfaceH,interfaceW, interfaceH);  
        stroke(255-backc);
        line(0,(g1*interfaceH)/255+(interfaceH),interfaceW,(g1*interfaceH)/255+(interfac
eH)); //line to tell green value
    }
   
    //right INNER circle
    if (mouseX > width-interfaceW && mouseY < (interfaceH)) {
      r2 = ((255*mouseY)/(interfaceH)); //red
        fill(r2+50,50,50); //red box on RIGHT to gauge red value of inner circle
        noStroke();
        rect(width-interfaceW,0,interfaceW, interfaceH); //line to guage red value of inner circle
        stroke(255-backc);
        line(width-interfaceW,(r2*interfaceH)/255,width,(r2*interfaceH)/255);
    }
    if (mouseX > width-interfaceW && mouseY > (interfaceH)) {
      g2 = ((255*mouseY)/(interfaceH)-255);
        noStroke();  
        fill(100,g2,100); //green box on RIGHT to gauge green value of inner circle
        rect(width-interfaceW,interfaceH,interfaceW, interfaceH);
        stroke(255-backc);
        line(width-interfaceW,(g2*interfaceH)/255+(interfaceH),width,(g2*interfaceH)/255
+(interfaceH));  //line to tell green value
    }

    //blue TOP
      if (mouseX > 1 && mouseX < topbarW && mouseY < topbarH) { //outer circle, blue control
      b1 = ((255*mouseX)/(topbarW));
        noStroke();  
        fill(100,100,b1); //blue box on top L to gauge blue value
        rect(0,0,topbarW, topbarH); //line to guage blue value
        stroke(255-b1);
        line(b1*topbarW/255,0,b1*topbarW/255,topbarH);
    }
    if (mouseX > 1 && mouseX > topbarW && mouseY < topbarH) {
      b2 = ((255*mouseX)/(topbarW)-255);
        noStroke();  
        fill(100,100,b2); //blue box on top R to gauge blue value
        rect(topbarW, 0, width, topbarH);  
        stroke(255-backc);
        line((b2*topbarW)/255+topbarW, 0, (b2*topbarW)/255+topbarW,topbarH); //line to tell blue value
    }
   
   

// display the spots:
for(int i=0;i<foo.length;i++) {
  foo[i].display();
}



}

class Spot {
float x, y, radius;
float vx,vy; // to store velocities
color colour;

Spot(float xpos, float ypos, float r, color c) {
  x = xpos;
  y = ypos;
  vx = random(-1,1);  // create small random horizontal velocity
  vy = 1 + random(3);  // set a vertical velocity
  radius = r;
  colour = c;
}

void display() {
  color from = color(r1,g1,b1,a);
  color to = color(r2,g2,b2,a);
  color interA = lerpColor(from, to, .25);
  color interB = lerpColor(from, to, .5);
  color interC = lerpColor(from, to, .75);
 
  noStroke();
 
  fill(from);
  ellipse(x, y, radius*5, radius*5);

  fill(interA);
  ellipse(x, y, radius*4, radius*4);
   
  fill(interB);
  ellipse(x, y, radius*3, radius*3);

   fill(interC);
  ellipse(x, y, radius*2, radius*2);
 
  fill(to);
  ellipse(x, y, radius, radius);
      x += vx*speed;
        y += vy*speed;
 
//  if mouseX = x and  mouseY = y{
//    x = mouseX;
//    y = mouseY;
//  }
 //   else if x <> mouseX and y <> mouseY; {
 
 //   }
 
  // If they go beyond the bottom of the screen one option is to simply place them back at the top:
  if(y > height + (maxRadius * 5)) {
    // by resetting all these it will look like a different ball
    int r = (int) random(100);
    int g = (int) random(100);
    int b = 155 + (int) random(100);
    colour = color(r,g
Re: raining circles (blended circles)
Reply #8 - Feb 10th, 2010, 5:40am
 
gabecolors wrote on Feb 10th, 2010, 3:42am:
any suggestions on how to create an area of the screen that when mouseover increases the balls by a count of one and a separate area of the screen that when mouseover decreases the balls by a count of one


(Careful - your code is getting too long to fit into a single post...)

Well you've already implemented something along the lines of what you describe with the colour change interface: First you need to check if the mouse is over the relevant portion of the screen; then you need to add/remove circles.  That's the slightly more tricky bit.

To make things easier for yourself in the longer term I'd suggest you use an ArrayList instead of an array to store the circle objects.  There's a little bit more work and a touch more complexity involved but it will make adding and removing circles much easier (see the additional documentation from the above reference page, in particular the add() and remove() methods).  One word of warning though - if you try to use remove() whilst iterating over an ArrayList you'll get an error.  That means you may have to flag an object to be deleted and then only delete it when it is safe to do so.

One further point - it would probably be a good idea to limit the rate at which circles are added/removed, perhaps using a timer or checking that a certain number of frames have elapsed: adding circles at the framerate might be a little unwieldy Wink
Re: raining circles (blended circles)
Reply #9 - Feb 16th, 2010, 1:40am
 
thanks blindfish. i think i'm in over my head with the time i have, but i did want to say that i read your post and tried and thank you for the suggestions... my code is a mess so I am just trying to clean it up a bit...

(you'll note i also removed indicators and brought controls over most of screen. it becomes an excerise for the user to figure out on his own how to control RGB and background)

Spot foo[] = new Spot[20];

//create initial color scheme for halation circles
float r1 = 170;
float g1 = 211;
float b1 = 126;
float r2 = 91;
float g2 = 105;
float b2 = 176;
int a = 150; //alpha
float backc = 255; //background white

int maxRadius;
float speed;
float interfaceW1; //width of controls for colors .45
float interfaceW2;
float interfaceH; //height of controls for colors .25
float backbarYpos;


void setup() {
 size (800,600);
 maxRadius = 20;
 speed = 0.5;
 interfaceW1 = 0.45*width;
 interfaceW2 = 0.55*width;
 interfaceH = 0.25*height;
 backbarYpos = 0.9*height;
//  backvalue = (255*mouseX)/width; TRIED THIS BUT THINK that calculations here don't work when come from mouse

 //there is stuff in the following part that isn't used but i don't know how to delete it without losing functionality
 for(int i=0;i<foo.length;i++) {
   int r = (int) random(100);
   int g = (int) random(100);
   int b = 155 + (int) random(100);
   color colour = color(r,g,b);
   foo[i] = new Spot(random(width),0,10+random(maxRadius), colour);
 }
 smooth();
}

void draw(){
 //go to default color if mouse pressed
 if(mousePressed){
   r1 = 170;
   g1 = 211;
   b1 = 126;
   r2 = 91;
   g2 = 105;
   b2 = 176;
   a = 150;
   backc = 255;
 }

 background(backc);

 //mouseover controls
 if (mouseY > backbarYpos) {
   backc = (255*mouseX)/width;
 }

 if (mouseX < interfaceW1 && mouseY < 0.25*height) {
   r1 = ((255*mouseX)/(interfaceW1));
 }
 if (mouseX > interfaceW2 && mouseY < 0.25*height) {
   r2 = ((255*(mouseX-interfaceW2))/interfaceW1);
 }

 if (mouseX < interfaceW1 && mouseY > 0.3*width && mouseY < 0.55*height) {
   g1 = ((255*mouseX)/(interfaceW1));
 }
 if (mouseX > interfaceW2 && mouseY > 0.3*width && mouseY < 0.55*height) {
   g2 = ((255*(mouseX-interfaceW2))/interfaceW1);
 }

 if (mouseX < interfaceW1 && mouseY > 0.6*width && mouseY < 0.85*height) {
   b1 = ((255*mouseX)/(interfaceW1));
 }
 if (mouseX > interfaceW2 && mouseY > 0.6*width && mouseY < 0.85*height) {
   b2 = ((255*(mouseX-interfaceW2))/interfaceW1);
 }



 // display the spots:
 for(int i=0;i<foo.length;i++) {
   foo[i].display();
 }

}


class Spot {
float x, y, radius;
float vx,vy; // to store velocities
color colour;

Spot(float xpos, float ypos, float r, color c) {
  x = xpos;
  y = ypos;
  vx = random(-1,1);  // create small random horizontal velocity
  vy = 1 + random(3);  // set a vertical velocity
  radius = r;
  colour = c;
}

void display() {
  color from = color(r1,g1,b1,a);
  color to = color(r2,g2,b2,a);
  color interA = lerpColor(from, to, .25);
  color interB = lerpColor(from, to, .5);
  color interC = lerpColor(from, to, .75);
 
  noStroke();
 
  fill(from);
  ellipse(x, y, radius*5, radius*5);

  fill(interA);
  ellipse(x, y, radius*4, radius*4);
   
  fill(interB);
  ellipse(x, y, radius*3, radius*3);

   fill(interC);
  ellipse(x, y, radius*2, radius*2);
 
  fill(to);
  ellipse(x, y, radius, radius);
      x += vx*speed;
        y += vy*speed;

 
  // If they go beyond the bottom of the screen one option is to simply place them back at the top:
  if(y > height + (maxRadius * 5)) {
    // by resetting all these it will look like a different ball
    int r = (int) random(100);
    int g = (int) random(100);
    int b = 155 + (int) random(100);
    colour = color(r,g,b);
    radius = 1+random(30);
    vx = random(-1,1);  // create small random horizontal velocity
    vy = 1 + random(3);  // set a vertical velocity
    x = random(width);
    y = -(maxRadius * 5);
  }
 
 

}

}  

//thanks blindfish
Page Index Toggle Pages: 1