using System; namespace Psychlops { namespace ColorSpaces { public struct HSV { public double H, S, V, A; public Color toRGB() { if (S == 0.0) return new Color(V, V, V, A); int hi = (int)Math.floor(H/60.0); double f = (H / 60.0) - (double)hi, p = V*(1.0-S), q = V*(1.0-f*S), t = V*(1.0-(1.0-f)*S); if (hi == 0) { return new Color(V, t, p, A); } else if (hi == 1) { return new Color(q, V, p, A); } else if (hi == 2) { return new Color(p, V, t, A); } else if (hi == 3) { return new Color(p, q, V, A); } else if (hi == 4) { return new Color(t, p, V, A); } else if (hi == 5) { return new Color(V, p, q, A); } else return Color.transparent; } public void fromRGB(Color o) { double MAX = Math.max(Math.max(o.r, o.g), o.b); double MIN = Math.min(Math.min(o.r, o.g), o.b); double h; if(MAX==MIN) { h=0.0; } else if(o.r>o.g && o.r>o.b) { h=60.0*(o.g-o.b)/(MAX-MIN)+360.0; } else if(o.g>o.b) { h=60.0*(o.b-o.r)/(MAX-MIN)+120.0; } else { h=60.0*(o.r-o.g)/(MAX-MIN)+240.0; } h = Math.mod(h, 360.0); double v = MAX, s; if(MAX==MIN) { s=0.0; } else { s=(MAX-MIN)/MAX; } H = h; S = s; V = v; A = o.a; } } /* * CIE 1931 * R: 700 nm * G: 546.1 nm * B: 435.8 nm * White Point: Illuminant E */ public struct CIERGB { public double R, G, B; public CIEXYZ convertToCIEXYZ() { double[,] b = { { 0.49, 0.31, 0.20 }, { 0.17697, 0.81240, 0.01063 }, { 0.00, 0.01, 0.99 } }; CIEXYZ v; v.X = b[0, 0] * R + b[0, 1] * G + b[0, 2] * B; v.Y = b[1, 0] * R + b[1, 1] * G + b[1, 2] * B; v.Z = b[2, 0] * R + b[2, 1] * G + b[2, 2] * B; return v; } } /* * CIE 1931 */ public struct CIEXYZ { public double X, Y, Z; public CIExyY convertToCIExyY() { CIExyY v; double denominator = X + Y + Z; v.x = X / denominator; v.y = Y / denominator; v.Y = Y; return v; } } public struct CIExyY { public double x, y, Y; public CIEXYZ convertToCIEXYZ() { CIEXYZ v; v.X = Y / y * x; v.Y = Y; v.Z = Y / y * (1 - x - y); return v; } // Yn = 1.0 when RGB of white point is { 1, 1, 1 } public CIELuv convertToCIELuv(double Yn = 1.0) { CIELuv v; double denominator = (-2 * x + 12 * y + 3); double up = 4 * x / denominator; double vp = 9 * y / denominator; double Yd = Y / Yn; v.L = Yd > System.Math.Pow(6 / 29, 3) ? 116 * System.Math.Pow(Yd, 3) : System.Math.Pow(29 / 3, 3) * Yd; v.u = 13 * v.L * (up - 0.2009); v.v = 13 * v.L * (vp - 0.4610); return v; } } /* L*u*v* * CIE 1976 * standard illuminant C */ public struct CIELuv { public double L, u, v; } public struct CIELab { public double L, a, b; } } }