2

I have n number of ball objects (each starting with a random velocity (0,4)) on the screen (in 2D) moving about colliding with each other. What I want to do is to assign each ball a colour based on their velocity, such that the balls with the highest velocity (say v) have the colour blue and the colour becomes increasingly red as the speed goes down (intermediate velocities take the range of rainbow colours). I understand it's a range conversion problem.

How do I go about this?

I have tried to get the magnitude of the velocity of the ball and rescale it to a range (0,255). Then I use the fill method to give colour to the balls.

public void display(){

    float v = sqrt(pow(this.getDX(),2)+pow(this.getDY(),2));
    int scale = (int)(v * 255)/8;
    stroke(0);

    fill(scale,0,scale);   
    ellipse(this.xpos, this.ypos, this.size ,this.size);
  }
}

I am unable to get the desired results. Mostly because I have no clue how to mix the colours, in this case, to get red for slowest balls and blue for the fastest balls.

  • Perhaps [lerpColor()](https://processing.org/reference/lerpColor_.html) can help. In any event, it would help if you gave more information about the range of `v` values that you intend to cover. It would be even better if you give a [mcve] to experiment with. – John Coleman Jan 21 '19 at 14:15
  • I do not expect `v` to be more than ~16-20. The minimum will be 0. Here are the Pastebin links to the entire code : 1) Main : https://pastebin.com/S0JBeEkW 2) Classes : https://pastebin.com/xLg2fE0k – Debajyoti Sengupta Jan 21 '19 at 14:33
  • 1
    Maybe something along the lines of (untested) `fill(lerpColor(color(255,0,0),color(0,0,255),map(v,0,20,0,1)))`. – John Coleman Jan 21 '19 at 14:37
  • This works well. I will test for a range of velocities and see it reproduces the desired result. – Debajyoti Sengupta Jan 21 '19 at 14:40
  • Ideally, I would want the entire range of rainbow colours to be mapped. ```color(255,0,0),color(0,0,255)``` only does R and B. Sorry, I should have been clearer. – Debajyoti Sengupta Jan 21 '19 at 15:34
  • 2
    In that case, maybe [this answer](https://stackoverflow.com/a/47860875/4996248) by Kevin Workman (Stack Overflow's resident Processing expert) will help. – John Coleman Jan 21 '19 at 15:48
  • @JohnColeman Aw shucks, thanks! :p – Kevin Workman Jan 21 '19 at 17:30

1 Answers1

2

[...] such that the balls with the highest velocity (say v) have the colour blue and the colour becomes increasingly red as the speed goes down (intermediate velocities take the range of rainbow colours) [...]

Read about the HSL and HSV color range, and write a method which transforms a hue value in range [0.0, 1.0] to a RGB color and sets the fill() color:

public void SetFillFromHUE(float hue) {

    float R = Math.abs(hue * 6.0 - 3.0) - 1.0;
    float G = 2.0 - Math.abs(hue * 6.0 - 2.0);
    float B = 2.0 - Math.abs(hue * 6.0 - 4.0);
    fill(R*255.0, G*255.0, B*255.0); 
}

I investigated that the v value always is in range [0, 10.0] (from your previous question Buggy bouncing balls.

So

float v = sqrt(pow(this.getDX(),2)+pow(this.getDY(),2)) / 10.0;

will give a value dependent on the velocity v in range [0.0, 1.0].

Investigating the hue color range, shows that 0.0 is red and 0.66 is blue.

SetFillFromHUE(v * 2.0/3.0);

sets a color that ranges from red to yellow to green to blue.

The final method display looks like this:

public void display(){

    float v = sqrt(pow(this.getDX(),2)+pow(this.getDY(),2)) / 10.0;

    stroke(0);
    SetFillFromHUE( v * 4.0/6.0 ); 
    ellipse(this.xpos, this.ypos, this.size ,this.size);
}

Rabbid76
  • 202,892
  • 27
  • 131
  • 174