# Gradient interpolation with 3+ points

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?

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 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.

It is fast enough for real time animation.

2 Likes

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

``````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);
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);
}

``````

Correction, it should be `float d_total`

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

Even faster would be to use GLSL shaders 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!

Thanks, I also added filter(BLUR) now.

Related: