# Complex gradient loop

**URL:** <https://discourse.processing.org/t/complex-gradient-loop/42832>\
**Category:** Coding Questions\
**Created:** [September 25, 2023, 9:15pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832 "2023-09-25T21:15:59Z")\
**Posts on this page:** 12\
**Page:** 2

<div class="post-metadata">

**Author:** ![humano](https://avatars.discourse-cdn.com/v4/letter/h/dbc845/32.png) [@humano](https://discourse.processing.org/u/humano)\
**Post date:** [September 28, 2023, 9:10pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/21 "2023-09-28T21:10:02Z")

</div>

And playing with the program and I am hallucinating with results. I have obtained this amazing gradient that you can see here:

> colorMode( HSB, 360,100,100 );

> ```
> color c = color( random(1,360), 100, 100 );
> 
> ```

 ![gradient_generator-2023-09-28-17-11-36](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/8/0/808cb007c439d2a6fe648c6f84b14c936c3e225f.png)  
But sometimes the result is dirtier because the colors of the points art not as closer and organized in the colour wheel:  
 ![gradient_generator-2023-09-28-17-17-23](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/5/9/596e838c281400027d714a83c215326838126b52.png)  
So how could I relate these points to follow the order of colors in colour wheel, from hue 1 to 360 in HSB color mode? Imagine that randoms colors are 22,45,154, 263,302 and 313, how could I distribute them like this: point 1(22), point 2(45), point 3(154), point 4(263), point 5(302), point 6(313)?

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [September 28, 2023, 10:07pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/22 "2023-09-28T22:07:00Z")

</div>

In `initControlPoints()`, you could change it to:

```auto
  for( int i=0; i<N; i++ ) {
    float ang = TAU*i/N;
    int x = (int)((0.5 + 0.4*cos(ang)) * 65536);
    int y = (int)((0.5 + 0.4*sin(ang)) * 65536);
    color c = color( 360.0*i/N, 100, 100 );
    inputs.pixels[i] = (x << 16) | y;
    inputs.pixels[i+N] = c;
  }

```

If you want some randomness, you would want to randomly generate and store N hue values in an array, sort it, and read them out in order when filling the `input.pixels`.

```auto
  float[] hues = new float[N];
  for( int i=0; i<N; i++ ) hues[i] = random(360);
  hues = sort( hues );
  for( int i=0; i<N; i++ ) {
    float ang = TAU*i/N;
    float r = random( 0.2, 0.5 );
    int x = (int)((0.5 + r*cos(ang)) * 65536);
    int y = (int)((0.5 + r*sin(ang)) * 65536);
    color c = color( hues[i], 100, 100 );
    inputs.pixels[i] = (x << 16) | y;
    inputs.pixels[i+N] = c;
  }

```

---

<div class="post-metadata">

**Author:** ![jafal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jafal/32/19112_2.png) [@jafal](https://discourse.processing.org/u/jafal)\
**Post date:** [September 29, 2023, 1:21am UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/23 "2023-09-29T01:21:52Z")

</div>

Hi

Complex but easy

```auto
void setup () {
size (600,600);
colorMode(HSB);
}
void draw(){
for(int i= 600; i >0; i=i -1) {
  stroke((i/2) + (mouseX/2), 300,300);
rect(0,0,i ,i);
}
}

```

---

<div class="post-metadata">

**Author:** ![humano](https://avatars.discourse-cdn.com/v4/letter/h/dbc845/32.png) [@humano](https://discourse.processing.org/u/humano)\
**Post date:** [October 2, 2023, 5:29pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/24 "2023-10-02T17:29:18Z")

</div>

well, no I am trying to change

> size( 1200, 1600, P3D );

and I receive this message:

“The sketch has been resized from 1200x1600 to 1200x1055 by the operating system.  
This happened outside Processing, and may be a limitation of the OS or window manager.”

how could make this image bigger in windows?

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [October 2, 2023, 5:52pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/25 "2023-10-02T17:52:30Z")

</div>

You can keep `size()` so it fits on your screen, but, in my code above, you can set the size of the `grad` PGraphics to be as large as you want.

So

```auto
void setup() {
  size( 600, 800, P3D );
  colorMode( HSB, 1, 1, 1, 1 );
  grad = createGraphics( width*2, height*2, P3D );
  gradShader = new PShader( this, gradVert, gradFrag );
  initControlPoints();
  gradShader.set( "strength", strength );
  gradShader.set( "bOklab", bOklab );
  noLoop();
}

```

and in `draw()`, change `image()` to `image( grad, 0, 0, width, height );` and where I have `save( fileName );` change it to `grad.save( fileName );` so it saves the PGraphics image rather than the screen image.

---

<div class="post-metadata">

**Author:** ![humano](https://avatars.discourse-cdn.com/v4/letter/h/dbc845/32.png) [@humano](https://discourse.processing.org/u/humano)\
**Post date:** [October 6, 2023, 7:41pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/26 "2023-10-06T19:41:28Z")

</div>

And what If I wanted to choose coordinates and colors of the control points? How could I use, for example, these values?

```auto
float x1 = 525;
float y1 = 150;
float x2 = 990;
float y2 = 500;
float x3 = 550;
float y3 = 925;
float x4 = 275;
float y4 = 725;
float x5 = 500;
float y5 = 125;
float x6 = 250;
float y6 = 200;

color a = color(179,100,100);
color b = color(68, 100,100);
color c = color(303, 100,100);
color d = color(299, 100,100);
color e = color(276, 100,100);
color f = color(193, 100,100);

```

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [October 6, 2023, 8:50pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/27 "2023-10-06T20:50:39Z")

</div>

Put them in an array and read from the array in the loop to fill the `inputs` texture. For instance if you have the coordinates in `x[]` and `y[]` and the colors in `c[]`, then you would use:

```auto
  for( int i=0; i<N; i++ ) {
    int x = (int)(65536 * x[i] / grad.width);
    int y = (int)(65536 * y[i] / grad.height);
    inputs.pixels[i] = (x << 16) | y;
    inputs.pixels[i+N] = c[i];
  }

```

---

<div class="post-metadata">

**Author:** ![humano](https://avatars.discourse-cdn.com/v4/letter/h/dbc845/32.png) [@humano](https://discourse.processing.org/u/humano)\
**Post date:** [October 6, 2023, 11:22pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/28 "2023-10-06T23:22:37Z")

</div>

like this?

```auto
float[] positions = new float [12];
float [x1] = 525;
float [y1] = 150;
float [x2] = 990;
float [y2] = 500;
float [x3] = 550;
float [y3] = 925;
float [x4] = 275;
float [y4] = 725;
float [x5] = 500;
float [y5] = 125;
float [x6] = 250;
float [y6] = 200;

color[] colors = new color [];
color [a] = color(179,100,100);
color [b] = color(68, 100,100);
color [c] = color(303, 100,100);
color [d] = color(299, 100,100);
color [e] = color(276, 100,100);
color [f] = color(193, 100,100);

```

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [October 6, 2023, 11:44pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/29 "2023-10-06T23:44:23Z")

</div>

More like this. It’s easier to make a 2D array of floats for the positions. I wouldn’t name an array `color` since that’s already a Processing function name – could be confusing.

> [@scudly](#):
>
> ```auto
> float[][] pos = {
> { 525, 150 }, { 990, 500 }, { 550, 925 },
> { 275, 725 }, { 500, 125 }, { 250, 200 }
> };
> color[] cols = { 
> color( 179, 100, 100 ), color( 68, 100, 100 ), color( 303, 100, 100 ),
> color( 299, 100, 100 ), color( 276, 100, 100 ), color( 193, 100, 100 )
> };
> 
> for( int i=0; i<N; i++ ) {
> int x = (int)(65536 * pos[i][0] / grad.width);
> int y = (int)(65536 * pos[i][1] / grad.height);
> inputs.pixels[i] = (x << 16) | y;
> inputs.pixels[i+N] = cols[i];
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![jafal](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jafal/32/19112_2.png) [@jafal](https://discourse.processing.org/u/jafal)\
**Post date:** [October 6, 2023, 11:55pm UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/30 "2023-10-06T23:55:34Z")

</div>

Hi

> **[Two-Dimensional Arrays](https://processing.org/tutorials/2darray/)**
>
> Store and acess data in a matrix using a two-dimensional array.

---

<div class="post-metadata">

**Author:** ![humano](https://avatars.discourse-cdn.com/v4/letter/h/dbc845/32.png) [@humano](https://discourse.processing.org/u/humano)\
**Post date:** [October 7, 2023, 2:09am UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/31 "2023-10-07T02:09:31Z")

</div>

Thanks! And do I receive this message? “NullPointerException” for this line

> ```
> inputs.pixels[i] = (x << 16) | y;
> 
> ```

```auto
PImage inputs;
PGraphics grad;
PShader gradShader;

int N = 9;
float strength = 1.;
boolean bShowPoints = true;
boolean bSaveFrame = false;

void setup() {
  size( 750, 1000, P3D );
  //fullScreen( P3D, SPAN );
  colorMode( HSB, 360,100,100 );
  grad = createGraphics( width, height, P3D );
  gradShader = new PShader( this, gradVert, gradFrag );
  initControlPoints();
  gradShader.set( "strength", strength );
  noLoop();
}

void initControlPoints() {
    float[][] pos = {
  { 525, 150 }, { 990, 500 }, { 550, 925 },
  { 275, 725 }, { 500, 125 }, { 250, 200 }
};
color[] cols = { 
  color( 179, 100, 100 ), color( 68, 100, 100 ), color( 303, 100, 100 ),
  color( 299, 100, 100 ), color( 276, 100, 100 ), color( 193, 100, 100 )
};

  for( int i=0; i<N; i++ ) {
    int x = (int)(65536 * pos[i][0] / grad.width);
    int y = (int)(65536 * pos[i][1] / grad.height);
    inputs.pixels[i] = (x << 16) | y;
    inputs.pixels[i+N] = cols[i];
  }
  //inputs = createImage( N, 2, ARGB );
  //inputs.loadPixels();
  //float[] hues = new float[N];
  // for( int i=0; i<N; i++ ) hues[i] = random(360);
  //hues = sort( hues );
  //for( int i=0; i<N; i++ ) {
  //float ang = TAU*i/N;
  // float r = random( 0.2, 0.5 );
    // int x = (int)((0.5 + r*cos(ang)) * 65536);
    // int y = (int)((0.5 + r*sin(ang)) * 65536);
    //color c = color( hues[i], 100, 100 );
    //inputs.pixels[i] = (x << 16) | y;
    //inputs.pixels[i+N] = c;
  //}
 //inputs.updatePixels();
 //gradShader.set( "inputs", inputs );
 //gradShader.set( "N", N );
}

void draw() {
  gradShader.set( "bShowPoints", bShowPoints );
  grad.beginDraw();
  grad.noStroke();
  grad.shader( gradShader );
  grad.rect( 0, 0, grad.width, grad.height );
  grad.resetShader();
  grad.endDraw();
  image( grad, 0, 0 );
  if( bShowPoints ) 
    text( str(N)+" "+str(strength), 8, 16 );
  if( bSaveFrame ) {
    String fileName = getClass().getSimpleName() + "-" +
      nf(year(),4) + "-" + nf(month(),2) + "-" + nf(day(),2) + "-" +
      nf(hour(),2) + "-" + nf(minute(),2) + "-" + nf(second(),2) + ".TIFF";
    save( fileName );
    println( "saved " + fileName );
    bSaveFrame = false;
  }
}

void keyPressed() {
  if( keyCode == ENTER ) initControlPoints();
  else if( keyCode == DOWN ) { 
    strength /= 1.1;    
    gradShader.set( "strength", strength );
  }
  else if( keyCode == UP ) { 
    strength *= 1.1;    
    gradShader.set( "strength", strength );
  }
  else if( keyCode == LEFT ) { N = max(N-1, 1); initControlPoints(); }
  else if( keyCode == RIGHT ) { N++; initControlPoints(); }
  else if( key == ' ' ) bShowPoints = !bShowPoints;
  else if( key == '+' ) bSaveFrame = true;
  redraw();
}

String[] gradVert = {"""
#version 330
uniform mat4 transformMatrix;
in vec4 position;
void main() {
  gl_Position = transformMatrix * position;
}
"""};

String[] gradFrag = {"""
#version 330
precision highp float;
uniform vec2 resolution;
uniform sampler2D inputs;
uniform int N;
uniform bool bShowPoints;
uniform float strength;
out vec4 fragColor;

void main() {
  float aspect = resolution.x/resolution.y;
  vec2 uv = gl_FragCoord.xy / resolution.y;
  vec3 col = vec3(0.);
  float totw = 0.;
  for( int i=0; i<N; i++ ) {
    vec4 posData = texelFetch( inputs, ivec2( i, 0 ), 0 ) * 255.0;
    float x = (posData.a * 256 + posData.r)*aspect;
    float y = posData.g * 256 + posData.b;
    vec2 pos = vec2( x, y ) / 65536.0;
    vec3 c = texelFetch( inputs, ivec2( i, 1 ), 0 ).rgb;
    float d = length( uv - pos );
    float w = exp( -d*d*N*strength );
    if( w > 0 ) {
      col += c * w;
      totw += w;
    }
  }
  if( totw > 0. ) col /= totw;

  if( bShowPoints ) {
    for( int i=0; i<N; i++ ) {
      vec4 posData = texelFetch( inputs, ivec2( i, 0 ), 0 ) * 255.0;
      float x = (posData.a * 256 + posData.r)*aspect;
      float y = posData.g * 256 + posData.b;
      vec2 pos = vec2( x, y ) / 65536.0;
      vec3 c = texelFetch( inputs, ivec2( i, 1 ), 0 ).rgb;
      float d = length( uv - pos );
      if( d < 0.01 ) col = vec3(1.);
      if( d < 0.007 ) col = c;
    }
  }

  fragColor = vec4( col, 1. );
}
"""};

```

---

<div class="post-metadata">

**Author:** ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)\
**Post date:** [October 7, 2023, 3:17am UTC](https://discourse.processing.org/t/complex-gradient-loop/42832/32 "2023-10-07T03:17:39Z")

</div>

You have to keep the rest of the code that creates the PImage. And because you have 6 points, you have to set N to 6 at the top or can set it to `N = pos.length;` after creating the `pos` array as I did in the code below.

```auto
void initControlPoints() {
float[][] pos = {
  { 525, 150 }, { 990, 500 }, { 550, 925 },
  { 275, 725 }, { 500, 125 }, { 250, 200 }
};
color[] cols = { 
  color( 179, 100, 100 ), color( 68, 100, 100 ), color( 303, 100, 100 ),
  color( 299, 100, 100 ), color( 276, 100, 100 ), color( 193, 100, 100 )
};

  N = pos.length;
  inputs = createImage( N, 2, ARGB );
  inputs.loadPixels();
  for( int i=0; i<N; i++ ) {
    int x = (int)(65536 * pos[i][0] / grad.width);
    int y = (int)(65536 * pos[i][1] / grad.height);
    inputs.pixels[i] = (x << 16) | y;
    inputs.pixels[i+N] = cols[i];
  }
  inputs.updatePixels();
  gradShader.set( "inputs", inputs );
  gradShader.set( "N", N );
}

```

[Previous page](https://discourse.processing.org/t/complex-gradient-loop/42832.md?page=1)
