<p><a href="https://stackoverflow.com/questions/180/function-for-creating-color-wheels">Original Question</a></p>

<p>If you are given N maximally distant colors (and some associated distance metric), can you come up with a way to sort those colors into some order such that the first M are also reasonably close to being a maximally distinct set?</p>

<p>In other words, given a bunch of distinct colors, come up with an ordering so I can use as many colors as I need starting at the beginning and be reasonably assured that they are all distinct and that nearby colors are also very distinct (e.g., bluish red isn't next to reddish blue).</p>

<p>Randomizing is OK but certainly not optimal.</p>

<p><em>Clarification: Given some large and visually distinct set of colors (say 256, or 1024), I want to sort them such that when I use the first, say, 16 of them that I get a relatively visually distinct subset of colors. This is equivalent, roughly, to saying I want to sort this list of 1024 so that the closer individual colors are visually, the farther apart they are on the list.</em></p>

[{'answer_id': 1340, 'author': 'Lasse V. Karlsen', 'author_id': 267, 'author_profile': 'https://Stackoverflow.com/users/267', 'pm_score': 1, 'selected': False, 'text': '<p>Do you mean that from a set of N colors, you need to pick M colors, where M &lt; N, such that M is the <em>best</em> representation of the N colors in the M space?</p>\n\n<p>As a better example, reduce a true-color (24 bit color space) to a 8-bit mapped color space (GIF?).</p>\n\n<p>There are quantization algorithms for this, like the <a href="http://www.imagemagick.org/www/quantize.html" rel="nofollow noreferrer">Adaptive Spatial Subdivision</a> algorithm used by ImageMagic.</p>\n\n<p>These algorithms usually don\'t just pick existing colors from the source space but creates new colors in the target space that most closely resemble the source colors. As a simplified example, if you have 3 colors in the original image where two are red (with different intensity or bluish tints etc.) and the third is blue, and need to reduce to two colors, the target image could have a red color that is some kind of average of the original two red + the blue color from the original image.</p>\n\n<p>If you need something else then I didn\'t understand your question :)</p>\n'}, {'answer_id': 1342, 'author': 'Nick Berardi', 'author_id': 17, 'author_profile': 'https://Stackoverflow.com/users/17', 'pm_score': 1, 'selected': False, 'text': "<p>You can split them in to RGB HEX format so that you can compare the R with R's of a different color, same with the G and B.</p>\n\n<p>Same format as HTML </p>\n\n<pre><code>XX XX XX\nRR GG BB\n\n00 00 00 = black\nff ff ff = white\nff 00 00 = red\n00 ff 00 = green\n00 00 ff = blue\n</code></pre>\n\n<p>So the only thing you would need to decide is how close you want the colors and what is an acceptable difference for the segments to be considered different.</p>\n"}, {'answer_id': 1351, 'author': 'Lasse V. Karlsen', 'author_id': 267, 'author_profile': 'https://Stackoverflow.com/users/267', 'pm_score': 2, 'selected': False, 'text': '<p>This also sounds to me like some kind of <em>resistance graph</em> where you try to map out the path of least resistance. If you inverse the requirements, path of maximum resistance, it could perhaps be used to produce a set that from the start produces maximum difference as you go, and towards the end starts to go back to values closer to the others.</p>\n\n<p>For instance, here\'s one way to perhaps do what you want.</p>\n\n<ol>\n<li>Calculate the distance (ref <a href="https://stackoverflow.com/questions/1313/followup-finding-an-accurate-distance-between-colors">your other post</a>) from each color to all other colors</li>\n<li>Sum the distances for each color, this gives you an indication for <em>how far away this color is from all other colors in total</em></li>\n<li>Order the list by distance, going down</li>\n</ol>\n\n<p>This would, it seems, produce a list that starts with the color that is farthest away from all other colors, and then go down, colors towards the end of the list would be closer to other colors in general.</p>\n\n<p>Edit: Reading your reply to my first post, about the spatial subdivision, would not exactly fit the above description, since colors close to other colors would fall to the bottom of the list, but let\'s say you have a cluster of colors somewhere, at least one of the colors from that cluster would be located near the start of the list, and it would be the one that generally was farthest away from all other colors in total. If that makes sense.</p>\n'}, {'answer_id': 8731, 'author': 'John with waffle', 'author_id': 279, 'author_profile': 'https://Stackoverflow.com/users/279', 'pm_score': 2, 'selected': False, 'text': '<p>This problem is called color quantization, and has many well known algorithms:  <a href="http://en.wikipedia.org/wiki/Color_quantization" rel="nofollow noreferrer">http://en.wikipedia.org/wiki/Color_quantization</a>  I know people who implemented the octree approach to good effect.</p>\n'}, {'answer_id': 8762, 'author': 'Coincoin', 'author_id': 42, 'author_profile': 'https://Stackoverflow.com/users/42', 'pm_score': 2, 'selected': False, 'text': "<p>It seems perception is important to you, in that case you might want to consider working with a perceptual color space such as YUV, YCbCr or Lab. Everytime I've used those, they have given me much better results than sRGB alone. </p>\n\n<p>Converting to and from sRGB can be a pain but in your case it could actually make the algorithm simpler and as a bonus it will mostly work for color blinds too!</p>\n"}, {'answer_id': 25793, 'author': 'palm3D', 'author_id': 2686, 'author_profile': 'https://Stackoverflow.com/users/2686', 'pm_score': 2, 'selected': False, 'text': '<p>N maximally distant colors can be considered a set of well-distributed points in a 3-dimensional (color) space. If you can generate them from a <a href="http://en.wikipedia.org/wiki/Halton_sequence" rel="nofollow noreferrer">Halton sequence</a>, then any prefix (the first M colors) also consists of well-distributed points.</p>\n'}, {'answer_id': 209469, 'author': 'Richard Poole', 'author_id': 26003, 'author_profile': 'https://Stackoverflow.com/users/26003', 'pm_score': 2, 'selected': False, 'text': "<p>If I'm understanding the question correctly, you wish to obtain the subset of <em>M</em> colours with the <strong>highest mean distance</strong> between colours, given some distance function <em>d</em>.</p>\n\n<p>Put another way, considering the initial set of <em>N</em> colours as a large, undirected graph in which all colours are connected, you want to find the <strong>longest path</strong> that visits any <em>M</em> nodes.</p>\n\n<p>Solving NP-complete graph problems is way beyond me I'm afraid, but you could try running a simple physical simulation:</p>\n\n<ol>\n<li>Generate <em>M</em> random points in colour space</li>\n<li>Calculate the distance between each point</li>\n<li>Calculate repulsion vectors for each point that will move it away from all other points (using 1 / (<em>distance</em> ^ 2) as the magnitude of the vector)</li>\n<li>Sum the repulsion vectors for each point</li>\n<li>Update the position of each point according to the summed repulsion vectors</li>\n<li>Constrain any out of bound coordinates (such as luminosity going negative or above one)</li>\n<li>Repeat from step 2 until the points stabilise</li>\n<li>For each point, select the nearest colour from the original set of <em>N</em></li>\n</ol>\n\n<p>It's far from efficient, but for small <em>M</em> it may be efficient enough, and it will give near optimal results.</p>\n\n<p>If your colour distance function is simple, there may be a more deterministic way of generating the optimal subset.</p>\n"}, {'answer_id': 308262, 'author': 'user4891', 'author_id': 4891, 'author_profile': 'https://Stackoverflow.com/users/4891', 'pm_score': 2, 'selected': False, 'text': "<ol>\n<li>Start with two lists.  CandidateColors, which initially contains your distinct colors and SortedColors, which is initially empty.</li>\n<li>Pick any color and remove it from CandidateColors and put it into SortedColors.  This is the first color and will be the most common, so it's a good place to pick a color that jives well with your application.</li>\n<li>For each color in CandidateColors calculate its total distance.  The total distance is the sum of the distance from the CandidateColor to each of the colors in SortedColors.</li>\n<li>Remove the color with the largest total distance from CandidateColors and add it to the end of SortedColors.</li>\n<li>If CandidateColors is not empty, go back to step 3.</li>\n</ol>\n\n<p>This greedy algorithm should give you good results.</p>\n"}, {'answer_id': 12253873, 'author': 'Tatarize', 'author_id': 631911, 'author_profile': 'https://Stackoverflow.com/users/631911', 'pm_score': 2, 'selected': False, 'text': '<p>You could just sort the candidate colors based on the maximum-distanced of the minimum-distance to any of the index colors.</p>\n\n<p>Using Euclidean color distance:</p>\n\n<pre><code>public double colordistance(Color color0, Color color1) {\n    int c0 = color0.getRGB();\n    int c1 = color1.getRGB();\n    return distance(((c0&gt;&gt;16)&amp;0xFF), ((c0&gt;&gt;8)&amp;0xFF), (c0&amp;0xFF), ((c1&gt;&gt;16)&amp;0xFF), ((c1&gt;&gt;8)&amp;0xFF), (c1&amp;0xFF));\n}\n\npublic double distance(int r1, int g1, int b1, int r2, int g2, int b2) {\n    int dr = (r1 - r2);\n    int dg = (g1 - g2);\n    int db = (b1 - b2);\n    return Math.sqrt(dr * dr + dg * dg + db * db);\n}\n</code></pre>\n\n<p>Though you can replace it with anything you want. It just needs a color distance routine.</p>\n\n<pre><code>public void colordistancesort(Color[] candidateColors, Color[] indexColors) {\n    double current;\n\n    double distance[] = new double[candidateColors.length];\n    for (int j = 0; j &lt; candidateColors.length; j++) {\n        distance[j] = -1;\n        for (int k = 0; k &lt; indexColors.length; k++) {\n            current = colordistance(indexColors[k], candidateColors[j]);\n            if ((distance[j] == -1) || (current &lt; distance[j])) {\n                distance[j] = current;\n            }\n        }\n    }\n\n    //just sorts.\n    for (int j = 0; j &lt; candidateColors.length; j++) {\n        for (int k = j + 1; k &lt; candidateColors.length; k++) {\n            if (distance[j] &gt; distance[k]) {\n                double d = distance[k];\n                distance[k] = distance[j];\n                distance[j] = d;\n\n                Color m = candidateColors[k];\n                candidateColors[k] = candidateColors[j];\n                candidateColors[j] = m;\n            }\n        }\n    }\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/1323', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2089740/']