diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java index eb90536f43..e743495eed 100644 --- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java +++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java @@ -18,6 +18,61 @@ import edu.wpi.first.wpiutil.math.MathUtil; */ @SuppressWarnings("MemberName") public class Color { + private static final double kPrecision = Math.pow(2, -12); + + public final double red; + public final double green; + public final double blue; + + /** + * Constructs a Color. + * + * @param red Red value (0-1) + * @param green Green value (0-1) + * @param blue Blue value (0-1) + */ + public Color(double red, double green, double blue) { + this.red = roundAndClamp(red); + this.green = roundAndClamp(green); + this.blue = roundAndClamp(blue); + } + + /** + * Constructs a Color from a Color8Bit. + * + * @param color The color + */ + public Color(Color8Bit color) { + this(color.red / 255.0, + color.green / 255.0, + color.blue / 255.0); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null || getClass() != other.getClass()) { + return false; + } + + Color color = (Color) other; + return Double.compare(color.red, red) == 0 + && Double.compare(color.green, green) == 0 + && Double.compare(color.blue, blue) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(red, green, blue); + } + + private static double roundAndClamp(double value) { + final var rounded = Math.round(value / kPrecision) * kPrecision; + return MathUtil.clamp(rounded, 0.0, 1.0); + } + /* * FIRST Colors */ @@ -740,59 +795,4 @@ public class Color { * #9ACD32. */ public static final Color kYellowGreen = new Color(0.6039216f, 0.8039216f, 0.19607843f); - - public final double red; - public final double green; - public final double blue; - - private static final double kPrecision = Math.pow(2, -12); - - /** - * Constructs a Color. - * - * @param red Red value (0-1) - * @param green Green value (0-1) - * @param blue Blue value (0-1) - */ - public Color(double red, double green, double blue) { - this.red = roundAndClamp(red); - this.green = roundAndClamp(green); - this.blue = roundAndClamp(blue); - } - - /** - * Constructs a Color from a Color8Bit. - * - * @param color The color - */ - public Color(Color8Bit color) { - this(color.red / 255.0, - color.green / 255.0, - color.blue / 255.0); - } - - @Override - public boolean equals(Object other) { - if (this == other) { - return true; - } - if (other == null || getClass() != other.getClass()) { - return false; - } - - Color color = (Color) other; - return Double.compare(color.red, red) == 0 - && Double.compare(color.green, green) == 0 - && Double.compare(color.blue, blue) == 0; - } - - @Override - public int hashCode() { - return Objects.hash(red, green, blue); - } - - private static double roundAndClamp(double value) { - final var rounded = Math.round(value / kPrecision) * kPrecision; - return MathUtil.clamp(rounded, 0.0, 1.0); - } } diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/ColorTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/ColorTest.java new file mode 100644 index 0000000000..231eab6abf --- /dev/null +++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/ColorTest.java @@ -0,0 +1,50 @@ +/*----------------------------------------------------------------------------*/ +/* Copyright (c) 2020 FIRST. All Rights Reserved. */ +/* Open Source Software - may be modified and shared by FRC teams. The code */ +/* must be accompanied by the FIRST BSD license file in the root directory of */ +/* the project. */ +/*----------------------------------------------------------------------------*/ + +package edu.wpi.first.wpilibj.util; + +import java.util.stream.Stream; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.params.provider.Arguments.arguments; + +class ColorTest { + private static final double kEpsilon = 1e-3; + + void assertColorMatches(double red, double green, double blue, Color color) { + assertAll( + () -> assertEquals(red, color.red, kEpsilon), + () -> assertEquals(green, color.green, kEpsilon), + () -> assertEquals(blue, color.blue, kEpsilon) + ); + } + + @ParameterizedTest + @MethodSource("staticColorProvider") + void staticColorTest(double red, double green, double blue, Color color) { + assertColorMatches(red, green, blue, color); + } + + @ParameterizedTest + @MethodSource("staticColorProvider") + void colorEqualsTest(double red, double green, double blue, Color color) { + assertEquals(color, new Color(red, green, blue)); + } + + static Stream staticColorProvider() { + return Stream.of( + arguments(0.0823529412, 0.376470589, 0.7411764706, Color.kDenim), + arguments(0.0, 0.4, 0.7019607844, Color.kFirstBlue), + arguments(0.9294117648, 0.1098039216, 0.1411764706, Color.kFirstRed) + ); + } +}