Degradado Lineal Diagonal

Hi!

How could I change this linear gradient from horizontal to diagonal?

Thanks!



void setup(){
  size(360,720);
  smooth();
  background(255,95,95);
  float l = width/255;
  for(int i = 0; i<width; i++) {
  stroke(255,123,97,255-i/(l));
  line(i,0,i, height);
}

}

You can use either line(0,i,i,0) or line(i,0,0,i).

thanks lexyth, I used this code, but Id like to change diagonal gradient from 1 to 2, as you can see in the image.

void setup(){
  size(270,540);
  smooth();
  background(255,95,95);
  float l = width/255;
  for(int i = 0; i<width; i++) {
  stroke(255,123,97,255-i/(l));
  line(i,0,0,i);
}

}

1 Like

Hi @humano,

There’s more than one way to go about it. If you click on the magnifying glass and search the forum you’ll find a few earlier threads.

If you have some understanding of how to define and create objects, and of how vectors / points work, that knowledge will go a long way. Specifically, I’m referring to scalar projection. Depending on how you plan to move the line of the gradient from 1 to 2, looking at lerp could help as well. As with points and vectors, so too with color: lerpColor.

The example code below is not the fastest way, but it shows an object oriented way of making a diagonal gradient.

A Vec2 class:

static class Vec2 {
  float x, y;

  Vec2 () {
  }

  Vec2 ( float x, float y ) {
    set(x, y);
  }

  Vec2 set ( Vec2 source ) {
    return set(source.x, source.y);
  }

  Vec2 set (  float x, float y ) {
    this.x = x;
    this.y = y;
    return this;
  }

  static float dot ( Vec2 a, Vec2 b ) {
    return a.x * b.x + a.y * b.y;
  }

  static Vec2 mult ( Vec2 a, float b, Vec2 target ) {
    return target.set(a.x * b, a.y * b);
  }

  static float project ( Vec2 a, Vec2 b, Vec2 target ) {
    float bMagSq = dot(b, b);
    if (bMagSq != 0.0) {
      float dAbBb = dot(a, b) / bMagSq;
      mult(b, dAbBb, target);
      return constrain(dAbBb, 0.0, 1.0);
    }
    target.set(0.0, 0.0);
    return 0.0;
  }

  static Vec2 sub ( Vec2 a, Vec2 b, Vec2 target ) {
    return target.set(a.x - b.x, a.y - b.y);
  }

  static Vec2 lerp( Vec2 a, Vec2 b, float t, Vec2 target) {
    if (t <= 0.0) return target.set(a);
    if (t >= 1.0) return target.set(b);
    return lerpUnclamped(a, b, t, target);
  }

  static Vec2 lerpUnclamped ( Vec2 a, Vec2 b, float t, Vec2 target ) {
    float u = 1.0 - t;
    return target.set(
      a.x * u + b.x * t, 
      a.y * u + b.y * t);
  }
}

The main sketch, which relies on loadPixels, pixels and updatePixels.

//color a = #FF5F5F;
//color b = #FF7B61;
color a = #FF0000;
color b = #0000FF;

Vec2 origin = new Vec2(0, 0);
Vec2 desta = new Vec2(270, 270);
Vec2 destb = new Vec2(270, 540);
Vec2 dest = new Vec2();
Vec2 point = new Vec2();
Vec2 projection = new Vec2();
Vec2 op = new Vec2();
Vec2 od = new Vec2();

void setup() {
  size(270, 540);
}

void draw() {
  float t = 0.5 + 0.5 * cos(frameCount * 0.05);
  Vec2.lerp(desta, destb, t, dest);

  loadPixels();
  for (int i = 0, y = 0; y < height; ++y) {
    point.y = y;
    for (int x = 0; x < width; ++x, ++i) {
      point.x = x;
      float fac = linearGradient(
        origin, dest, point, 
        projection, op, od);
      pixels[i] = lerpColor(a, b, fac, RGB);
    }
  }
  updatePixels();
  
  stroke(255.0);
  strokeWeight(1.25);
  line(origin.x, origin.y, dest.x, dest.y);
}

static float linearGradient ( 
  Vec2 origin, 
  Vec2 dest, 
  Vec2 point, 

  Vec2 projection, 
  Vec2 op, 
  Vec2 od ) {

  Vec2.sub(origin, point, op);
  Vec2.sub(origin, dest, od);
  return Vec2.project(op, od, projection);
}

Best.

1 Like

thank you @behreajj

maybe this is too complicated for my, so I have decided use an horizontal linear gradient. But when I write my gradient code in my animation, it doesn’t work!!! The middle of the gradient is not in the middle of the screen. Do you know why?

Thank you so much

int cx, cy;
int offset;

float secondsRadius;
float clockDiameter;

void setup() {
  size(270, 540);
  background(247,108,127);
  stroke(255);
  offset = second();
  
  int radius = min(width, height) / 2;
  secondsRadius = radius * 0.72;
  clockDiameter = radius * 1.8;
  
  cx = width / 2;
  cy = height / 2;
}

void draw() {
  background(247,108,127);
  float l = width/255;
  for(int i = 0; i<width; i++) {
  stroke(252,150,120,255-i/(l));
  line(i,0,i, height);
}
  
 
  
  // Angles for sin() and cos() start at 3 o'clock;
  // subtract HALF_PI to make them start at the top
    float s = -map(second()-offset, 0, 10, 0, TWO_PI) -HALF_PI; 

  
    
  // Draw the hand of the clock
  stroke(255);
  strokeWeight(5);
  line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius);

  
  // Draw the second ticks
  strokeWeight(5);
  beginShape(POINTS);
  for (int a = 0; a < 360; a+=36) {
    float angle = radians(a)+HALF_PI;
    float x = cx + cos(angle) * secondsRadius;
    float y = cy + sin(angle) * secondsRadius;
    vertex(x, y);
  }
  endShape();
}
1 Like

Set the strokeWeight(1) or pushStyle() and popStyle();

  //push();
  float l = width/255;
  strokeWeight(1);              //Default
  for(int i = 0; i<width; i++) 
    {
    stroke(252,150,120,255-i/(l));
    line(i,0,i, height);
    }
  //pop();

:slight_smile:

References:

1 Like

oh yes, it was as simple as set the strokeWeight(1), thanks @glv

1 Like

Not sure if you still need it, but you can use this to change the direction :

float dir = height/width; //to get what you want

   dir = mouseY/mouseX; //to Play around with direction

   line(i * dir, 0, 0, i * (1/dir)); //to draw it right. 

Edit: Btw, with this method you could also have the gradient rotate with the Hand of the clock :sweat_smile: looks pretty nice, tried it.

Edit: …well, doesn’t look all that good after all, though that‘s just cause it‘s pretty jumpy…

1 Like