|
|
|
package com.porcupine.color;
|
|
|
|
|
|
|
|
|
|
|
|
import java.awt.Color;
|
|
|
|
|
|
|
|
import com.porcupine.math.Calc;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* RGB color
|
|
|
|
*
|
|
|
|
* @author Ondřej Hruška (MightyPork)
|
|
|
|
*/
|
|
|
|
public class RGB {
|
|
|
|
|
|
|
|
/** White */
|
|
|
|
public static final RGB WHITE = new RGB(1, 1, 1);
|
|
|
|
/** Black */
|
|
|
|
public static final RGB BLACK = new RGB(0, 0, 0);
|
|
|
|
/** Red */
|
|
|
|
public static final RGB RED = new RGB(1, 0, 0);
|
|
|
|
/** Lime green */
|
|
|
|
public static final RGB GREEN = new RGB(0, 1, 0);
|
|
|
|
/** Blue */
|
|
|
|
public static final RGB BLUE = new RGB(0, 0, 1);
|
|
|
|
/** Yellow */
|
|
|
|
public static final RGB YELLOW = new RGB(1, 1, 0);
|
|
|
|
/** Purple */
|
|
|
|
public static final RGB PURPLE = new RGB(1, 0, 1);
|
|
|
|
/** Cyan */
|
|
|
|
public static final RGB CYAN = new RGB(0, 1, 1);
|
|
|
|
/** orange */
|
|
|
|
public static final RGB ORANGE = new RGB(1, 0.6, 0);
|
|
|
|
|
|
|
|
/** R */
|
|
|
|
public double r;
|
|
|
|
/** G */
|
|
|
|
public double g;
|
|
|
|
/** B */
|
|
|
|
public double b;
|
|
|
|
/** ALPHA */
|
|
|
|
public double a = 1;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create black color 0,0,0
|
|
|
|
*/
|
|
|
|
public RGB() {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get copy with custom alpha
|
|
|
|
*
|
|
|
|
* @param alpha alpha to set
|
|
|
|
* @return copy w/ alpha
|
|
|
|
*/
|
|
|
|
public RGB setAlpha(double alpha) {
|
|
|
|
return copy().setAlpha_ip(alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set alpha IP
|
|
|
|
*
|
|
|
|
* @param alpha alpha to set
|
|
|
|
* @return this
|
|
|
|
*/
|
|
|
|
public RGB setAlpha_ip(double alpha) {
|
|
|
|
a = alpha;
|
|
|
|
norm();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get copy.
|
|
|
|
*
|
|
|
|
* @return copy
|
|
|
|
*/
|
|
|
|
public RGB copy() {
|
|
|
|
return new RGB(r, g, b, a);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get copy with alpha multiplied by custom value
|
|
|
|
*
|
|
|
|
* @param alpha alpha to set
|
|
|
|
* @return copy w/ alpha
|
|
|
|
*/
|
|
|
|
public RGB mulAlpha(double alpha) {
|
|
|
|
return copy().mulAlpha_ip(alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Multiply alpha by given number
|
|
|
|
*
|
|
|
|
* @param alpha alpha multiplier
|
|
|
|
* @return this
|
|
|
|
*/
|
|
|
|
public RGB mulAlpha_ip(double alpha) {
|
|
|
|
a *= alpha;
|
|
|
|
norm();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Color from RGB 0-1
|
|
|
|
*
|
|
|
|
* @param r red
|
|
|
|
* @param g green
|
|
|
|
* @param b blue
|
|
|
|
*/
|
|
|
|
public RGB(Number r, Number g, Number b) {
|
|
|
|
this.r = r.doubleValue();
|
|
|
|
this.g = g.doubleValue();
|
|
|
|
this.b = b.doubleValue();
|
|
|
|
norm();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Color from RGB 0-1
|
|
|
|
*
|
|
|
|
* @param r red
|
|
|
|
* @param g green
|
|
|
|
* @param b blue
|
|
|
|
* @param a alpha
|
|
|
|
*/
|
|
|
|
public RGB(Number r, Number g, Number b, Number a) {
|
|
|
|
this.r = r.doubleValue();
|
|
|
|
this.g = g.doubleValue();
|
|
|
|
this.b = b.doubleValue();
|
|
|
|
this.a = a.doubleValue();
|
|
|
|
norm();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Color from hex 0xRRGGBB
|
|
|
|
*
|
|
|
|
* @param hex hex integer
|
|
|
|
*/
|
|
|
|
public RGB(int hex) {
|
|
|
|
setTo(RGB.fromHex(hex));
|
|
|
|
norm();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Color from hex 0xRRGGBB
|
|
|
|
*
|
|
|
|
* @param hex hex integer
|
|
|
|
* @param alpha alpha color
|
|
|
|
*/
|
|
|
|
public RGB(int hex, double alpha) {
|
|
|
|
setTo(RGB.fromHex(hex));
|
|
|
|
a = alpha;
|
|
|
|
norm();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Color from other RGB and alpha channel
|
|
|
|
*
|
|
|
|
* @param color other RGB color
|
|
|
|
* @param alpha new alpha channel
|
|
|
|
*/
|
|
|
|
public RGB(RGB color, double alpha) {
|
|
|
|
setTo(color);
|
|
|
|
setAlpha_ip(alpha);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return red channel 0-1
|
|
|
|
*/
|
|
|
|
public double r() {
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return green channel 0-1
|
|
|
|
*/
|
|
|
|
public double g() {
|
|
|
|
return g;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return blue channel 0-1
|
|
|
|
*/
|
|
|
|
public double b() {
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return alpha 0-1
|
|
|
|
*/
|
|
|
|
public double a() {
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set color to other color
|
|
|
|
*
|
|
|
|
* @param copied copied color
|
|
|
|
* @return this
|
|
|
|
*/
|
|
|
|
public RGB setTo(RGB copied) {
|
|
|
|
|
|
|
|
r = copied.r;
|
|
|
|
g = copied.g;
|
|
|
|
b = copied.b;
|
|
|
|
a = copied.a;
|
|
|
|
|
|
|
|
norm();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set to represent hex color
|
|
|
|
*
|
|
|
|
* @param hex hex integer RRGGBB
|
|
|
|
* @return this
|
|
|
|
*/
|
|
|
|
public RGB setTo(int hex) {
|
|
|
|
setTo(RGB.fromHex(hex));
|
|
|
|
norm();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set to R,G,B 0-1
|
|
|
|
*
|
|
|
|
* @param r red
|
|
|
|
* @param g green
|
|
|
|
* @param b blue
|
|
|
|
* @param a alpha
|
|
|
|
* @return this
|
|
|
|
*/
|
|
|
|
public RGB setTo(Number r, Number g, Number b, Number a) {
|
|
|
|
this.r = r.doubleValue();
|
|
|
|
this.g = g.doubleValue();
|
|
|
|
this.b = b.doubleValue();
|
|
|
|
this.a = a.doubleValue();
|
|
|
|
norm();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set to R,G,B 0-1
|
|
|
|
*
|
|
|
|
* @param r red
|
|
|
|
* @param g green
|
|
|
|
* @param b blue
|
|
|
|
* @return this
|
|
|
|
*/
|
|
|
|
public RGB setTo(Number r, Number g, Number b) {
|
|
|
|
this.r = r.doubleValue();
|
|
|
|
this.g = g.doubleValue();
|
|
|
|
this.b = b.doubleValue();
|
|
|
|
this.a = 1;
|
|
|
|
norm();
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fix numbers out of range 0-1
|
|
|
|
*
|
|
|
|
* @return this
|
|
|
|
*/
|
|
|
|
public RGB norm() {
|
|
|
|
r = Calc.clampd(r, 0, 1);
|
|
|
|
g = Calc.clampd(g, 0, 1);
|
|
|
|
b = Calc.clampd(b, 0, 1);
|
|
|
|
a = Calc.clampd(a, 0, 1);
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get hex value 0xRRGGBB
|
|
|
|
*
|
|
|
|
* @return hex value RRGGBB
|
|
|
|
*/
|
|
|
|
public int getHex() {
|
|
|
|
int ri = (int) Math.round(r * 255);
|
|
|
|
int gi = (int) Math.round(g * 255);
|
|
|
|
int bi = (int) Math.round(b * 255);
|
|
|
|
return (ri << 16) | (gi << 8) | bi;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert to HSV
|
|
|
|
*
|
|
|
|
* @return HSV representation
|
|
|
|
*/
|
|
|
|
public HSV toHSV() {
|
|
|
|
float[] hsv = { 0, 0, 0 };
|
|
|
|
Color.RGBtoHSB((int) (r * 255), (int) (g * 255), (int) (b * 255), hsv);
|
|
|
|
return new HSV(hsv[0], hsv[1], hsv[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create color from hex 0xRRGGBB
|
|
|
|
*
|
|
|
|
* @param hex hex RRGGBB
|
|
|
|
* @return the new color
|
|
|
|
*/
|
|
|
|
public static RGB fromHex(int hex) {
|
|
|
|
int bi = hex & 0xff;
|
|
|
|
int gi = (hex >> 8) & 0xff;
|
|
|
|
int ri = (hex >> 16) & 0xff;
|
|
|
|
return new RGB(ri / 255D, gi / 255D, bi / 255D);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Make from HSV
|
|
|
|
*
|
|
|
|
* @param color HSV color
|
|
|
|
* @return RGB
|
|
|
|
*/
|
|
|
|
public static RGB fromHSV(HSV color) {
|
|
|
|
return color.toRGB();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "RGB[" + r + ";" + g + ";" + b + ";" + a + "]";
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
if (obj == null) return false;
|
|
|
|
if (!(obj instanceof RGB)) return false;
|
|
|
|
return ((RGB) obj).r == r && ((RGB) obj).g == g && ((RGB) obj).b == b && ((RGB) obj).a == a;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
return Double.valueOf(r).hashCode() ^ Double.valueOf(g).hashCode() ^ Double.valueOf(b).hashCode() ^ Double.valueOf(a).hashCode();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|