2012-06-04 2 views
4

Мне нужна функция, которая будет генерировать три числа, поэтому я могу использовать их как шаблон RGB для моего SVG.
Хотя это просто, мне также нужно убедиться, что я не использую тот же цвет дважды. Как именно я это делаю? Сгенерируйте одно число за раз с простым rand (время посева активно), а затем что? Я не хочу исключать число, но, может быть, всю картину?
Я как бы потерялся здесь.генерировать случайный цвет RGB с использованием функции rand()

Чтобы быть точным, при первом вызове этой функции я получу, например, 218 199 154, а вторым я получу 47 212 236, которые определенно являются двумя разными цветами. Какие-либо предложения?

Также я думаю, что struct с int r, int g, int b подходит для этого?

Редактировать: Цвета должны отличаться от человеческого глаза. Извините, что не упоминал об этом раньше.

+0

Чтобы гарантировать, что один и тот же цвет никогда не используется дважды, просто храните цвета, созданные до сих пор в связанном списке (или хеш-карте, если у вас есть доступ к одному). Продолжайте применять rand, пока ваш номер не находится в этом наборе. – Lalaland

+0

Другое соображение: это «тот же цвет» для компьютера или для человека? Если во-вторых, то одной единицы разницы в одном из номеров RGB, вероятно, недостаточно, чтобы сделать ее достаточно разной для глаз. – Arkadiy

+0

@ Аркадий: да отличается от человеческого глаза. Не только другой оттенок того же цвета, который не будет узнаваем. – Markus

ответ

2

Вы можете использовать набор для хранения сгенерированных цветов. Первый instanciate новый набор. Затем каждый раз, когда вы генерируете цвет, посмотрите, присутствует ли значение в вашем наборе. Если запись существует, пропустите ее и повторите попытку для нового цвета. Если нет, вы можете использовать его, но не забывайте кэшировать его в Set after. Это может стать неэффективным, если вам нужно создать большое количество цветов.

+0

Это похоже на хорошее решение, но как я могу гарантировать, что он будет генерировать два разных цвета для двух разных вызовов, в то время как эти цвета будут быть разным человеческим глазом не только для компьютера, я имею в виду, что он будет желтым и фиолетовым, а не желтым и светло-желтым (который человеческий глаз вряд ли узнает). – Markus

+0

Итак, после генерации цвета вам нужно отсканировать сгенерированный список цветов, чтобы проверить, что он не слишком близко. Вы должны решить минимальный балл между двумя цветами (r, g, b), которые сделают результат уникальным. Если все три значения (r g и b) слишком близки к существующему цвету, вы начинаете новое поколение.IE r: 200 g: 200 b: 200. если вы создадите 199; 199; 150 с баллами, установленными в 5, это хорошо благодаря синему. Если вы проиграете 195,198,197, все три интервала цвета находятся под лимитом балла. – jocelyn

+0

все в порядке, я сделал то, что вы сказали, потому что это кажется самым простым решением для меня, и, похоже, он работает нормально. Спасибо. – Markus

0

Одна из идей заключается в использовании битового вектора для представления набора генерируемых цветов. Для 24-битной точности бит-бит будет равен 2 бит, что составляет 16 777 216 бит или 2 МБ. Конечно, не так много, в эти дни, и было бы очень быстро искать и вставлять цвета.

+0

Вы могли бы объяснить немного больше? :) – Markus

2

Самый дешевый способ сделать это - использовать Bloom filter, который имеет очень малую память, но приводит к случайным ложным срабатываниям (т. Е. Вы думаете, что используете цвет, но у вас его нет). В принципе, создайте три случайных числа между 0-255, сохраните их, как вам нравится, хешируйте их как триплет и поместите хэш в фильтр.

Также вы можете выбросить низкие биты каждого канала, так как, вероятно, нелегко сказать # FFFFF0 по сравнению с # FFFFF2.

+0

Это интересно, но проблема немного сложнее, поскольку я хочу, чтобы оба одинаковых цвета больше не повторялись, и 255 255 0 для первого вызова и 255 255 1 для второго не произойдет. (так как это вряд ли узнаваем) – Markus

+0

Мне это известно. Мое предложение не производит их в таком порядке. Я просто имею в виду, что при вычислении хэш-функций в фильтре вы должны отбрасывать младшие биты, чтобы предотвратить такое дублирование. – apmasell

+0

Мне удалось добиться этого с помощью другого решения, но спасибо за ваше время :) – Markus

2

Вот простой способ:

1.Generate a random integer. 
2.Shift it 8 times to have 24 meaningful bits, store this integer value. 
3.Use first 8 bits for R, second group of 8 bits for G, 
     and the remaining 8 bits for B value. 

Для каждого нового случайного числа, переложить его в 8 раз, сравнить все другие целые значения, сохраненные ранее, если ни один из них не совпадает с новым использовать его для нового цвета (шаг 3).

Дифференциация человеческого глаза - интересная тема, поскольку пороги восприятия варьируются от одного человека к другому. Чтобы достичь этого, смените целое число 14 раз, получите первые 6 бит для R (два байта на две, чтобы снова получить 8 бит), получите второй 6 бит для G и последние 6 бит для B. Если вы считаете, что 6 бит не являются хорошо для него, уменьшить его на 5,4 ...

простого Запуск с 4 значащими битами для каждого канала: Моего случайное целого:

0101-1111-0000-1111-0000-1100-1101-0000 

I сдвиг (вы можете также использовать многократно или по модулю) он остается 20 раз:

0000-0000-0000-0000-0000-0101-1111-0000 

хранить это значение.

Затем получают первые 4 бита для R 4 вторых бит для G и последние 4 бита для B:

R: 0101 
G: 1111 
B: 0000 

Коврик их, чтобы сделать каждый из них 8 бит.

R: 0101-0000 
G: 1111-0000 
B: 0000-0000 

Используйте их для своих цветовых компонентов.

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

Смежные вопросы