So i answer to myself (because maybe it will help a day someone else)
My intuition saying that we should use for 2 other vertices, the color at the center of the gradient line is a false
assumption.
Or at least, it was true
only for a gradient line that fit a perfect [b]square[/b]
.
So, it’s more complicate with a quad
.
Let’s go with this example (full size of image : http://i.imgur.com/RCb1fGc.png)
Principle
It’s a linear gradient
, that mean all points on an orhogonal line
of the gradient line
has the same color
!
That mean, for computing the color for 2 others vertices, we must find the orthogonal line
of the gradient line
that pass by the vertex and check where is the intersection with the gradient line
.
After what, we can compute the distance of this intersection point and the start point (x0,y0)
.
This distance
(in a range of [0 ~ 1]
relative to the length of the gradient line) give us the interpolation factor
to apply for finding the color at this intersection point.
This color is the same for our vertex. That’s all.
We must compute theses distances
:
dU that give the factor of interpolation to apply from color A to colorB for the vertex (x0,y1)
dV that give the factor of interpolation to apply from color A to colorB for the vertex (x1,y0)
Compute the equation of our gradient line:
The slope
is the change in height divided by the change in horizontal distance : m = (y0 - y1) / (x0 - x1)
The slope-intercept
formula is y = mx + b
that give b = y - mx
float m = (y0 - y1) / (x0 - x1);
float b = y0 - (m * x0);
Compute the equation of the orthogonal line of the gradient line that pass by (x0,y1)
The slope of a line perpendicular to a line is the negative reciprocal of its slope : 1 / -m
float mo = 1f / -m;
float bo = y1 - ( m * x0 );
Compute the intersection point of the gradient line and the orthogonal line
At the intersection point, both equation lines are equals, that give y == mx + b == mox + bo
That provide theses equations for computing the intersection :
x = (bo - b) / (m - mo)
y = mx + b
float xU = (bo - b) / (m - mo);
float yU = (m * xU) + b;
Computing the distance of the point (x0,y0) to the intersection point (that provide dU)
I use the simple pythagor theorem:
float d1 = xU - x0;
float d2 = yU - y0;
dU = (float)Math.sqrt( (d1*d1) + (d2*d2) );
dU = dU / length; // Length is the distance of the gradient line from (x0,y0) to (x1,y1). That allow to convert dU in a [0 ~ 1] range.
Compute dV from dU
dV can be computed by symetric from dU.
dV = 1 - dU;
Interpolate colors at (x0,y1) and (x1,y0)
- Considering
cA[]
giving color’s component of color A at (x0,y0)
- Considering
cB[]
giving color’s component of color B at (x1,y1)
We can obtain cU[]
giving color’s component at (x0,y1)
float[] cU = new float[4];
cU[0] = ( (cB[0] - cA[0]) * dU ) + cA[0];
cU[1] = ( (cB[1] - cA[1]) * dU ) + cA[1];
cU[2] = ( (cB[2] - cA[2]) * dU ) + cA[2];
cU[3] = ( (cB[3] - cA[3]) * dU ) + cA[3];
And the same for cV[]
giving color’s component at (x1,y0)
cV = new float[4];
cV[0] = ( (cB[0] - cA[0]) * dV ) + cA[0];
cV[1] = ( (cB[1] - cA[1]) * dV ) + cA[1];
cV[2] = ( (cB[2] - cA[2]) * dV ) + cA[2];
cV[3] = ( (cB[3] - cA[3]) * dV ) + cA[3];
I tested, i obtain the same result than LinearGradientPaint
from awt/swing
Maybe it exist a simpler method but this one seems to work !