algorithm – Trying to port Javascript to Java may left some error

I’m porting this code to Java and after a few tests all seems ok but I need to know if I’m doing this right.

The code takes some colors and create a color ramp for maps and other stuff. You can see the original Javascript version working here.

I removed the “slider” part and fixed the amplitude to 0..100 for color ramp and 0..1 for levels.

package br.com.cmabreu.color;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

public class ColorGradientGenerator {
    private List<ColorItem> gradient;
    
    public ColorGradientGenerator() {
        this.gradient = new ArrayList<ColorItem>();
    }
    
    public void addToGradient( int index, int red, int green, int blue, int alpha ) throws Exception {
        if( index > 100 ) throw new Exception("Index must be <= 100");
        if( index < 0 )   throw new Exception("Index must be >= 0");
        Color color = new Color(red,green,blue,alpha);
        gradient.add( new ColorItem( index, color ) );
    }

    
    public void removeFromGradient( int index ) {
        gradient.remove(index);
    }
    
    private ColorItem getItemZero() throws Exception {
        for ( ColorItem colorItem : gradient  ) {
            if( colorItem.getIndex() == 0 ) return colorItem;
        }
        throw new Exception("Cannot find lower bound color");
    }
    
    
    public Color getColorAt( double value ) throws Exception {
        ColorItem firstColor = null, secondColor = null;
        double firstColorX, secondColorX;
        value = value * 100;
        int iVal = (int)value;
        
        firstColor = getItemZero();
        for ( ColorItem colorItem : gradient  ) {
            if( iVal <= colorItem.getIndex() ) {
                secondColor = colorItem;
                break;
            } else {
                firstColor = colorItem;
            }
        }
        if( secondColor == null ) throw new Exception("Cannot find upper bound color");
        
        firstColorX =  firstColor.getIndex();
        secondColorX = secondColor.getIndex() - firstColorX;
        
        double sliderX = (double)iVal - (double)firstColorX;
        
        double ratio = 0.0;
        if( secondColor.getIndex() > 0) {
            ratio = sliderX / (double)secondColorX;
        }  
        // System.out.println("Sx: " + sliderX + "   Fc: " + firstColor.getIndex() + "  Sc: " + secondColor.getIndex() + "  Ratio: " + ratio );     
        return pickHex( firstColor.getColor(), secondColor.getColor(), ratio);
    }

    
    private Color pickHex( Color firstColor, Color secondColor, double weight ) {
        double w  = weight * 2 - 1;
        double w1 = ( w / 1+1 ) / 2;
        double w2 = 1 - w1;
        
        long red   = Math.round( secondColor.getRed()   * w1 + firstColor.getRed()   * w2 );
        long green = Math.round( secondColor.getGreen() * w1 + firstColor.getGreen() * w2 );
        long blue  = Math.round( secondColor.getBlue()  * w1 + firstColor.getBlue()  * w2 );
        
        String hex = String. format("#%02X%02X%02X", red, green, blue);
        System.out.println( red + "," + green + "," + blue + " ||  " + hex );
        
        return new Color( (int)red, (int)green, (int)blue );
    }
    
    
}

You can invoke the class this way:
Prepare some colors to sample. Must have a zero index and 100 index do create a very simple gradient. By adding colors in the middle of this range you can create nice gradients.

    public static void main(String() args) {
        ColorGradientGenerator cg = new ColorGradientGenerator();
        
        try {
            cg.addToGradient(0,   128, 64, 0, 255);
            cg.addToGradient(50,  58, 168, 69, 255);
            cg.addToGradient(100, 255, 255, 255, 255);
            
            cg.getColorAt(0.0);
            cg.getColorAt(0.5);
            cg.getColorAt(0.8);
            cg.getColorAt(1.0);
            
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

What I need to know is: Am I forgot to cover something that will lead to an error? My concern is about the things I changed/removed from the original code.

Another thing: a value of 0.8 for example will not put you at 80% of the color ramp. I can’t think a global way to do this. Instead will put you at 80% of the gradient made by the color pair near (that match) 80% of the sample colors.

Lets see:

In the example I’ve created a ramp using 3 colors:

 cg.addToGradient(0,   128, 64, 0, 255);  // #804000
 cg.addToGradient(50,  58, 168, 69, 255); // #3aa845
 cg.addToGradient(100, 255, 255, 255, 255); // #FFFFFF

So, 0.8 will take the last pair because 80 is between 100 and 50 ( lower #3aa845 and upper #FFFFFF), create a gradient and give you the color at 80% of this ( #B0DCB5 ).

EDIT : This is the ColorItem class

package br.com.cmabreu.color;

import java.awt.Color;

public class ColorItem {
    private int index;
    private Color color;

    public ColorItem( int index, Color color ) {
        this.color = color;
        this.index = index;
    }
    
    public Color getColor() {
        return color;
    }
    
    public int getIndex() {
        return index;
    }
    
}