# Gradient interpolation with 3+ points

**URL:** https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832
**Category:** Coding Questions
**Created:** [October 14, 2021, 4:42pm UTC](https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832 "2021-10-14T16:42:26Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![dirknbr](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dirknbr/32/14600_2.png) [@dirknbr](https://discourse.processing.org/u/dirknbr)
#### Post date: [October 14, 2021, 4:42pm UTC](https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832/1 "2021-10-14T16:42:26Z")

</div>

We have a n x n canvas and m (say 3) points in it. The m points/nodes all have different fixed RGB colors. The color of **each** dot in n x n is defined by the distance from any of the color nodes. So each dot is a mixture (gradient) of the m nodes, ruled by the distance from the node.

How can you do this efficiently in processing, given that n and m can be large?

---

<div class="post-metadata">

### Author: ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)
#### Post date: [October 14, 2021, 6:47pm UTC](https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832/2 "2021-10-14T18:47:25Z")

</div>

I implemented an n-point shader for OPENRNDR (a different framework). Maybe that approach is efficient enough? If you can read GLSL you might understand the code at [orx/NPointGradient.kt at master · openrndr/orx · GitHub](https://github.com/openrndr/orx/blob/master/orx-shade-styles/src/commonMain/kotlin/NPointGradient.kt) and port it to Processing.  
Basically it’s passing an array of positions and array of colors, then using them to calculate the colors of every pixel. The built in uniforms for the shader are listed [here](https://guide.openrndr.org/#/06_Advanced_drawing/C04_Shade_styles).

It is fast enough for real time animation.

 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/5/537c5758f8bb6608e55af976094670cab533ca04.png)

---

<div class="post-metadata">

### Author: ![dirknbr](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dirknbr/32/14600_2.png) [@dirknbr](https://discourse.processing.org/u/dirknbr)
#### Post date: [October 15, 2021, 9:25am UTC](https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832/3 "2021-10-15T09:25:44Z")

</div>

Ok here is my version, the rect() bit is probably not the best, also it doesn’t look at smooth as I expected.

```auto
PVector[] points = new PVector[4];
PVector[] cols = new PVector[4];

void setup() {
	size(200, 200);
	background(100);
	frameRate(1);
	noLoop();
  points[0] = new PVector(50, 50);
  points[1] = new PVector(20, 20);
  points[2] = new PVector(80, 60);
  points[3] = new PVector(120, 120);
  cols[0] = new PVector(255, 100, 100);
  cols[1] = new PVector(200, 255, 100);
  cols[2] = new PVector(0, 100, 200);								
  cols[3] = new PVector(50, 0, 200);                
}

void draw() {
	// ellipse(mouseX, mouseY, 20, 20);
	for (int x = 0; x < width; x += 1) {
		for (int y = 0; y < height; y += 1) {
			PVector rgb = new PVector(0, 0, 0);
			float d_total = 0;
			for (int i = 0; i < points.length; i++) {
				// weight by inverse distance, avoid div by 0
				float d = 100 / (dist(x, y, points[i].x, points[i].y) + random(-0.001, .001));
        PVector incr = PVector.mult(cols[i], d);
        // rgb.add(cols[i]);
				rgb.add(incr);
				d_total += d;
			}
			rgb.div(d_total);
      // rgb.div(points.length);
      noStroke();
			fill(rgb.x, rgb.y, rgb.z);
			rect(x, y, 1, 1);
		}
	}
       filter(BLUR, 5);
}

```

---

<div class="post-metadata">

### Author: ![dirknbr](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dirknbr/32/14600_2.png) [@dirknbr](https://discourse.processing.org/u/dirknbr)
#### Post date: [October 17, 2021, 8:44am UTC](https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832/4 "2021-10-17T08:44:30Z")

</div>

Correction, it should be `float d_total`

---

<div class="post-metadata">

### Author: ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)
#### Post date: [October 17, 2021, 9:11am UTC](https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832/5 "2021-10-17T09:11:24Z")

</div>

Great that you got it working! 🙂

btw. you can edit your post to make the `int` a `float` with the little pen icon.

And I would say if you use the `pixels` array it would be faster than with `rect`. [pixels[] / Reference / Processing.org](https://processing.org/reference/pixels.html)

Even faster would be to use GLSL [shaders](https://processing.org/reference/PShader.html) but that’s a whole different language and not ideal if you don’t know it already. The reason it would be faster is because it would calculate the pixel colors in parallel instead of sequentially. Also only important if you want to do it animated in real time. If the goal is to save an image it doesn’t matter that much.

Cheers!

---

<div class="post-metadata">

### Author: ![dirknbr](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/dirknbr/32/14600_2.png) [@dirknbr](https://discourse.processing.org/u/dirknbr)
#### Post date: [October 18, 2021, 8:02am UTC](https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832/6 "2021-10-18T08:02:50Z")

</div>

Thanks, I also added filter(BLUR) now.

---

<div class="post-metadata">

### Author: ![hamoid](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/hamoid/32/58_2.png) [@hamoid](https://discourse.processing.org/u/hamoid)
#### Post date: [October 18, 2021, 11:14am UTC](https://discourse.processing.org/t/gradient-interpolation-with-3-points/32832/7 "2021-10-18T11:14:09Z")

</div>

Related:

> [@HELP. How can I intersect three colors from these ellipses?](https://discourse.processing.org/t/help-how-can-i-intersect-three-colors-from-these-ellipses/22500/4):
>
> Hi @johncusack slight_smile Welcome to the forum! Anything that has to do with gradients is a great fit for shaders, unfortunately writing GLSL is not very beginner friendly. Based on [Is there a better way to draw gradient colored ellipse?](https://discourse.processing.org/t/is-there-a-better-way-to-draw-gradient-colored-ellipse/22220/4) I wrote a 3 point gradient which might look like this: PShader gradient; PShape shp; int[][] coordinate = { {0, 150}, {100, 450}, {200, 500}, {150, 750}, {400, 850}, {500, 750}, {450, 450}, {500, 100}, {175, 0} }; void setup() { size(600, 1000, P3D…
