001/* 002 * Copyright (c) 2020-2021 REV Robotics 003 * 004 * Redistribution and use in source and binary forms, with or without 005 * modification, are permitted provided that the following conditions are met: 006 * 007 * 1. Redistributions of source code must retain the above copyright notice, 008 * this list of conditions and the following disclaimer. 009 * 2. Redistributions in binary form must reproduce the above copyright 010 * notice, this list of conditions and the following disclaimer in the 011 * documentation and/or other materials provided with the distribution. 012 * 3. Neither the name of REV Robotics nor the names of its 013 * contributors may be used to endorse or promote products derived from 014 * this software without specific prior written permission. 015 * 016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 017 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 018 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 019 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 020 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 021 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 022 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 023 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 024 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 025 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 026 * POSSIBILITY OF SUCH DAMAGE. 027 */ 028 029package com.revrobotics; 030 031import edu.wpi.first.wpilibj.util.Color; 032 033public class CIEColor { 034 private double X; 035 private double Y; 036 private double Z; 037 private double magnitude; 038 039 // private final double IlluminantD65[] = { 040 // 95.0489, 100.0, 108.8840 041 // }; 042 043 private final double XYZtoRGB[] = { 044 3.2404542, 045 -1.5371385, 046 -0.4985314, 047 -0.9692660, 048 1.8760108, 049 0.0415560, 050 0.0556434, 051 -0.2040259, 052 1.0572252 053 }; 054 055 private static double CIERGB_f(double val) { 056 return (val > 0.0031308) ? (1.055 * Math.pow(val, 1 / 2.4) - 0.055) : (12.92 * val); 057 } 058 059 private static double clamp(double x, double min, double max) { 060 if (x > max) return max; 061 if (x < min) return min; 062 return x; 063 } 064 065 private Color ToRGB() { 066 double _X = clamp(X / 100, 0.0, 1.0); 067 double _Y = clamp(Y / 100, 0.0, 1.0); 068 double _Z = clamp(Z / 100, 0.0, 1.0); 069 double r = _X * XYZtoRGB[0] + _Y * XYZtoRGB[1] + _Z * XYZtoRGB[2]; 070 double g = _X * XYZtoRGB[3] + _Y * XYZtoRGB[4] + _Z * XYZtoRGB[5]; 071 double b = _X * XYZtoRGB[6] + _Y * XYZtoRGB[7] + _Z * XYZtoRGB[8]; 072 073 r = CIERGB_f(r); 074 g = CIERGB_f(g); 075 b = CIERGB_f(b); 076 077 return new Color(r, g, b); 078 } 079 080 /** 081 * Get the X component of the color 082 * 083 * @return CIE X 084 */ 085 public double getX() { 086 return X; 087 } 088 089 /** 090 * Get the Y component of the color 091 * 092 * @return CIE Y 093 */ 094 public double getY() { 095 return Y; 096 } 097 098 /** 099 * Get the Z component of the color 100 * 101 * @return CIE Z 102 */ 103 public double getZ() { 104 return Z; 105 } 106 107 /** 108 * Get the x calculated coordinate of the CIE 19313 color space 109 * 110 * <p>https://en.wikipedia.org/wiki/CIE_1931_color_space 111 * 112 * @return CIE Yx 113 */ 114 public double getYx() { 115 return X / magnitude; 116 } 117 118 /** 119 * Get the y calculated coordinate of the CIE 19313 color space 120 * 121 * <p>https://en.wikipedia.org/wiki/CIE_1931_color_space 122 * 123 * @return CIE Yy 124 */ 125 public double getYy() { 126 return Y / magnitude; 127 } 128 129 public CIEColor(double x, double y, double z) { 130 this.X = x; 131 this.Y = y; 132 this.Z = z; 133 this.magnitude = x + y + z; 134 } 135}