Class ColorTools

java.lang.Object
com.github.tommyettinger.colorful.pure.ipt.ColorTools

public class ColorTools extends Object
Contains code for manipulating colors as int and packed float values in the IPT color space. IPT has more perceptually-uniform handling of hue than some other color spaces, like YCwCm, and even though the version here gives up the complex exponential adjustments to various components that the original IPT paper used, it still is pretty good at preserving perceptual lightness. In most regards, this is a more thoroughly-constructed color space than YCwCm, but YCwCm may still be useful because of how it maps to aesthetic components of color. See ipt(float, float, float, float) for docs on the I, P, and T channels.
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    static float
    alpha(float encoded)
    Gets the alpha channel value of the given encoded color, as a float from 0.0f to 1.0f, inclusive.
    static int
    alphaInt(float encoded)
    Gets the alpha channel value of the given encoded color, as an even int ranging from 0 to 254, inclusive.
    static float
    blot(float start, float change)
    Interpolates from the packed float color start towards that color made opaque by change.
    static float
    blue(float encoded)
    Gets the blue channel value of the given encoded color, as a float from 0.0f to 1.0f, inclusive.
    static int
    blueInt(float encoded)
    Gets the blue channel value of the given encoded color, as an int ranging from 0 to 255, inclusive.
    static float
    darken(float start, float change)
    Interpolates from the packed float color start towards black by change.
    static float
    differentiateLightness(float mainColor, float contrastingColor)
    Given a packed float IPT color mainColor and another IPT color that it should be made to contrast with, gets a packed float IPT color with I that should be quite different from contrastingColor's I, but the same chromatic channels and opacity (A and B are likely to be clamped if the result gets close to white or black).
    static float
    dullen(float start, float change)
    Brings the chromatic components of start closer to grayscale by change (desaturating them).
    static float
    editIPT(float encoded, float addI, float addP, float addT, float addAlpha)
    Given a packed float IPT color, this edits its intensity, protan, tritan, and alpha channels by adding the corresponding "add" parameter and then clamping.
    static float
    editIPT(float encoded, float addI, float addP, float addT, float addAlpha, float mulI, float mulP, float mulT, float mulAlpha)
    Given a packed float IPT color, this edits its intensity, protan, tritan, and alpha channels by first multiplying each channel by the corresponding "mul" parameter and then adding the corresponding "add" parameter, before clamping.
    static float
    enrich(float start, float change)
    Pushes the chromatic components of start away from grayscale by change (saturating them).
    static float
    fade(float start, float change)
    Interpolates from the packed float color start towards transparent by change.
    static float
    floatGetHSL(float hue, float saturation, float lightness, float opacity)
    Gets a color as an IPT packed float given floats representing hue, saturation, lightness, and opacity.
    static float
    fromHSI(float packed)
    Converts from a packed float in HSI format to a packed float in IPT format.
    static float
    fromHSI(float hue, float saturation, float intensity, float alpha)
    Converts from hue, saturation, intensity, and alpha components (each ranging from 0 to 1 inclusive) to a packed float color in IPT format.
    static float
    fromRGBA(float packed)
    Takes a color encoded as an RGBA8888 packed float and converts to a packed float in the IPT format this uses.
    static float
    fromRGBA(float r, float g, float b, float a)
    Takes RGBA components from 0.0 to 1.0 each and converts to a packed float in the IPT format this uses.
    static float
    fromRGBA8888(int rgba)
    Takes a color encoded as an RGBA8888 int and converts to a packed float in the IPT format this uses.
    static float
    green(float encoded)
    Gets the green channel value of the given encoded color, as a float from 0.0f to 1.0f, inclusive.
    static int
    greenInt(float encoded)
    Gets the green channel value of the given encoded color, as an int ranging from 0 to 255, inclusive.
    static float
    hue(float encoded)
    Gets the hue of the given encoded color, as a float from 0f (inclusive, red and approaching orange if increased) to 1f (exclusive, red and approaching purple if decreased).
    static boolean
    inGamut(float packed)
    Returns true if the given packed float color, as IPT, is valid to convert losslessly back to RGBA.
    static boolean
    inGamut(float i, float p, float t)
    Returns true if the given IPT values are valid to convert losslessly back to RGBA.
    static float
    intensity(float encoded)
    The "intensity" of the given packed float in IPT format, which is like its lightness; ranges from 0.0f to 1.0f .
    static float
    inverseLightness(float mainColor, float contrastingColor)
    Given a packed float IPT color mainColor and another IPT color that it should be made to contrast with, gets a packed float IPT color with roughly inverted intnsity but the same chromatic channels and opacity (P and T are likely to be clamped if the result gets close to white or black).
    static float
    ipt(float intens, float protan, float tritan, float alpha)
    Gets a packed float representation of a color given as 4 float components, here, I (intensity or lightness), P (protan, a chromatic component ranging from greenish to reddish), T (tritan, a chromatic component ranging from bluish to yellowish), and A (alpha or opacity).
    static float
    lessenChange(float color, float fraction)
    Makes the additive IPT color stored in color cause less of a change when used as a tint, as if it were mixed with neutral gray.
    static float
    lighten(float start, float change)
    Interpolates from the packed float color start towards white by change.
    static float
    lightness(float encoded)
     
    static float
    limitToGamut(float packed)
    Iteratively checks whether the given IPT color is in-gamut, and either brings the color closer to 50% gray if it isn't in-gamut, or returns it as soon as it is in-gamut.
    static float
    limitToGamut(float i, float p, float t)
    Iteratively checks whether the given IPT color is in-gamut, and either brings the color closer to 50% gray if it isn't in-gamut, or returns it as soon as it is in-gamut.
    static float
    limitToGamut(float i, float p, float t, float a)
    Iteratively checks whether the given IPT color is in-gamut, and either brings the color closer to 50% gray if it isn't in-gamut, or returns it as soon as it is in-gamut.
    static float
    offsetLightness(float mainColor)
    Pretty simple; adds 0.5 to the given color's I and wraps it around if it would go above 1.0, then averages that with the original I.
    static float
    protan(float encoded)
    The "protan" of the given packed float in IPT format, which when combined with tritan describes the hue and saturation of a color; ranges from 0f to 1f .
    static float
    protanDown(float start, float change)
    Interpolates from the packed float color start towards a cooler color (green to blue) by change.
    static float
    protanUp(float start, float change)
    Interpolates from the packed float color start towards a warmer color (orange to magenta) by change.
    static float
    Produces a random packed float color that is always in-gamut (and opaque) and should be uniformly distributed.
    static float
    randomEdit(float color, long seed, float variance)
    Makes a quasi-randomly-edited variant on the given color, allowing typically a small amount of variance (such as 0.05 to 0.25) between the given color and what this can return.
    static float
    randomizedColor(com.github.tommyettinger.random.EnhancedRandom random)
    Produces a random packed float color that is always opaque and should be uniformly distributed.
    static float
    red(float encoded)
    Gets the red channel value of the given encoded color, as a float from 0.0f to 1.0f, inclusive.
    static int
    redInt(float encoded)
    Gets the red channel value of the given encoded color, as an int ranging from 0 to 255, inclusive.
    static float
    saturation(float encoded)
    Gets the saturation of the given encoded color, as a float ranging from 0.0f to 1.0f, inclusive.
    static float
    subrandomColor(float r, float g, float b)
    Limited-use; like randomColor(Random) but for cases where you already have three floats (r, g, and b) distributed how you want.
    static float
    toEditedFloat(float basis, float hue, float saturation, float light, float opacity)
    Gets a variation on the packed float color basis as another packed float that has its hue, saturation, lightness, and opacity adjusted by the specified amounts.
    static float
    toRGBA(float packed)
    Converts a packed float color in the format produced by ipt(float, float, float, float) to a packed float in RGBA format.
    static int
    toRGBA8888(float packed)
    Converts a packed float color in the format produced by ipt(float, float, float, float) to an RGBA8888 int.
    static float
    tritan(float encoded)
    The "tritan" of the given packed float in IPT format, which when combined with protan describes the hue and saturation of a color; ranges from 0f to 1f .
    static float
    tritanDown(float start, float change)
    Interpolates from the packed float color start towards an "artificial" color (between blue and purple) by change.
    static float
    tritanUp(float start, float change)
    Interpolates from the packed float color start towards a "natural" color (between green and orange) by change.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

  • Method Details

    • ipt

      public static float ipt(float intens, float protan, float tritan, float alpha)
      Gets a packed float representation of a color given as 4 float components, here, I (intensity or lightness), P (protan, a chromatic component ranging from greenish to reddish), T (tritan, a chromatic component ranging from bluish to yellowish), and A (alpha or opacity). Intensity should be between 0 and 1, inclusive, with 0 used for very dark colors (almost only black), and 1 used for very light colors (almost only white). Protan and tritan range from 0.0 to 1.0, with grayscale results when both are about 0.5. There's some aesthetic value in changing just one chroma value. When protan is high and tritan is low, the color is more purple/magenta, when both are low it is more bluish, when tritan is high and protan is low, the color tends to be greenish, and when both are high it tends to be orange. When protan and tritan are both near 0.5f, the color is closer to gray. Alpha is the multiplicative opacity of the color, and acts like RGBA's alpha.
      This method bit-masks the resulting color's byte values, so any values can technically be given to this as intensity, protan, and tritan, but they will only be reversible from the returned float color to the original I, P, and T values if the original values were in the range that intensity(float), protan(float), and tritan(float) return.
      Parameters:
      intens - 0f to 1f, intensity or I component of IPT, with 0.5f meaning "no change" and 1f brightening
      protan - 0f to 1f, protan or P component of IPT, with 1f more orange, red, or magenta
      tritan - 0f to 1f, tritan or T component of IPT, with 1f more green, yellow, or red
      alpha - 0f to 1f, 0f makes the color transparent and 1f makes it opaque
      Returns:
      a float encoding a color with the given properties
    • toRGBA8888

      public static int toRGBA8888(float packed)
      Converts a packed float color in the format produced by ipt(float, float, float, float) to an RGBA8888 int. This format of int can be used with Pixmap and in some other places in libGDX.
      Parameters:
      packed - a packed float color, as produced by ipt(float, float, float, float)
      Returns:
      an RGBA8888 int color
    • toRGBA

      public static float toRGBA(float packed)
      Converts a packed float color in the format produced by ipt(float, float, float, float) to a packed float in RGBA format. This format of float can be used with the standard SpriteBatch and in some other places in libGDX.
      Parameters:
      packed - a packed float color, as produced by ipt(float, float, float, float)
      Returns:
      a packed float color as RGBA
    • fromRGBA8888

      public static float fromRGBA8888(int rgba)
      Takes a color encoded as an RGBA8888 int and converts to a packed float in the IPT format this uses.
      Parameters:
      rgba - an int with the channels (in order) red, green, blue, alpha; should have 8 bits per channel
      Returns:
      a packed float as IPT, which this class can use
    • fromRGBA

      public static float fromRGBA(float packed)
      Takes a color encoded as an RGBA8888 packed float and converts to a packed float in the IPT format this uses.
      Parameters:
      packed - a packed float in RGBA8888 format, with A in the MSB and R in the LSB
      Returns:
      a packed float as IPT, which this class can use
    • fromRGBA

      public static float fromRGBA(float r, float g, float b, float a)
      Takes RGBA components from 0.0 to 1.0 each and converts to a packed float in the IPT format this uses.
      Parameters:
      r - red, from 0.0 to 1.0 (both inclusive)
      g - green, from 0.0 to 1.0 (both inclusive)
      b - blue, from 0.0 to 1.0 (both inclusive)
      a - alpha, from 0.0 to 1.0 (both inclusive)
      Returns:
      a packed float as IPT, which this class can use
    • redInt

      public static int redInt(float encoded)
      Gets the red channel value of the given encoded color, as an int ranging from 0 to 255, inclusive.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      an int from 0 to 255, inclusive, representing the red channel value of the given encoded color
    • greenInt

      public static int greenInt(float encoded)
      Gets the green channel value of the given encoded color, as an int ranging from 0 to 255, inclusive.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      an int from 0 to 255, inclusive, representing the green channel value of the given encoded color
    • blueInt

      public static int blueInt(float encoded)
      Gets the blue channel value of the given encoded color, as an int ranging from 0 to 255, inclusive.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      an int from 0 to 255, inclusive, representing the blue channel value of the given encoded color
    • alphaInt

      public static int alphaInt(float encoded)
      Gets the alpha channel value of the given encoded color, as an even int ranging from 0 to 254, inclusive. Because of how alpha is stored in libGDX, no odd-number values are possible for alpha.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      an even int from 0 to 254, inclusive, representing the alpha channel value of the given encoded color
    • red

      public static float red(float encoded)
      Gets the red channel value of the given encoded color, as a float from 0.0f to 1.0f, inclusive.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      a float from 0.0f to 1.0f, inclusive, representing the red channel value of the given encoded color
    • green

      public static float green(float encoded)
      Gets the green channel value of the given encoded color, as a float from 0.0f to 1.0f, inclusive.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      a float from 0.0f to 1.0f, inclusive, representing the green channel value of the given encoded color
    • blue

      public static float blue(float encoded)
      Gets the blue channel value of the given encoded color, as a float from 0.0f to 1.0f, inclusive.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      a float from 0.0f to 1.0f, inclusive, representing the blue channel value of the given encoded color
    • alpha

      public static float alpha(float encoded)
      Gets the alpha channel value of the given encoded color, as a float from 0.0f to 1.0f, inclusive.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      a float from 0.0f to 1.0f, inclusive, representing the alpha channel value of the given encoded color
    • floatGetHSL

      public static float floatGetHSL(float hue, float saturation, float lightness, float opacity)
      Gets a color as an IPT packed float given floats representing hue, saturation, lightness, and opacity. All parameters should normally be between 0 and 1 inclusive, though any hue is tolerated (precision loss may affect the color if the hue is too large). A hue of 0 is red, progressively higher hue values go to orange, yellow, green, blue, and purple before wrapping around to red as it approaches 1. A saturation of 0 is grayscale, a saturation of 1 is brightly colored, and values close to 1 will usually appear more distinct than values close to 0, especially if the hue is different. A lightness of 0.001f or less is always black (also using a shortcut if this is the case, respecting opacity), while a lightness of 1f is white. Very bright colors are mostly in a band of high-saturation where lightness is 0.5f.
      Parameters:
      hue - 0f to 1f, color wheel position
      saturation - 0f to 1f, 0f is grayscale and 1f is brightly colored
      lightness - 0f to 1f, 0f is black and 1f is white
      opacity - 0f to 1f, 0f is fully transparent and 1f is opaque
      Returns:
      a float encoding a color with the given properties
    • saturation

      public static float saturation(float encoded)
      Gets the saturation of the given encoded color, as a float ranging from 0.0f to 1.0f, inclusive.
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      the saturation of the color from 0.0 (a grayscale color; inclusive) to 1.0 (a bright color, inclusive)
    • lightness

      public static float lightness(float encoded)
    • hue

      public static float hue(float encoded)
      Gets the hue of the given encoded color, as a float from 0f (inclusive, red and approaching orange if increased) to 1f (exclusive, red and approaching purple if decreased).
      Parameters:
      encoded - a color as a packed float that can be obtained by ipt(float, float, float, float)
      Returns:
      The hue of the color from 0.0 (red, inclusive) towards orange, then yellow, and eventually to purple before looping back to almost the same red (1.0, exclusive)
    • intensity

      public static float intensity(float encoded)
      The "intensity" of the given packed float in IPT format, which is like its lightness; ranges from 0.0f to 1.0f . You can edit the intensity of a color with lighten(float, float) and darken(float, float).
      Parameters:
      encoded - a color encoded as a packed float, as by ipt(float, float, float, float)
      Returns:
      the intensity value as a float from 0.0f to 1.0f
    • protan

      public static float protan(float encoded)
      The "protan" of the given packed float in IPT format, which when combined with tritan describes the hue and saturation of a color; ranges from 0f to 1f . If protan is 0f, the color will be cooler, more green or blue; if protan is 1f, the color will be warmer, from magenta to orange. You can edit the protan of a color with protanUp(float, float) and protanDown(float, float).
      Parameters:
      encoded - a color encoded as a packed float, as by ipt(float, float, float, float)
      Returns:
      the protan value as a float from 0.0f to 1.0f
    • tritan

      public static float tritan(float encoded)
      The "tritan" of the given packed float in IPT format, which when combined with protan describes the hue and saturation of a color; ranges from 0f to 1f . If tritan is 0f, the color will be more "artificial", more blue or purple; if tritan is 1f, the color will be more "natural", from green to yellow to orange. You can edit the tritan of a color with tritanUp(float, float) and tritanDown(float, float).
      Parameters:
      encoded - a color encoded as a packed float, as by ipt(float, float, float, float)
      Returns:
      the tritan value as a float from 0.0f to 1.0f
    • toEditedFloat

      public static float toEditedFloat(float basis, float hue, float saturation, float light, float opacity)
      Gets a variation on the packed float color basis as another packed float that has its hue, saturation, lightness, and opacity adjusted by the specified amounts. Note that this edits the color in HSL space, not IPT! Takes floats representing the amounts of change to apply to hue, saturation, lightness, and opacity; these can be between -1f and 1f. Returns a float that can be used as a packed or encoded color. The float is likely to be different than the result of ipt(float, float, float, float) unless hue, saturation, lightness, and opacity are all 0. This won't allocate any objects.
      The parameters this takes all specify additive changes for a color component, clamping the final values so they can't go above 1 or below 0, with an exception for hue, which can rotate around if lower or higher hues would be used. As an example, if you give this 0.4f for saturation, and the current color has saturation 0.7f, then the resulting color will have 1f for saturation. If you gave this -0.1f for saturation and the current color again has saturation 0.7f, then resulting color will have 0.6f for saturation.
      Parameters:
      basis - a packed float color that will be used as the starting point to make the next color
      hue - -1f to 1f, the hue change that can be applied to the new float color (not clamped, wraps)
      saturation - -1f to 1f, the saturation change that can be applied to the new float color
      light - -1f to 1f, the light/brightness change that can be applied to the new float color
      opacity - -1f to 1f, the opacity/alpha change that can be applied to the new float color
      Returns:
      a float encoding a variation of basis with the given changes
    • lighten

      public static float lighten(float start, float change)
      Interpolates from the packed float color start towards white by change. While change should be between 0f (return start as-is) and 1f (return white), start should be a packed color, as from ipt(float, float, float, float). This is a good way to reduce allocations of temporary Colors, and is a little more efficient and clear than using FloatColors.lerpFloatColors(float, float, float) to lerp towards white. Unlike FloatColors.lerpFloatColors(float, float, float), this keeps the alpha and both chroma of start as-is.
      Parameters:
      start - the starting color as a packed float
      change - how much to go from start toward white, as a float between 0 and 1; higher means closer to white
      Returns:
      a packed float that represents a color between start and white
      See Also:
    • darken

      public static float darken(float start, float change)
      Interpolates from the packed float color start towards black by change. While change should be between 0f (return start as-is) and 1f (return black), start should be a packed color, as from ipt(float, float, float, float). This is a good way to reduce allocations of temporary Colors, and is a little more efficient and clear than using FloatColors.lerpFloatColors(float, float, float) to lerp towards black. Unlike FloatColors.lerpFloatColors(float, float, float), this keeps the alpha and both chroma of start as-is.
      Parameters:
      start - the starting color as a packed float
      change - how much to go from start toward black, as a float between 0 and 1; higher means closer to black
      Returns:
      a packed float that represents a color between start and black
      See Also:
    • protanUp

      public static float protanUp(float start, float change)
      Interpolates from the packed float color start towards a warmer color (orange to magenta) by change. While change should be between 0f (return start as-is) and 1f (return fully warmed), start should be a packed color, as from ipt(float, float, float, float). This is a good way to reduce allocations of temporary Colors, and is a little more efficient and clear than using FloatColors.lerpFloatColors(float, float, float) to lerp towards a warmer color. Unlike FloatColors.lerpFloatColors(float, float, float), this keeps the alpha and intensity of start as-is.
      Parameters:
      start - the starting color as a packed float
      change - how much to warm start, as a float between 0 and 1; higher means a warmer result
      Returns:
      a packed float that represents a color between start and a warmer color
      See Also:
    • protanDown

      public static float protanDown(float start, float change)
      Interpolates from the packed float color start towards a cooler color (green to blue) by change. While change should be between 0f (return start as-is) and 1f (return fully cooled), start should be a packed color, as from ipt(float, float, float, float). This is a good way to reduce allocations of temporary Colors, and is a little more efficient and clear than using FloatColors.lerpFloatColors(float, float, float) to lerp towards a cooler color. Unlike FloatColors.lerpFloatColors(float, float, float), this keeps the alpha and intensity of start as-is.
      Parameters:
      start - the starting color as a packed float
      change - how much to cool start, as a float between 0 and 1; higher means a cooler result
      Returns:
      a packed float that represents a color between start and a cooler color
      See Also:
    • tritanUp

      public static float tritanUp(float start, float change)
      Interpolates from the packed float color start towards a "natural" color (between green and orange) by change. While change should be between 0f (return start as-is) and 1f (return fully natural), start should be a packed color, as from ipt(float, float, float, float). This is a good way to reduce allocations of temporary Colors, and is a little more efficient and clear than using FloatColors.lerpFloatColors(float, float, float) to lerp towards a more natural color. Unlike FloatColors.lerpFloatColors(float, float, float), this keeps the alpha and intensity of start as-is.
      Parameters:
      start - the starting color as a packed float
      change - how much to change start to a natural color, as a float between 0 and 1; higher means a more natural result
      Returns:
      a packed float that represents a color between start and a more natural color
      See Also:
    • tritanDown

      public static float tritanDown(float start, float change)
      Interpolates from the packed float color start towards an "artificial" color (between blue and purple) by change. While change should be between 0f (return start as-is) and 1f (return fully artificial), start should be a packed color, as from ipt(float, float, float, float). This is a good way to reduce allocations of temporary Colors, and is a little more efficient and clear than using FloatColors.lerpFloatColors(float, float, float) to lerp towards a more artificial color. Unlike FloatColors.lerpFloatColors(float, float, float), this keeps the alpha and intensity of start as-is.
      Parameters:
      start - the starting color as a packed float
      change - how much to change start to a bolder color, as a float between 0 and 1; higher means a more artificial result
      Returns:
      a packed float that represents a color between start and a more artificial color
      See Also:
    • blot

      public static float blot(float start, float change)
      Interpolates from the packed float color start towards that color made opaque by change. While change should be between 0f (return start as-is) and 1f (return start with full alpha), start should be a packed color, as from ipt(float, float, float, float). This is a good way to reduce allocations of temporary Colors, and is a little more efficient and clear than using FloatColors.lerpFloatColors(float, float, float) to lerp towards transparent. This won't change the intensity, protan, or tritan of the color.
      Parameters:
      start - the starting color as a packed float
      change - how much to go from start toward opaque, as a float between 0 and 1; higher means closer to opaque
      Returns:
      a packed float that represents a color between start and its opaque version
      See Also:
    • fade

      public static float fade(float start, float change)
      Interpolates from the packed float color start towards transparent by change. While change should be between 0 (return start as-is) and 1f (return the color with 0 alpha), start should be a packed color, as from ipt(float, float, float, float). This is a good way to reduce allocations of temporary Colors, and is a little more efficient and clear than using FloatColors.lerpFloatColors(float, float, float) to lerp towards transparent. This won't change the intensity, protan, or tritan of the color.
      Parameters:
      start - the starting color as a packed float
      change - how much to go from start toward transparent, as a float between 0 and 1; higher means closer to transparent
      Returns:
      a packed float that represents a color between start and transparent
      See Also:
    • dullen

      public static float dullen(float start, float change)
      Brings the chromatic components of start closer to grayscale by change (desaturating them). While change should be between 0f (return start as-is) and 1f (return fully gray), start should be a packed color, as from ipt(float, float, float, float). This only changes protan and tritan; it leaves intensity and alpha alone, unlike lessenChange(float, float), which usually changes intensity.
      Parameters:
      start - the starting color as a packed float
      change - how much to change start to a desaturated color, as a float between 0 and 1; higher means a less saturated result
      Returns:
      a packed float that represents a color between start and a desaturated color
      See Also:
    • enrich

      public static float enrich(float start, float change)
      Pushes the chromatic components of start away from grayscale by change (saturating them). While change should be between 0f (return start as-is) and 1f (return maximally saturated), start should be a packed color, as from ipt(float, float, float, float). This usually changes only protan and tritan, but higher values for change can force the color out of the gamut, which this corrects using limitToGamut(float, float, float, float) (and that can change intensity somewhat). If the color stays in-gamut, then intensity won't change; alpha never changes.
      Parameters:
      start - the starting color as a packed float
      change - how much to change start to a saturated color, as a float between 0 and 1; higher means a more saturated result
      Returns:
      a packed float that represents a color between start and a saturated color
      See Also:
    • inverseLightness

      public static float inverseLightness(float mainColor, float contrastingColor)
      Given a packed float IPT color mainColor and another IPT color that it should be made to contrast with, gets a packed float IPT color with roughly inverted intnsity but the same chromatic channels and opacity (P and T are likely to be clamped if the result gets close to white or black). This won't ever produce black or other very dark colors, and also has a gap in the range it produces for intensity values between 0.5 and 0.55. That allows most of the colors this method produces to contrast well as a foreground when displayed on a background of contrastingColor, or vice versa. This will leave the intensity unchanged if the chromatic channels of the contrastingColor and those of the mainColor are already very different. This has nothing to do with the contrast channel of the tweak in ColorfulBatch; where that part of the tweak can make too-similar lightness values further apart by just a little, this makes a modification on mainColor to maximize its lightness difference from contrastingColor without losing its other qualities.
      Parameters:
      mainColor - a packed float color, as produced by ipt(float, float, float, float); this is the color that will be adjusted
      contrastingColor - a packed float color, as produced by ipt(float, float, float, float); the adjusted mainColor will contrast with this
      Returns:
      a different IPT packed float color, based on mainColor but with potentially very different lightness
    • differentiateLightness

      public static float differentiateLightness(float mainColor, float contrastingColor)
      Given a packed float IPT color mainColor and another IPT color that it should be made to contrast with, gets a packed float IPT color with I that should be quite different from contrastingColor's I, but the same chromatic channels and opacity (A and B are likely to be clamped if the result gets close to white or black). This allows most of the colors this method produces to contrast well as a foreground when displayed on a background of contrastingColor, or vice versa.
      This is similar to inverseLightness(float, float), but is considerably simpler, and this method will change the lightness of mainColor when the two given colors have close lightness but distant chroma. Because it averages the original I of mainColor with the modified one, this tends to not produce harsh color changes.
      Parameters:
      mainColor - a packed IPT float color; this is the color that will be adjusted
      contrastingColor - a packed IPT float color; the adjusted mainColor will contrast with the I of this
      Returns:
      a different packed IPT float color, based on mainColor but typically with different lightness
    • offsetLightness

      public static float offsetLightness(float mainColor)
      Pretty simple; adds 0.5 to the given color's I and wraps it around if it would go above 1.0, then averages that with the original I. This means light colors become darker, and dark colors become lighter, with almost all results in the middle-range of possible lightness.
      Parameters:
      mainColor - a packed IPT float color
      Returns:
      a different packed IPT float color, with its I channel changed and limited to the correct gamut
    • lessenChange

      public static float lessenChange(float color, float fraction)
      Makes the additive IPT color stored in color cause less of a change when used as a tint, as if it were mixed with neutral gray. When fraction is 1.0, this returns color unchanged; when fraction is 0.0, it returns Palette.GRAY, and when it is in-between 0.0 and 1.0 it returns something between the two. This is meant for things like area of effect abilities that make smaller color changes toward their periphery.
      Parameters:
      color - a color that should have its tinting effect potentially weakened
      fraction - how much of color should be kept, from 0.0 to 1.0
      Returns:
      an IPT float color between gray and color
    • randomEdit

      public static float randomEdit(float color, long seed, float variance)
      Makes a quasi-randomly-edited variant on the given color, allowing typically a small amount of variance (such as 0.05 to 0.25) between the given color and what this can return. The seed should be different each time this is called, and can be obtained from a random number generator to make the colors more random, or can be incremented on each call. If the seed is only incremented or decremented, then this shouldn't produce two similar colors in a row unless variance is very small. The variance affects the I, P, and T of the generated color, and each of those channels can go up or down by the given variance as long as the total distance isn't greater than the variance (this considers P and T extra-wide, going from -1 to 1, while I goes from 0 to 1, but only internally for measuring distance).
      Parameters:
      color - a packed float color, as produced by ipt(float, float, float, float)
      seed - a long seed that should be different on each call; should not be 0
      variance - max amount of difference between the given color and the generated color; always less than 1
      Returns:
      a generated packed float color that should be at least somewhat different from color
    • inGamut

      public static boolean inGamut(float packed)
      Returns true if the given packed float color, as IPT, is valid to convert losslessly back to RGBA.
      Parameters:
      packed - a packed float color as IPT
      Returns:
      true if the given packed float color can be converted back and forth to RGBA
    • inGamut

      public static boolean inGamut(float i, float p, float t)
      Returns true if the given IPT values are valid to convert losslessly back to RGBA.
      Parameters:
      i - intensity channel, as a float from 0 to 1
      p - protan channel, as a float from 0 to 1
      t - tritan channel, as a float from 0 to 1
      Returns:
      true if the given packed float color can be converted back and forth to RGBA
    • limitToGamut

      public static float limitToGamut(float packed)
      Iteratively checks whether the given IPT color is in-gamut, and either brings the color closer to 50% gray if it isn't in-gamut, or returns it as soon as it is in-gamut.
      Parameters:
      packed - a packed float color in IPT format; often this color is not in-gamut
      Returns:
      the first color this finds that is between the given IPT color and 50% gray, and is in-gamut
      See Also:
    • limitToGamut

      public static float limitToGamut(float i, float p, float t)
      Iteratively checks whether the given IPT color is in-gamut, and either brings the color closer to 50% gray if it isn't in-gamut, or returns it as soon as it is in-gamut. This always produces an opaque color.
      Parameters:
      i - intensity component; will be clamped between 0 and 1 if it isn't already
      p - protan component; will be clamped between 0 and 1 if it isn't already
      t - tritan component; will be clamped between 0 and 1 if it isn't already
      Returns:
      the first color this finds that is between the given IPT color and 50% gray, and is in-gamut
      See Also:
    • limitToGamut

      public static float limitToGamut(float i, float p, float t, float a)
      Iteratively checks whether the given IPT color is in-gamut, and either brings the color closer to 50% gray if it isn't in-gamut, or returns it as soon as it is in-gamut.
      Parameters:
      i - intensity component; will be clamped between 0 and 1 if it isn't already
      p - protan component; will be clamped between 0 and 1 if it isn't already
      t - tritan component; will be clamped between 0 and 1 if it isn't already
      a - alpha component; will be clamped between 0 and 1 if it isn't already
      Returns:
      the first color this finds that is between the given IPT color and 50% gray, and is in-gamut
      See Also:
    • editIPT

      public static float editIPT(float encoded, float addI, float addP, float addT, float addAlpha)
      Given a packed float IPT color, this edits its intensity, protan, tritan, and alpha channels by adding the corresponding "add" parameter and then clamping. This returns a different float value (of course, the given float can't be edited in-place). You can give a value of 0 for any "add" parameter you want to stay unchanged. This clamps the resulting color to remain in-gamut, so it should be safe to convert it back to RGBA.
      Parameters:
      encoded - a packed float IPT color
      addI - how much to add to the intensity channel; typically in the -1 to 1 range
      addP - how much to add to the protan channel; typically in the -2 to 2 range
      addT - how much to add to the tritan channel; typically in the -2 to 2 range
      addAlpha - how much to add to the alpha channel; typically in the -1 to 1 range
      Returns:
      a packed float IPT color with the requested edits applied to encoded
    • editIPT

      public static float editIPT(float encoded, float addI, float addP, float addT, float addAlpha, float mulI, float mulP, float mulT, float mulAlpha)
      Given a packed float IPT color, this edits its intensity, protan, tritan, and alpha channels by first multiplying each channel by the corresponding "mul" parameter and then adding the corresponding "add" parameter, before clamping. This means the intensity value is multiplied by mulI, then has addI added, and then is clamped to the normal range for intensity (0 to 1). This returns a different float value (of course, the given float can't be edited in-place). You can give a value of 0 for any "add" parameter you want to stay unchanged, or a value of 1 for any "mul" parameter that shouldn't change. Note that this manipulates protan and tritan in the -1 to 1 range, so if you multiply by a small number like 0.25f, then this will produce a less-saturated color, and if you multiply by a larger number like 4f, then you will get a much more-saturated color. This clamps the resulting color to remain in-gamut, so it should be safe to convert it back to RGBA.
      Parameters:
      encoded - a packed float IPT color
      addI - how much to add to the intensity channel; typically in the -1 to 1 range
      addP - how much to add to the protan channel; typically in the -2 to 2 range
      addT - how much to add to the tritan channel; typically in the -2 to 2 range
      addAlpha - how much to add to the alpha channel; typically in the -1 to 1 range
      mulI - how much to multiply the intensity channel by; should be non-negative
      mulP - how much to multiply the protan channel by; usually non-negative (not always)
      mulT - how much to multiply the tritan channel by; usually non-negative (not always)
      mulAlpha - how much to multiply the alpha channel by; should be non-negative
      Returns:
      a packed float IPT color with the requested edits applied to encoded
    • fromHSI

      public static float fromHSI(float packed)
      Converts from a packed float in HSI format to a packed float in IPT format.
      Parameters:
      packed - a packed float in HSI format
      Returns:
      a packed float in IPT format
    • fromHSI

      public static float fromHSI(float hue, float saturation, float intensity, float alpha)
      Converts from hue, saturation, intensity, and alpha components (each ranging from 0 to 1 inclusive) to a packed float color in IPT format.
      Parameters:
      hue - hue, from 0 to 1 inclusive; 0 is red, 0.25 is yellow, 0.75 is blue
      saturation - saturation from 0 (grayscale) to a limit between 0 and 1 depending on intensity (it can be 1 only when intensity is 0.5)
      intensity - intensity, or lightness, from 0 (black) to 1 (white)
      alpha - alpha transparency/opacity, from 0 (fully transparent) to 1 (fully opaque)
      Returns:
      a packed float in IPT format
    • randomColor

      public static float randomColor(Random random)
      Produces a random packed float color that is always in-gamut (and opaque) and should be uniformly distributed.
      Parameters:
      random - a Random object (or preferably a subclass of Random, like LaserRandom)
      Returns:
      a packed float color that is always in-gamut
    • randomizedColor

      public static float randomizedColor(com.github.tommyettinger.random.EnhancedRandom random)
      Produces a random packed float color that is always opaque and should be uniformly distributed. This is named differently from randomColor(Random) to avoid confusion when a class both extends Random and EnhancedRandom.
      Parameters:
      random - any subclass of juniper's EnhancedRandom, such as a DistinctRandom or FourWheelRandom
      Returns:
      a packed float color that is always in-gamut
    • subrandomColor

      public static float subrandomColor(float r, float g, float b)
      Limited-use; like randomColor(Random) but for cases where you already have three floats (r, g, and b) distributed how you want. This can be somewhat useful if you are using a "subrandom" or "quasi-random" sequence, like the Halton, Sobol, or R3 sequences, to get 3D points and map them to colors. It can also be useful if you want to randomly generate the RGB channels yourself and track the values produced, as you would if you wanted to avoid generating too many colors with high blue, for instance. This approximately maps the r, g, and b parameters to distances on the RGB axes of a rectangular prism, which is stretched and rotated to form the IPT gamut.
      Parameters:
      r - red value to use; will be clamped between 0 and 1
      g - green value to use; will be clamped between 0 and 1
      b - blue value to use; will be clamped between 0 and 1
      Returns:
      a packed float color that is always opaque