# Linear Gradient with angle forumla

EDIT: Ok so the question here is how to you generate a linear gradient along a vector.

Here is the function i'm looking for:

function CreateGradient(x,y, x1,y1,x2,y2) {
// x and y are the point in our image we are looking to create the  color for in grayscale
// x1,y1,x2,y2 is the vector in which the linear gradient should run
// Can be in any language
}


What I have so far (that doesn't work):

var width = 2.0;
var offset = 0;

var convX = ((x / RES) * width - width/2) - offset;
var convY = ((y / RES) * width - width/2) - offset;

var angle = Math.atan(y1-y2, x1-x2);

var rx = Math.cos(angle);
var ry = Math.sin(angle);

var here = convX * rx + convY * ry;
var start = x1 * rx + y1 * ry;
var end = x2 * rx + y2 * ry;

var lerpValue = (start - here) / (start - end);

var val = lerp(0,255,clamp(lerpValue,0.0,1.0));


RES is the total resolution of the picture. val in the value (0-255) which represents the R G and B values of the pixel

Final Edit: I have it now thanks code for the future:

var x1 = 0;
var y1 = 0;
var x2 = 255;
var y2 = 255;

var dx = x2-x1;
var dy = y2-y1;

var rx = x-x1;
var ry = y-y1;

var t = ((rx*dx) +(ry*dy)) / ((dx*dx) + (dy*dy));

return lerp(0,255,t);

• Ok I'll make it easier then how to you generate a linear gradient between two points (x1,y1,x2,y2) – Dave3of5 Jul 9 '16 at 16:12
• Ok I've updated is this clearer ? – Dave3of5 Jul 9 '16 at 16:20

It looks an introduction to linear algebra is in order, or more precisely the dot product:

dot(a, b) = |a| |b| cos(Theta)


Why is it helpful? Because of its relation to the scalar/vector projection, the length of projection of vector a onto vector b is

lenPA = |a| cos(theta)


or more practically, derived from dot product definition:

lenPA = (a . b) / |b|


and when you know how far the current coordinate is projected onto the line between gradient's step1 and step2, all you have to do is to normalize it:

t = lenPA / |b|
color = lerp(color1, color2, t)


where a is relative position of fragment xy to the gradient step1 and b is non-normalized gradient (direction) going from step1 to step2.

vec2 step1 = vec2(200, 200);
vec2 step2 = vec2(400, 400);

vec4 color1 = vec4(0.0,0.5,1.0,1.0);
vec4 color2 = vec4(1.0,5.0,0.0,1.0);

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
//----constant, can pre compute------
vec2 gDrirection = step2 - step1;
float lenSq = dot(gDrirection, gDrirection);//len(gDrirection)^2
//-----------------------------------
vec2 relCoords = fragCoord - step1;
float t = dot (relCoords, gDrirection) /  lenSq;
fragColor = mix(color1, color2, t); //mix = lerp
}

• Hey thanks, I don't understand those wikipedia articles fully. But this is what I'm looking for I just needed to know how to project a point onto a 2d vector I think I can take it from here thanks. – Dave3of5 Jul 9 '16 at 18:28
• @Dave3of5 Just read the glsl code - dot the relative coordinates to first gradient point coords - step1 and the gradient direction step2 - step1 and than divide it by squared length of latter vector: float t = dot (relCoords, gDrirection) / lenSq; <- thats all relevat code. Or are you not sure how do vector operations like subtracting or dot product? Dot product is member-wise (x to x, y to y etc.) multiplication of which products you sum to single number. – wondra Jul 9 '16 at 18:41

is this what you want ?

    float endPercent = curLength / totalLength;                                                         // Calculates the percent of colour at the ending point of the line to be used in current pixel
float startPercent = 1 - (curLength / totalLength);                                                 // Calculates the percent of colour at the starting point of the line to be used in current pixel

float a = Math.abs(end.getColour().getAInInt() * endPercent + start.getColour().getAInInt() * startPercent);    //Interpolating alpha
float r = Math.abs(end.getColour().getRInInt() * endPercent + start.getColour().getRInInt() * startPercent);    //Interpolating red
float g = Math.abs(end.getColour().getGInInt() * endPercent + start.getColour().getGInInt() * startPercent);    //Interpolating green
float b = Math.abs(end.getColour().getBInInt() * endPercent + start.getColour().getBInInt() * startPercent);    //Interpolating blue

return new PixelData(a, b, g, r);                                                                   // returing the intepolated value


• hey not quite but thanks so much for responding. – Dave3of5 Jul 9 '16 at 19:50
• @Dave3of5 sorry i could not help much. :) – A---B Jul 9 '16 at 22:44