Created
April 10, 2019 16:21
-
-
Save loretoparisi/d9272754d59d5c660f0f24c5d5330ac1 to your computer and use it in GitHub Desktop.
Generate a random HSV palette of non overlapping colors
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function randomHSVPalette(options) { | |
function random(min, max) { | |
return min + Math.random() * (max - min); | |
} | |
function HSVtoXYZ(hsv) { | |
var h = hsv[0]; | |
var s = hsv[1]; | |
var v = hsv[2]; | |
var angle = h * Math.PI * 2; | |
return [Math.sin(angle) * s * v, | |
Math.cos(angle) * s * v, | |
v | |
]; | |
} | |
function distSq(a, b) { | |
var dx = a[0] - b[0]; | |
var dy = a[1] - b[1]; | |
var dz = a[2] - b[2]; | |
return dx * dx + dy * dy + dz * dz; | |
} | |
if (!options) { | |
options = {}; | |
} | |
var numColors = options.numColors || 10; | |
var hRange = options.hRange || [0, 1]; | |
var sRange = options.sRange || [0, 1]; | |
var vRange = options.vRange || [0, 1]; | |
var exclude = options.exclude || [ | |
[0, 0, 0], | |
[0, 0, 1] | |
]; | |
var points = exclude.map(HSVtoXYZ); | |
var result = []; | |
while (result.length < numColors) { | |
var bestHSV; | |
var bestXYZ; | |
var bestDist = 0; | |
for (var i = 0; i < 100; i++) { | |
var hsv = [random(hRange[0], hRange[1]), random(sRange[0], sRange[1]), random(vRange[0], vRange[1])]; | |
var xyz = HSVtoXYZ(hsv); | |
var minDist = 100; | |
points.forEach(function(point) { | |
minDist = Math.min(minDist, distSq(xyz, point)); | |
}); | |
if (minDist > bestDist) { | |
bestHSV = hsv; | |
bestXYZ = xyz; | |
bestDist = minDist; | |
} | |
} | |
points.push(bestXYZ); | |
result.push(bestHSV); | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage