Last active
June 3, 2016 12:04
-
-
Save toja/7a6b92ba0519ab07f6a909a7ba9eeb6e to your computer and use it in GitHub Desktop.
4096 Random Colors - Histogram (DeltaE00)
This file contains 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
height: 480 | |
license: gpl-3.0 |
This file contains 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
// code adapted from https://github.com/zschuessler/DeltaE | |
function dE00(x1,x2){var sqrt=Math.sqrt;var pow=Math.pow;this.x1=x1;this.x2=x2;this.deltaLPrime=x2.l-x1.l;this.LBar=(x1.l+x2.l)/2;this.C1=sqrt(pow(x1.a,2)+pow(x1.a,2));this.C2=sqrt(pow(x2.b,2)+pow(x2.b,2));this.CBar=(this.C1+this.C2)/2;this.aPrime1=x1.a+x1.a/2*(1-sqrt(pow(this.CBar,7)/(pow(this.CBar,7)+pow(25,7))));this.aPrime2=x2.a+x2.a/2*(1-sqrt(pow(this.CBar,7)/(pow(this.CBar,7)+pow(25,7))));this.CPrime1=sqrt(pow(this.aPrime1,2)+pow(x1.b,2));this.CPrime2=sqrt(pow(this.aPrime2,2)+pow(x2.b,2));this.CBarPrime=(this.CPrime1+this.CPrime2)/2;this.deltaCPrime=this.CPrime2-this.CPrime1;this.SsubL=1+.015*pow(this.LBar-50,2)/sqrt(20+pow(this.LBar-50,2));this.SsubC=1+.045*this.CBarPrime;this.hPrime1=0;this.hPrime2=0;this.deltahPrime=0;this.deltaHPrime=0;this.HBarPrime=0;this.T=0;this.SsubH=0;this.RsubT=0}dE00.prototype.getDeltaE=function(){var sqrt=Math.sqrt;var sin=Math.sin;var pow=Math.pow;this.hPrime1=this.gethPrime1();this.hPrime2=this.gethPrime2();this.deltahPrime=this.getDeltahPrime();this.deltaHPrime=2*sqrt(this.CPrime1*this.CPrime2)*sin(this.degreesToRadians(this.deltahPrime)/2);this.HBarPrime=this.getHBarPrime();this.T=this.getT();this.SsubH=1+.015*this.CBarPrime*this.T;this.RsubT=this.getRsubT();var lightness=this.deltaLPrime/this.SsubL;var chroma=this.deltaCPrime/this.SsubC;var hue=this.deltaHPrime/this.SsubH;return sqrt(pow(lightness,2)+pow(chroma,2)+pow(hue,2)+this.RsubT*chroma*hue)};dE00.prototype.getRsubT=function(){var sin=Math.sin;var sqrt=Math.sqrt;var pow=Math.pow;var exp=Math.exp;return-2*sqrt(pow(this.CBarPrime,7)/(pow(this.CBarPrime,7)+pow(25,7)))*sin(this.degreesToRadians(60*exp(-pow((this.HBarPrime-275)/25,2))))};dE00.prototype.getT=function(){var cos=Math.cos;return 1-.17*cos(this.degreesToRadians(this.HBarPrime-30))+.24*cos(this.degreesToRadians(2*this.HBarPrime))+.32*cos(this.degreesToRadians(3*this.HBarPrime+6))-.2*cos(this.degreesToRadians(4*this.HBarPrime-63))};dE00.prototype.getHBarPrime=function(){var abs=Math.abs;if(abs(this.hPrime1-this.hPrime2)>180){return(this.hPrime1+this.hPrime2+360)/2}return(this.hPrime1+this.hPrime2)/2};dE00.prototype.getDeltahPrime=function(){var abs=Math.abs;if(0===this.C1||0===this.C2){return 0}if(abs(this.hPrime1-this.hPrime2)<=180){return this.hPrime2-this.hPrime1}if(this.hPrime2<=this.hPrime1){return this.hPrime2-this.hPrime1+360}else{return this.hPrime2-this.hPrime1-360}};dE00.prototype.gethPrime1=function(){return this._gethPrimeFn(this.x1.b,this.aPrime1)};dE00.prototype.gethPrime2=function(){return this._gethPrimeFn(this.x2.b,this.aPrime2)};dE00.prototype._gethPrimeFn=function(x,y){var hueAngle;if(x===0&&y===0){return 0}hueAngle=this.radiansToDegrees(Math.atan2(x,y));if(hueAngle>=0){return hueAngle}else{return hueAngle+360}};dE00.prototype.radiansToDegrees=function(radians){return radians*(180/Math.PI)};dE00.prototype.degreesToRadians=function(degrees){return degrees*(Math.PI/180)}; |
This file contains 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
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script src="deltaE00.min.js"></script> | |
<body> | |
<script> | |
var width = 960, | |
height = 480, | |
grid = [32,32], | |
space = 1.0, | |
deltaMin = 3.0, | |
numColors = 4096; | |
var binWidth = width / grid[0] - space * 2, | |
binHeight = height / grid[1] - space * 2; | |
var x = d3.scale.linear() | |
.domain([0, 360]) | |
.range([0, width]); | |
var y = d3.scale.linear() | |
.range([height, 0]); | |
var xz = d3.range(0, width, width / grid[0]), | |
yz = d3.range(0, height, height / grid[1]); | |
var bins = yz.map(function(y) { return xz.map(function(x) { return { x: x, y: y, z: 0 }; }); }); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
svg.append("g") | |
.selectAll(".bins") | |
.data(d3.merge(bins)) | |
.enter().append("rect") | |
.attr("id", function (d) { return "x" + d.x + "y" + d.y; }) | |
.attr("x", function (d) { return d.x + space; }) | |
.attr("y", function (d) { return d.y + space; }) | |
.attr("width", binWidth) | |
.attr("height", binHeight) | |
.style("fill", function (d) { return d3.rgb(255 - d.z, 255 - d.z, 255 - d.z).toString(); }); | |
var dots = svg.append("g") | |
var sample = colorSampler(numColors); | |
colors = []; | |
d3.timer(function() { | |
var hsl = sample(); | |
if (!hsl) return true; | |
var cx = x(hsl.h), | |
cy = y(hsl.l); | |
dots.append("circle") | |
.attr("cx", cx) | |
.attr("cy", cy) | |
.attr("r", 8) | |
.style("fill", hsl.toString()) | |
.transition() | |
.attr("r", 0); | |
var col = Math.floor((cx / width) * grid[0]), | |
row = Math.floor((cy / height) * grid[1]), | |
bin = bins[row][col], | |
id = "x" + bin.x + "y" + bin.y; | |
bin.z += 8; | |
d3.select("#" + id) | |
.style("fill", d3.rgb(255 - bin.z, 255 - bin.z, 255 - bin.z).toString()); | |
}); | |
function colorSampler(numSamplesMax) { | |
return function() { | |
if (colors.length > numSamplesMax) return; | |
do { | |
var hsl = d3.hsl(d3.rgb( | |
Math.floor(Math.random() * 256), | |
Math.floor(Math.random() * 256), | |
Math.floor(Math.random() * 256) | |
)); | |
var lab = d3.lab(hsl); | |
} | |
while (!hsl.h || !isValidColor(lab)); | |
colors.push(lab); | |
return hsl; | |
}; | |
} | |
function isValidColor(lab) { | |
if (colors.length == 0) return true; | |
for (i = 0; i < colors.length; i++) { | |
var delta = new dE00(lab, colors[i]).getDeltaE(); | |
if (delta < deltaMin) | |
return false; | |
} | |
return true; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment