Самый быстрый способ создать цвет, который не находится в массиве цветов - PullRequest
1 голос
/ 04 декабря 2011

Мне интересно, как лучше решить эту проблему ...

У меня есть массив пользовательских цветов, которые помещаются в стек как значения rgb.Я хочу найти второй цвет для каждого определенного пользователем цвета.Эти вторые цвета должны быть полностью уникальными из пользовательского массива, но могут быть совершенно случайными и не должны иметь никаких визуальных отношений с любым из пользовательских цветов.

Будет генерировать случайные значения RGB и проверять его на соответствиестек будет быстрым, поскольку маловероятно, что случайные числа найдут один и тот же цвет с первой попытки.Или просто начать с 255 254 253 и вычесть 1 из каждого значения, а затем лучше протестировать его со стеком, что также очень маловероятно и требует меньше операций.Или любая другая идея?

Ответы [ 3 ]

2 голосов
/ 04 декабря 2011

Вот код для начала:

var colors = [];

function getRandUniqColor()
{
    var r = getRGBString(),
        g = getRGBString(),
        b = getRGBString(),
        rgb = r + g + b;

    if ( colors.indexOf(rgb) == -1 )
    {
        colors.push(rgb);
        return {
            r: r,
            g: g,
            b: b
        }
    }
    else
    {
        return getRandUniqColor()
    }
}

function getRGBString()
{
    var num = Math.floor( Math.random() * 255 ).toString();
    while (num.length < 3)
    {
        num = '0' + num;
    }
    return num;
}

Просто вызовите getRandUniqColor(), и вы получите объектный литерал значений RGB.

Примечание: Если будет задействовано много цветов, вы не должны использовать рекурсивную функцию.

... и вот скрипка: http://jsfiddle.net/wV6Mw/

1 голос
/ 04 декабря 2011

Я бы предложил генерировать случайные значения RGB (объединить три случайных числа), а затем создать функцию, которая измеряет разницу в цвете между сгенерированным случайным цветом и значениями в вашей структуре данных.Если ваш сгенерированный цвет слишком близок к тому, который у вас уже есть, создайте новый.Вам нужно будет решить, насколько «отличным» вы хотите, чтобы случайный цвет был от того, который у вас уже есть, но разница только в нескольких точках R, G и B не будет заметно различаться, поэтому вам следует искать какой-то минимумразделение по крайней мере в одном канале.

Поиск «Рассчитать цветовую разницу RGB» дает вам множество ссылок на то, как рассчитать значимую разницу между двумя значениями цвета.Эта ссылка из этого поиска имеет конкретное уравнение, и вот предыдущий вопрос о SO о цветовых различиях.

Вы также можете создавать дополнительные цвета из того, что у вас уже есть, есливам просто нужны разные цвета и вам не нужны / не нужны действительно случайные цвета.

Вы можете сгенерировать случайный цвет, подобный этому, в форме данных или в форме шестнадцатеричной строки:

// generate r,g,b data structure like {r: 255, g: 30, b: 09}
function generateRandomColorData() {
    function randomColorVal() {
        return(Math.floor(Math.random() * 256));
    }
    return {r:randomColorVal(), g: randomeColorVal(), b: randomColorVal()};
}

// generate hex string color value like FF4409
function generateRandomColorHex() {
    function randomColorVal() {
        var val = Math.floor(Math.random() * 256).toString(16);
        if (val.length < 2) {
            val = "0" + val;
        }
        return(val);
    }
    return(randomColorVal() + randomColorVal() + randomColorVal());
}
0 голосов
/ 04 декабря 2011

Как уже говорили другие, самый простой способ, вероятно, будет просто создать случайные цвета и проверить наличие коллизий.

Если вы много заполняете цветовое пространство (пользователи выбирают миллионы цветов), то другим способом будет создание цветового куба размером 256 ^ 3 бит, и пусть «1» представляет используемые цвета.Затем вы можете начать с позиции 0 и использовать первый «0» в качестве сгенерированного цвета, следующий «0» в качестве второго и так далее.Структура данных будет чуть более 2 МБ оперативной памяти.

Но случайность - это, вероятно, путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...