ritwik sinha - 6 months ago 18
Java Question

# Weird interpolation between colors in hsv?

I want to achieve interpolation between red and blue. something like this

but in a single line.

My java code:

``````private PixelData InterpolateColour(float totalLength, float curLength){
float startColourV[] = new float[3];
Color.RGBtoHSB(m_start.getColour().getR() & 0xFF, m_start.getColour().getG()  & 0xFF, m_start.getColour().getB()  & 0xFF, startColourV);

float endColourV[] = new float[3];
Color.RGBtoHSB(m_end.getColour().getR()  & 0xFF, m_end.getColour().getG()  & 0xFF, m_end.getColour().getB()  & 0xFF, endColourV);

float endPercent = curLength / totalLength;
float startPercent = 1 - curLength / totalLength;

float h = endColourV[0] * endPercent + startColourV[0] * startPercent;
float s = endColourV[1] * endPercent + startColourV[1] * startPercent;
float b = endColourV[2] * endPercent + startColourV[2] * startPercent;

int colourRGB = Color.HSBtoRGB(h, s, b);

byte[] ByteArray = ByteBuffer.allocate(4).putInt(colourRGB).array();

return new PixelData(ByteArray[0], ByteArray[3], ByteArray[2], ByteArray[1]);
}
``````

and the result i am getting is this

.

I don't understand, from where all that green is coming from. Can somebody please help me ?

why not use just RGB with simple linear interpolation for this:

``````color(t)=(color0*t)+(color1*(1.0-t))
``````

where `t=<0.0,1.0>` is the parameter. So just loop it in the full range with as many steps as you need.

Integer C++/VCL example (sorry not a JAVA coder):

``````// borland GDI clear screen
Canvas->Brush->Color=clBlack;
Canvas->FillRect(ClientRect);
union _color
{
DWORD dd;
BYTE db[4];
} c0,c1,c;
//    0x00BBGGRR
c0.dd=0x000000FF; // Red
c1.dd=0x00FF0000; // Blue
int x,y,t0,t1;
for (x=0,y=ClientHeight/2;x<ClientWidth;x++)
{
t0=x;
t1=ClientWidth-1-x;
c.db[0]=((DWORD(c0.db[0])*t0)+(DWORD(c1.db[0])*t1))/(ClientWidth-1);
c.db[1]=((DWORD(c0.db[1])*t0)+(DWORD(c1.db[1])*t1))/(ClientWidth-1);
c.db[2]=((DWORD(c0.db[2])*t0)+(DWORD(c1.db[2])*t1))/(ClientWidth-1);
c.db[3]=((DWORD(c0.db[3])*t0)+(DWORD(c1.db[3])*t1))/(ClientWidth-1);
Canvas->Pixels[x][y]=c.dd;
}
``````

where `ClientWidth,ClientHeight` is my app form resolution, `Canvas` is access to the GDI interface of the form and `Canvas->Pixels[x][y]` is single pixel access (slow but for this example it is enough). The only important stuff is the for loop. Here resulting image:

Source (Stackoverflow)