Java Color Mix mixColors(Color c)

Here you can find the source of mixColors(Color c)

Description

<p>Returns an array of 9 colors which one could use very good together.</p> <p>The code to calculate the colors is taken from Twyst <http://www.colormixers.com/>.<br /> I've just translated it into Java.</p>

License

Apache License

Parameter

Parameter Description
c The base Color (returned as index 0)

Return

An Array of colors which are harmonic to the base color.

Declaration

public static Color[] mixColors(Color c) 

Method Source Code


//package com.java2s;
/*/*from   ww  w .ja va 2 s  . c o  m*/
 * Copyright 2005 Patrick Gotthardt
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.awt.*;

public class Main {
    /**
     * <p>Returns an array of 9 colors which one could use very good together.</p>
     * <p>The code to calculate the colors is taken from Twyst <http://www.colormixers.com/>.<br />
     * I've just translated it into Java.</p>
     *
     * @author Twyst, Patrick Gotthardt
     * @param c The base Color (returned as index 0)
     * @return An Array of colors which are harmonic to the base color.
     */
    public static Color[] mixColors(Color c) {
        Color[] result = new Color[9];

        result[0] = c;

        double[] hs = RGBtoHSV(c);
        double[] y = new double[3];
        double[] yx = new double[3];
        double[] p = new double[3];
        double[] pr = new double[3];

        // First two
        p[0] = y[0] = hs[0];
        p[1] = y[1] = hs[1];

        if (hs[2] > 70) {
            y[2] = hs[2] - 30;
            p[2] = hs[2] - 15;
        } else {
            y[2] = hs[2] + 30;
            p[2] = hs[2] + 15;
        }

        result[1] = HSVtoRGB(p);
        result[2] = HSVtoRGB(y);

        // Second three
        if (hs[0] >= 0 && hs[0] < 30) {
            pr[0] = yx[0] = y[0] = hs[0] + 20;
            pr[1] = yx[1] = y[1] = hs[1];
            y[2] = hs[2];

            if (hs[2] > 70) {
                yx[2] = hs[2] - 30;
                pr[2] = hs[2] - 15;
            } else {
                yx[2] = hs[2] + 30;
                pr[2] = hs[2] + 15;
            }
        }
        if (hs[0] >= 30 && hs[0] < 60) {
            pr[0] = yx[0] = y[0] = hs[0] + 150;
            y[1] = minMax(hs[1] - 30, 0, 100);
            y[2] = minMax(hs[2] - 20, 0, 100);

            pr[1] = yx[1] = minMax(hs[1] - 70, 0, 100);
            yx[2] = minMax(hs[2] + 20, 0, 100);
            pr[2] = hs[2];
        }
        if (hs[0] >= 60 && hs[0] < 180) {
            pr[0] = yx[0] = y[0] = hs[0] - 40;
            pr[1] = yx[1] = y[1] = hs[1];

            y[2] = hs[2];

            if (hs[2] > 70) {
                yx[2] = hs[2] - 30;
                pr[2] = hs[2] - 15;
            } else {
                yx[2] = hs[2] + 30;
                pr[2] = hs[2] + 15;
            }
        }
        if (hs[0] >= 180 && hs[0] < 220) {
            pr[0] = yx[0] = hs[0] - 170;
            y[0] = hs[0] - 160;

            pr[1] = yx[1] = y[1] = hs[1];
            y[2] = hs[2];

            if (hs[2] > 70) {
                yx[2] = hs[2] - 30;
                pr[2] = hs[2] - 15;
            } else {
                yx[2] = hs[2] + 30;
                pr[2] = hs[2] + 15;
            }
        }
        if (hs[0] >= 220 && hs[0] < 300) {
            pr[0] = yx[0] = y[0] = hs[0];
            pr[1] = yx[1] = y[1] = minMax(hs[1] - 60, 0, 100);
            y[2] = hs[2];

            if (hs[2] > 70) {
                yx[2] = hs[2] - 30;
                pr[2] = hs[2] - 15;
            } else {
                yx[2] = hs[2] + 30;
                pr[2] = hs[2] + 15;
            }
        }
        if (hs[0] >= 300) {
            if (hs[1] > 50) {
                pr[1] = yx[1] = y[1] = hs[1] - 40;
            } else {
                pr[1] = yx[1] = y[1] = hs[1] + 40;
            }

            pr[0] = yx[0] = y[0] = (hs[0] + 20) % 360;
            y[2] = hs[2];

            if (hs[2] > 70) {
                yx[2] = hs[2] - 30;
                pr[2] = hs[2] - 15;
            } else {
                yx[2] = hs[2] + 30;
                pr[2] = hs[2] + 15;
            }
        }

        result[3] = HSVtoRGB(y);
        result[4] = HSVtoRGB(pr);
        result[5] = HSVtoRGB(yx);

        // now change y again
        y[0] = y[1] = 0;
        y[2] = 100 - hs[2];
        result[6] = HSVtoRGB(y);
        y[2] = hs[2];
        result[7] = HSVtoRGB(y);

        // now change pr again
        pr[0] = pr[1] = 0;
        pr[2] = hs[2] >= 50 ? 0 : 100;
        result[8] = HSVtoRGB(pr);

        return result;
    }

    /**
     * <p>Returns the HSV representation of the RGB-Color. All values are between 0 and 255.</p>
     * <p>The code is taken from Twyst <http://www.colormixers.com/>.<br />
     * I've just translated it into Java.</p>
     *
     * @author Twyst, Patrick Gotthardt
     * @param c The color to be translated to HSV.
     * @return An double[] with three items (0=h; s=1; 2=v)
     */
    public static double[] RGBtoHSV(Color c) {
        double[] hsv = new double[3];
        int r = c.getRed(), g = c.getGreen(), b = c.getBlue();
        int min = Math.min(Math.min(r, g), b); // get the smallest of all
        int max = Math.max(Math.max(r, g), b); // get the biggest of all
        int delta = max - min;

        double h = 0, s;
        double v = 100 * max / 255;
        // Is it a gray color?
        if (delta == 0) {
            h = s = 0;
        } else {
            s = (100 * delta) / max;

            double del_r = (100 * (((max - r) / 6) + (max / 2))) / delta;
            double del_g = (100 * (((max - g) / 6) + (max / 2))) / delta;
            double del_b = (100 * (((max - b) / 6) + (max / 2))) / delta;

            if (r == max) {
                h = 60 * (g - b) / delta;
            } else if (g == max) {
                h = 120 + 60 * (b - r) / delta;
            } else if (b == max) {
                h = 240 + 60 * (r - g) / delta;
            }
            if (h < 0) {
                h = h + 360;
            }
        }
        hsv[0] = h;
        hsv[1] = s;
        hsv[2] = v;

        return hsv;
    }

    /**
     * <p>Returns the color object represented by the HSV.</p>
     * <p>The code is taken from Twyst <http://www.colormixers.com/>.<br />
     * I've just translated it into Java.</p>
     *
     * @author Twyst, Patrick Gotthardt
     * @param data An double[] with three items (0=h; s=1; 2=v)
     * @return The Color object based on the HSV values
     */
    public static Color HSVtoRGB(double[] data) {
        if (data == null || data.length != 3) {
            throw new IllegalArgumentException("data must be an array of 3 items and must not be null!");
        }
        return HSVtoRGB(data[0], data[1], data[2]);
    }

    /**
     * <p>Returns the color object represented by the HSV.</p>
     * <p>The code is taken from Twyst <http://www.colormixers.com/>.<br />
     * I've just translated it into Java.</p>
     * <p>All values must be between 0 and 255!.</p>
     *
     * @author Twyst, Patrick Gotthardt
     * @param h The "H"-value of the color.
     * @param s The "S"-value of the color.
     * @param v The "V"-value of the color.
     * @return The Color object based on the HSV values
     */
    public static Color HSVtoRGB(double h, double s, double v) {
        int r = 0, g = 0, b = 0;

        if (s == 0) {
            r = g = b = (int) Math.round(v * 2.55);
        } else {
            h = h / 60;
            s = s / 100;
            v = v / 100;

            double i = Math.floor(h);
            double f = h - i;

            int p = (int) Math.round(255 * (v * (1 - s)));
            int q = (int) Math.round(255 * (v * (1 - s * f)));
            int t = (int) Math.round(255 * (v * (1 - s * (1 - f))));
            int v2 = (int) Math.round(255 * v);

            switch ((int) i) {
            case 0:
                r = v2;
                g = t;
                b = p;
                break;
            case 1:
                r = q;
                g = v2;
                b = p;
                break;
            case 2:
                r = p;
                g = v2;
                b = t;
                break;
            case 3:
                r = p;
                g = q;
                b = v2;
                break;
            case 4:
                r = t;
                g = p;
                b = v2;
                break;
            default:
                r = v2;
                g = p;
                b = q;
                break;
            }
        }

        return new Color(r, g, b);
    }

    private static double minMax(double x, double min, double max) {
        if (x > max)
            return max;
        if (x < min)
            return min;
        return x;
    }
}

Related

  1. mix(double x, double y, double a)
  2. mix(final Color c1, final Color c2, final double factor)
  3. mix(int a, int b, int amt)
  4. mixColor(Paint p, double value)
  5. mixColors(Color a, Color b, double r)
  6. mixColors(List colors)
  7. mixColorWithAlpha(Color base, Color mix)
  8. mixedColor(Color originalColor, Color overlayColor)
  9. mixOver(Color backColor, Color frontColor)