All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nl.cloudfarming.client.util.Gradient Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2008-2012 AgroSense Foundation.
 *
 * AgroSense is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * There are special exceptions to the terms and conditions of the GPLv3 as it is applied to
 * this software, see the FLOSS License Exception
 * .
 *
 * AgroSense is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with AgroSense.  If not, see .
 */
package nl.cloudfarming.client.util;

import java.awt.Color;
import java.util.HashMap;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Objects;
import java.util.TreeMap;

/**
 *
 * @author johan
 */
public class Gradient {
    private final NavigableMap stops;

    public Gradient(Map stops) {
        this.stops = new TreeMap<>(stops);
    }

    public Color getColor(double position) {
        final double first = stops.firstKey(), last = stops.lastKey();
        if (position <= first) { return stops.get(first); }
        if (position >= last) { return stops.get(last); }
        final Map.Entry  lo = stops.lowerEntry(position), hi = stops.ceilingEntry(position); // ceil: higher or equal
        final double fraction = (position - lo.getKey()) / (hi.getKey() - lo.getKey());
        return ColorUtil.interpolateRGBA(lo.getValue(), hi.getValue(), fraction);
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 59 * hash + Objects.hashCode(this.stops);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Gradient other = (Gradient) obj;
        if (!Objects.equals(this.stops, other.stops)) {
            return false;
        }
        return true;
    }

    public static class Builder {
        private final Map stops = new HashMap<>();

        public Builder stop(double  position, Color color) {
            assert position >= 0.0 && position <= 1.0 : "Position must be between 0.0 and 1.0 passed value " + position;
            assert color != null;
            stops.put(position, color);
            return this;
        }

        public Gradient build() {
            assert stops.size() > 0;
            return new Gradient(stops);
        }
    }
    
    /**
     * Create a gradient using evenly spaced color stops.
     * 
     * @param colors
     * @return 
     */
    public static Gradient create(Color... colors) {
        if (colors == null || colors.length == 0) {
            throw new IllegalArgumentException();
        }
        if (colors.length == 1) {
            return new Builder().stop(0.0, colors[0]).stop(1.0, colors[0]).build();
        }
        
        double step = 1.0 / (colors.length - 1), offset = 0.0;
        final Builder builder = new Builder();

        for (Color color : colors) {
            // min: fix for rounding errors on last stop offset
            builder.stop(Math.min(offset, 1.0), color);
            offset += step;
        }
        return builder.build();
    }

    public static void main(String[] args) {

        final Gradient g = new Builder()
                .stop(0.4, Color.red)
                .stop(0.75, Color.black)
                .stop(1.0, Color.yellow)
                .build();

        for (double d = 0.0; d <= 1.0; d += 1.0/8.0) {
            System.out.println(d + "\t" + g.getColor(d));
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy