Skip to content

Instantly share code, notes, and snippets.

@dylanwatsonsoftware
Created June 11, 2015 16:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dylanwatsonsoftware/3f6a658fd7209e010dad to your computer and use it in GitHub Desktop.
Save dylanwatsonsoftware/3f6a658fd7209e010dad to your computer and use it in GitHub Desktop.
Java version of @m1ch4ls C# ColorGenerator
public class ColorGenerator {
public static List<Color> generate(int colors, int skip) {
final int lastindex = colors + skip;
return new Points(colors + skip).asList().subList(skip, lastindex);
}
// RYB color space
private static class RYB {
private static final double[] White = { 1, 1, 1 };
private static final double[] Red = { 1, 0, 0 };
private static final double[] Yellow = { 1, 1, 0 };
private static final double[] Blue = { 0.163, 0.373, 0.6 };
private static final double[] Violet = { 0.5, 0, 0.5 };
private static final double[] Green = { 0, 0.66, 0.2 };
private static final double[] Orange = { 1, 0.5, 0 };
private static final double[] Black = { 0.2, 0.094, 0.0 };
public static double[] ToRgb(double r, double y, double b) {
double[] rgb = new double[3];
for (int i = 0; i < 3; i++) {
rgb[i] = White[i] * (1.0 - r) * (1.0 - b) * (1.0 - y) + Red[i] * r * (1.0 - b) * (1.0 - y)
+ Blue[i] * (1.0 - r) * b * (1.0 - y) + Violet[i] * r * b * (1.0 - y) + Yellow[i]
* (1.0 - r) * (1.0 - b) * y + Orange[i] * r * (1.0 - b) * y + Green[i] * (1.0 - r) * b
* y + Black[i] * r * b * y;
}
return rgb;
}
}
private static class Points {
private final int pointsCount;
private double[] picked;
private int pickedCount;
private final List<double[]> points = new ArrayList<double[]>();
private Points(int count) {
pointsCount = count;
}
private Points generate() {
points.clear();
int numBase = (int) Math.ceil(Math.pow(pointsCount, 1.0 / 3.0));
int ceil = (int) Math.pow(numBase, 3.0);
for (int i = 0; i < ceil; i++) {
points.add(new double[] { Math.floor(i / (double) (numBase * numBase)) / (numBase - 1.0),
Math.floor((i / (double) numBase) % numBase) / (numBase - 1.0),
Math.floor(i % numBase) / (numBase - 1.0), });
}
return this;
}
private double distance(double[] p1) {
double distance = 0;
for (int i = 0; i < 3; i++) {
distance += Math.pow(p1[i] - picked[i], 2.0);
}
return distance;
}
private double[] pick() {
if (picked == null) {
picked = points.remove(0);
pickedCount = 1;
return picked;
}
double d1 = distance(points.get(0));
int i1 = 0, i2 = 0;
for (double[] point : points) {
double d2 = distance(point);
if (d1 < d2) {
i1 = i2;
d1 = d2;
}
i2 += 1;
}
double[] pick = points.remove(i1);
for (int i = 0; i < 3; i++) {
picked[i] = (pickedCount * picked[i] + pick[i]) / (pickedCount + 1.0);
}
pickedCount += 1;
return pick;
}
public List<Color> asList() {
generate();
List<Color> colors = new ArrayList<>();
for (int i = 0; i < pointsCount; i++) {
final double[] point = pick();
double[] rgb = RYB.ToRgb(point[0], point[1], point[2]);
SolidColor color = new SolidColor(getPastelColorPercentage(rgb[0]),
getPastelColorPercentage(rgb[1]), getPastelColorPercentage(rgb[2]));
colors.add(color);
}
return colors;
}
private int getColorPercentage(final double channelPercentage) {
return (int) Math.floor(255 * channelPercentage);
}
private int getPastelColorPercentage(final double channelPercentage) {
return (int) Math.round(127 * channelPercentage + Math.random() * 100);
}
}
}
@dylanwatsonsoftware
Copy link
Author

This class is obviously missing imports but...

To use:

// The actual number of colours you need
int coloursToGenerate = 30;

// The colours at the start that you don't want (White and Black are the first 2)
int coloursToSkip = 2;

List<Color> colours = ColorGenerator.generate(coloursToGenerate, coloursToSkip);

@kibotu
Copy link

kibotu commented May 29, 2016

👍 SolidColor is kinda missing though

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment