Reputation: 71
I need to build 2d matrix 50x50 representing boxes with random colors, but if the boxes which are close to each other have the same colors, they should get different random color from each other, until it's different and then continue building.
Here I made matrix with boxes inside it works fine, but colors sometimes do match:
function onLoad(evt)
{
var matrix = [];
for (var i = 0; i < 50; i++) {
var row = [];
for (var j = 0; j < 50; j++) {
var randColor = Math.floor(Math.random()*16777215).toString(16);
row.push(MyComponent(randColor));
}
matrix.push(row);
}
var newData = matrix.map(function(row) {
return row.map(function(x) {
return x;
})})
}
Upvotes: 0
Views: 373
Reputation: 370699
You need a way to determine whether a particular color is too close to another. One way to do this is with rgb-lab (or, less accurately, euclidean distance). Say you use rgb-lab's deltaE
function, which takes two arguments, where each argument is a 3-item array of RGB amounts.
Generate your random colors such that you can get their components' decimal values easily, and so that you can also get their hex string representation easily. Then iterate over the filled adjacent indicies and compare the colors. If they're too similar, try again. Something along the lines of:
const MINIMUM_DISTANCE = 25;
const getColor = () => {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
const str = r.toString(16) + g.toString(16) + b.toString(16);
return { rgb: [r, g, b], str };
};
const matrix = [];
for (let i = 0; i < 50; i++) {
const row = [];
for (let j = 0; j < 50; j++) {
let color;
let tooClose = false;
do {
color = getColor();
tooClose =
(row[j - 1] && deltaE(color.rgb, row[j - 1].rgb) < 25) ||
(matrix[i - 1] && deltaE(color.rgb, row[i - 1][j].rgb < 25));
} while (tooClose);
row.push(color);
}
}
Change the MINIMUM_DISTANCE as desired. See here for an explanation of the numbers.
Then you'll need to turn the color objects into an array of components with color strings at the end.
const arrayOfComponents = matrix.map(
row => row.map(
({ str }) => MyComponent(str)
)
);
Upvotes: 3