{"item":{"status":"visible","url":"\/2011\/09\/16\/n-distinct-colors\/","trash":"","name":"n-distinct-colors","parent":"","title":"Generate N distinct colors","date":"2011-09-16 16:52:00","filepath":"posts\/2000564_n-distinct-colors.xml.json","type":"post","content":"<img class=\"alignleft size-full wp-image-570\" style=\"margin-bottom: 5px; margin-right: 5px;\" title=\"colors\" src=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colors.gif\" alt=\"colors\" width=\"157\" height=\"158\" \/>While working on a project I realized I needed to generate a specific number of colors that are visually distinct from each other so that when two colors are side-by-side, the viewer can tell they are different. \u00a0In my case, the players (of a game I am working on) need to pick a piece color so they can't be confused by another player's pieces.\n\nOne could argue about what \"visually distinct color\" means since the human eye\/brain perceives a linear hue gradient (aka rainbow) in bands. \u00a0Even a linear change in a single color is seen in bands (sudden changes of shade or saturation). \u00a0There is also the issue with color blindness...\n\nI ignored all those \"what-abouts\" and \"what ifs\" out since I wanted something quick and dirty... something finished and useful. \u00a0So, I decided to slice up the RGB color space. \u00a0Sure, I could have messed with HSL or HSV, but using RGB does the trick just fine...\n\n<em>...continued (<a href=\"http:\/\/www.8bitrobot.com\/2011\/09\/16\/n-distinct-colors\/\">explanation and source code<\/a>)<\/em>\n\n<!--more-->\n\nThere are three channels to RGB, which unsurprisingly are Red, Green, and Blue. \u00a0An RGB number can be represented in Hexadecimal like so: #3CA6FF. \u00a0What my algorithm does is vary each channel value in large jumps.\n\nStart with each channel supporting two values: 00 and FF. \u00a0If we vary each channel with these values we get 8 different colors (2 values per channel for 3 channels: 2*2*2 or 2^3):\n<ol>\n\t<li>000000<\/li>\n\t<li>0000FF<\/li>\n\t<li>00FF00<\/li>\n\t<li>00FFFF<\/li>\n\t<li>FF0000<\/li>\n\t<li>FF00FF<\/li>\n\t<li>FFFF00<\/li>\n\t<li>FFFFFF<\/li>\n<\/ol>\nIf we need more then 8 colors we need to add another value to each channel. \u00a0Say we want 3 values: 00, 80, FF. \u00a0This means we can then have 27 colors (3*3*3). \u00a0Here's a sample of some of the values:\n<ol>\n\t<li>000000<\/li>\n\t<li>000080<\/li>\n\t<li>80FF00<\/li>\n\t<li>808080<\/li>\n\t<li>FF80FF<\/li>\n\t<li>...<\/li>\n<\/ol>\nNow, let's look at it from reverse. \u00a0If you need N colors, you will then need \u00a0ceil(N^(1\/3)) values per channel. \u00a0It might be easier to read this as \"take the cube root of N then round up\". \u00a0For example, if you want 32 colors then you will need 4 values per channel.\n\nThere is a potential problem when generating these numbers programatically. \u00a0If you use simple loops then you will most likely be iterating over one channel more often than the others. \u00a0This is bad if you only a subset of all possible colors (32 of the 64 colors when using 4 values per channel). \u00a0This means your red channel probably won't get a chance to contribute and all your colors will have blue and some green tints.\n<pre style=\"padding-left: 30px;\"># this is pseudo code\ntotal = 0\nfor red in range(4):\n for green in range(4):\n for blue in range(4):\n if total &lt;= N:\n print color(red, green, blue)\n total += 1<\/pre>\nNot only that, but your list will include more of the less-distinct colors. \u00a0For example, there isn't much difference between #000033 and #000000 or #66CC99 and #99CC99. \u00a0It would be better to include #FF0000 before including values that are \"close\" to each other.\n\nSo, the python code included is an attempt to output colors that are more distinct first. \u00a0Take a look at these samples (generated with <a href=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colortohtml.txt\">colortohtml.py<\/a>). \u00a0You'll notice that the lower the N, the more distinct the color set is.\n<ul>\n\t<li><a href=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colors16.html\">16 colors<\/a><\/li>\n\t<li><a href=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colors32.html\">32 colors<\/a><\/li>\n\t<li><a href=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colors64.html\">64 colors<\/a><\/li>\n\t<li><a href=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colors128.html\">128 colors<\/a><\/li>\n\t<li><a href=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colors256.html\">256 colors<\/a><\/li>\n<\/ul>\nThe code is not perfect (or efficient), but it does get the job done. \u00a0I've put it in the public domain, so feel free to use the source code.\n<ul>\n\t<li><a href=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colorgen.txt\">colorgen.py<\/a><\/li>\n\t<li><a href=\"http:\/\/www.8bitrobot.com\/media\/uploads\/2011\/09\/colortohtml.txt\">colortohtml.py<\/a><\/li>\n<\/ul>"}}
comments powered by Disqus

Lorem Ipsum

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.


Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

This page is best viewed with Firefox 3.5+, Chrome 5+, Safari 5+, Opera 10.6+, IE 9+
Copyright © 2014 8bitrobot.com