Skip to content

Instantly share code, notes, and snippets.

@saifuddin778
Last active July 1, 2016 03:54
Show Gist options
  • Save saifuddin778/c394319d00481be11a8c4a86acabca89 to your computer and use it in GitHub Desktop.
Save saifuddin778/c394319d00481be11a8c4a86acabca89 to your computer and use it in GitHub Desktop.
Color Clustering - II

Also related to the Color Clustering - I, but this example (with a few parameters tweaking) achieves clustering with more well-defined and kind of hard-imposed hyperplanes between different color clusters, making the space more well distributed.

Observing visually, one sees how colors fight and take over each other, consume the space, and grow their colonies.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
text-align: center;
}
.node {
opacity: 0.6;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var n = 40;
var m = n*n;
var width = 500;
var height = 500;
function rb(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function get_neighbors_params(node) {
var params = {};
var proximity = 2;
params.min_x = +node.attr("x") - proximity * (+node.attr("width") + 1);
params.max_x = +node.attr("x") + proximity * (+node.attr("width") + 1);
params.min_y = +node.attr("y") - proximity * (+node.attr("height") + 1);
params.max_y = +node.attr("y") + proximity * (+node.attr("height") + 1);
return params;
}
function setup_som(width, height, n) {
var space = d3.select("body").append("svg").attr("width", width).attr("height", height).append("g");
var m = n * n;
var x = 0;
var y = 0 - (height / n);
var nodes = d3.range(m).map(function(d, i) {
x = (width / n) * (d % n);
if (d % n == 0) {
y += (height / n);
}
var weight = [rb(0, 1000), 1, Math.max(Math.random(), 0.3)];
return {
x: x,
y: y,
width: width / n,
height: height / n,
weight: weight,
i: i,
fill: d3.hsl.apply(null, weight),
}
});
space.selectAll()
.data(nodes)
.enter()
.append("rect")
.attr("class", "node")
.attr("width", function(d) {
return d.width
})
.attr("height", function(d) {
return d.height
})
.attr("x", function(d) {
return d.x
})
.attr("y", function(d) {
return d.y
})
.attr("rx", function(d) {
return d.width / 6
})
.attr("ry", function(d) {
return d.height / 6
})
.attr("fill", function(d) {
return d.fill
});
}
function init_som(m) {
var iter_limit = 6000;
var t = 0;
var nodes = d3.selectAll(".node");
var runner = setInterval(
function() {
var w;
var node_i = parseInt(rb(0, m));
var node = nodes.filter(function(d) {
return d.i == node_i;
});
node.each(function(g, i) {
w = g.weight;
});
var params = get_neighbors_params(node);
nodes.filter(function(e) {
return e.x >= params.min_x && e.x <= params.max_x;
})
.filter(function(e) {
return e.y >= params.min_y && e.y <= params.max_y;
})
.each(function(d, i) {
var nw = [];
for (var ut = 0; ut < w.length; ut++) {
if (ut == 0) {
nw.push(d.weight[ut] + 0.9 * (w[ut] - d.weight[ut]));
} else if (ut == 2) {
nw.push(d.weight[ut] + 0.1 * (w[ut] - d.weight[ut]));
}
}
d.weight[0] = nw[0];
d.weight[2] = nw[1];
return;
})
.style("fill", function(d) {
return d3.hsl.apply(null, d.weight);
})
t += 1;
if (t == iter_limit) {
clearTimeout(runner);
}
},
1
);
}
setup_som(width, height, n);
init_som(m);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment