Skip to content
Snippets Groups Projects
Histogram.java 1.98 KiB
Newer Older
  • Learn to ignore specific revisions
  • package viewer;
    
    import javafx.scene.paint.Color;
    
    /**
     * Histogram of colors, used to generate a list of colors made
    
     * from several gradients combined, so that the list looks smooth.
    
    record Histogram(double[] breakpoints, Color[] colors) {
    
    
        /**
         * Creates a schema of colors.
         * <code>breakpoints</code> and <code>colors</code> must have the same length.
         * Two consecutive indices of <code>colors</code> define a gradient of colors.
         * Those colors will be linearly mapped to the interval defined by the same
         * indices taken in <code>breakpoints</code>
         * For instance, { 0, 0.4, 1.} with { BLACK, RED, WHITE} represents a black
         * to red to white spectrum, where 40% of the point are the black to red
         * gradient, 60% are the red to white gradient.
         *
         * @param breakpoints values from 0 to 1, in increasing order, the first value must be 0 and the last one.
         * @param colors      colors assigned to each breakpoint.
         */
    
        Histogram {
    
            assert (breakpoints[0] == 0);
            assert (breakpoints[breakpoints.length - 1] == 1);
            assert (colors.length == breakpoints.length);
        }
    
    
        /**
         * Generates a list of colors of given length representing this spectrum.
         *
         * @param howManyPoints the number of colors returned
         * @return a list of colors following the schema defined in the constructor
         */
        Color[] generate(int howManyPoints) {
            Color[] result = new Color[howManyPoints];
            int bpIndex = 0;
            for (int ptIndex = 0; ptIndex < howManyPoints; ptIndex++) {
    
                double absolute = (double) ptIndex / (double) howManyPoints;
    
                while (absolute > breakpoints[bpIndex + 1] && bpIndex < breakpoints.length - 1)
                    bpIndex++;
                double relative = (absolute - breakpoints[bpIndex]) / (breakpoints[bpIndex + 1] - breakpoints[bpIndex]);
                result[ptIndex] = colors[bpIndex].interpolate(colors[bpIndex + 1], relative);
            }
            return result;
        }
    
    }