Створюйте на графіках чітко різні кольори RGB


84

При генерації графіків та відображенні різних наборів даних зазвичай є гарною ідеєю розрізняти набори за кольором. Тож один рядок - червоний, а наступний - зелений тощо. Тоді проблема полягає в тому, що коли кількість наборів даних невідома, потрібно випадково генерувати ці кольори, і вони часто потрапляють дуже близько один до одного (зелений, світло-зелений, наприклад).

Будь-які ідеї щодо того, як це можна вирішити і як можна було б генерувати чітко різні кольори?

Було б чудово, якби якісь приклади (не соромтеся просто обговорити проблему та рішення без прикладів, якщо вам це легше) були в кольорах на основі C # та RGB.


Відповіді:


132

У вас є три кольорових канали від 0 до 255 R, G і B.

Спочатку пройдіть

0, 0, 255
0, 255, 0
255, 0, 0

Тоді пройдіть

0, 255, 255
255, 0, 255
255, 255, 0

Потім розділіть на 2 => 128 і почніть спочатку:

0, 0, 128
0, 128, 0
128, 0, 0
0, 128, 128
128, 0, 128
128, 128, 0

Ділимо на 2 => 64

Наступного разу додати 64 до 128 => 192

дотримуйтесь шаблону.

Просте програмування і дає вам досить чіткі кольори.

EDIT: Запит на зразок коду

Також - додавши додатковий шаблон, як показано нижче, якщо сірий колір є прийнятним:

255, 255, 255
128, 128, 128 

Є кілька способів, як ви можете впоратися з їх генеруванням у коді.

Легкий шлях

Якщо ви можете гарантувати, що вам ніколи не знадобиться більше фіксованої кількості кольорів, просто сформуйте масив кольорів за цим шаблоном і використовуйте такі:

    static string[] ColourValues = new string[] { 
        "FF0000", "00FF00", "0000FF", "FFFF00", "FF00FF", "00FFFF", "000000", 
        "800000", "008000", "000080", "808000", "800080", "008080", "808080", 
        "C00000", "00C000", "0000C0", "C0C000", "C000C0", "00C0C0", "C0C0C0", 
        "400000", "004000", "000040", "404000", "400040", "004040", "404040", 
        "200000", "002000", "000020", "202000", "200020", "002020", "202020", 
        "600000", "006000", "000060", "606000", "600060", "006060", "606060", 
        "A00000", "00A000", "0000A0", "A0A000", "A000A0", "00A0A0", "A0A0A0", 
        "E00000", "00E000", "0000E0", "E0E000", "E000E0", "00E0E0", "E0E0E0", 
    };

Важкий шлях

Якщо ви не знаєте, скільки кольорів вам знадобиться, код нижче сформує до 896 кольорів, використовуючи цей шаблон. (896 = 256 * 7/2) 256 - це кольоровий простір на канал, у нас є 7 шаблонів, і ми зупиняємось, перш ніж дійдемо до кольорів, розділених лише 1 значенням кольору.

Я, мабуть, зробив цю роботу важче, ніж потрібно. По-перше, існує генератор інтенсивності, який починається з 255, потім генерує значення відповідно до схеми, описаної вище. Генератор шаблонів просто перебирає сім кольорових шаблонів.

using System;

class Program {
    static void Main(string[] args) {
        ColourGenerator generator = new ColourGenerator();
        for (int i = 0; i < 896; i++) {
            Console.WriteLine(string.Format("{0}: {1}", i, generator.NextColour()));
        }
    }
}

public class ColourGenerator {

    private int index = 0;
    private IntensityGenerator intensityGenerator = new IntensityGenerator();

    public string NextColour() {
        string colour = string.Format(PatternGenerator.NextPattern(index),
            intensityGenerator.NextIntensity(index));
        index++;
        return colour;
    }
}

public class PatternGenerator {
    public static string NextPattern(int index) {
        switch (index % 7) {
        case 0: return "{0}0000";
        case 1: return "00{0}00";
        case 2: return "0000{0}";
        case 3: return "{0}{0}00";
        case 4: return "{0}00{0}";
        case 5: return "00{0}{0}";
        case 6: return "{0}{0}{0}";
        default: throw new Exception("Math error");
        }
    }
}

public class IntensityGenerator {
    private IntensityValueWalker walker;
    private int current;

    public string NextIntensity(int index) {
        if (index == 0) {
            current = 255;
        }
        else if (index % 7 == 0) {
            if (walker == null) {
                walker = new IntensityValueWalker();
            }
            else {
                walker.MoveNext();
            }
            current = walker.Current.Value;
        }
        string currentText = current.ToString("X");
        if (currentText.Length == 1) currentText = "0" + currentText;
        return currentText;
    }
}

public class IntensityValue {

    private IntensityValue mChildA;
    private IntensityValue mChildB;

    public IntensityValue(IntensityValue parent, int value, int level) {
        if (level > 7) throw new Exception("There are no more colours left");
        Value = value;
        Parent = parent;
        Level = level;
    }

    public int Level { get; set; }
    public int Value { get; set; }
    public IntensityValue Parent { get; set; }

    public IntensityValue ChildA {
        get {
            return mChildA ?? (mChildA = new IntensityValue(this, this.Value - (1<<(7-Level)), Level+1));
        }
    }

    public IntensityValue ChildB {
        get {
            return mChildB ?? (mChildB = new IntensityValue(this, Value + (1<<(7-Level)), Level+1));
        }
    }
}

public class IntensityValueWalker {

    public IntensityValueWalker() {
        Current = new IntensityValue(null, 1<<7, 1);
    }

    public IntensityValue Current { get; set; }

    public void MoveNext() {
        if (Current.Parent == null) {
            Current = Current.ChildA;
        }
        else if (Current.Parent.ChildA == Current) {
            Current = Current.Parent.ChildB;
        }
        else {
            int levelsUp = 1;
            Current = Current.Parent;
            while (Current.Parent != null && Current == Current.Parent.ChildB) {
                Current = Current.Parent;
                levelsUp++;
            }
            if (Current.Parent != null) {
                Current = Current.Parent.ChildB;
            }
            else {
                levelsUp++;
            }
            for (int i = 0; i < levelsUp; i++) {
                Current = Current.ChildA;
            }

        }
    }
}

Я не повністю беру приклад. Хтось може навести для цього приклад на C #?
McBainUK

Сподіваюся, що зразок коду допомагає - мабуть, є набагато чистіший спосіб ходити по дереву значень інтенсивності, але це був перший удар, який працював досить добре. Ура.
Sam Meldrum

4
Зверніть увагу, що цей алгоритм створить кілька кольорових пар, ДУЖЕ схожих (особливо в дуже темних або світлих регіонах з низьким насиченням). Він добре справляється зі стартом у регіонах з високою насиченістю та легкістю, але пропускає багато тонких кольорів, які все ще візуально відрізняються.
Фрогц

1
У підсумку я зробив щось подібне у Javascript - здається, на rgb будується психічний костиль / обмежувальний реагент. Якби у нас було чотири кольорових канали на 256 варіантів, чи писали б ми формули з (* n ) більшою кількістю кольорів? Навіть незважаючи на це, критика @Phrogz & @dean все одно буде стояти (і саме тому я шукав ТО кращої відповіді). Повинен бути спосіб захопити чітко різні відтінки на кожному кроці інтенсивності. Відповідь Фрогза, наведена нижче, йде на правильному шляху, але не швидко доступна таким людям, як я, якщо я хочу сотні кольорів за допомогою якогось intлічильника.
рюш

2
Я додав відповідь програмно вирішуючи питання. Ця відповідь тут насправді помилкова. Коли ви додаєте 128 до суміші. Ви не просто візеруєте його 0. Ви візеруєте 0 і 255. Список кольорів "Легкий шлях" у цьому відношенні однаково розбитий. Це в основному білі, чорні, R, G, B, C, Y, M поступово слабкі і слабкі.
Татарізувати

80

Для реалізації списку варіацій, куди потрапляють ваші кольори, 255 потім використовуйте всі можливості цього, потім додайте 0 і всі шаблони RGB з цими двома значеннями. Потім додайте 128 і всі комбінації RGB з ними. Потім 64. Потім 192. І т.д.

На Java

public Color getColor(int i) {
    return new Color(getRGB(i));
}

public int getRGB(int index) {
    int[] p = getPattern(index);
    return getElement(p[0]) << 16 | getElement(p[1]) << 8 | getElement(p[2]);
}

public int getElement(int index) {
    int value = index - 1;
    int v = 0;
    for (int i = 0; i < 8; i++) {
        v = v | (value & 1);
        v <<= 1;
        value >>= 1;
    }
    v >>= 1;
    return v & 0xFF;
}

public int[] getPattern(int index) {
    int n = (int)Math.cbrt(index);
    index -= (n*n*n);
    int[] p = new int[3];
    Arrays.fill(p,n);
    if (index == 0) {
        return p;
    }
    index--;
    int v = index % 3;
    index = index / 3;
    if (index < n) {
        p[v] = index % n;
        return p;
    }
    index -= n;
    p[v      ] = index / n;
    p[++v % 3] = index % n;
    return p;
}

Це дозволить створювати візерунки цього типу нескінченно (2 ^ 24) у майбутньому. Однак через сотню плям ви, швидше за все, не побачите великої різниці між кольором з 0 або 32 на місці синього.

Можливо, вам краще нормалізувати це в інший колірний простір. Колірний простір LAB, наприклад із нормалізованими та перетвореними значеннями L, A, B. Тож виразність кольору проштовхується через щось більше схоже на людське око.

getElement () перевертає ендіан 8-бітового числа і починає рахувати від -1, а не від 0 (маскуючи за допомогою 255). Отже, він переходить 255,01271992,64, ... із зростанням числа він рухається все менше і менше значущих бітів, поділяючи число.

getPattern () визначає, яким повинен бути найважливіший елемент у шаблоні (це корінь куба). Потім приступає до розбиття 3N² + 3N + 1 різних моделей, що включають цей найважливіший елемент.

Цей алгоритм створить (перші 128 значень):

#FFFFFF 
#000000 
#FF0000 
#00FF00 
#0000FF 
#FFFF00 
#00FFFF 
#FF00FF 
#808080 
#FF8080 
#80FF80 
#8080FF 
#008080 
#800080 
#808000 
#FFFF80 
#80FFFF 
#FF80FF 
#FF0080 
#80FF00 
#0080FF 
#00FF80 
#8000FF 
#FF8000 
#000080 
#800000 
#008000 
#404040 
#FF4040 
#40FF40 
#4040FF 
#004040 
#400040 
#404000 
#804040 
#408040 
#404080 
#FFFF40 
#40FFFF 
#FF40FF 
#FF0040 
#40FF00 
#0040FF 
#FF8040 
#40FF80 
#8040FF 
#00FF40 
#4000FF 
#FF4000 
#000040 
#400000 
#004000 
#008040 
#400080 
#804000 
#80FF40 
#4080FF 
#FF4080 
#800040 
#408000 
#004080 
#808040 
#408080 
#804080 
#C0C0C0 
#FFC0C0 
#C0FFC0 
#C0C0FF 
#00C0C0 
#C000C0 
#C0C000 
#80C0C0 
#C080C0 
#C0C080 
#40C0C0 
#C040C0 
#C0C040 
#FFFFC0 
#C0FFFF 
#FFC0FF 
#FF00C0 
#C0FF00 
#00C0FF 
#FF80C0 
#C0FF80 
#80C0FF 
#FF40C0 
#C0FF40 
#40C0FF 
#00FFC0 
#C000FF 
#FFC000 
#0000C0 
#C00000 
#00C000 
#0080C0 
#C00080 
#80C000 
#0040C0 
#C00040 
#40C000 
#80FFC0 
#C080FF 
#FFC080 
#8000C0 
#C08000 
#00C080 
#8080C0 
#C08080 
#80C080 
#8040C0 
#C08040 
#40C080 
#40FFC0 
#C040FF 
#FFC040 
#4000C0 
#C04000 
#00C040 
#4080C0 
#C04080 
#80C040 
#4040C0 
#C04040 
#40C040 
#202020 
#FF2020 
#20FF20 

Прочитайте зліва направо, зверху вниз. 729 кольорів (9³). Отже, всі шаблони до n = 9. Ви помітите швидкість, з якою вони починають стикатися. Існує лише так багато варіантів WRGBCYMK. І це рішення, хоча розумне в основному робить лише різні відтінки основних кольорів.

Колірна сітка, 729 16x16

Значна частина суперечок пов’язана із зеленим кольором і тим, як більшість зелених рослин схожі на більшість людей. Вимога, щоб кожен з них на початку був максимально різним, а не просто достатньо різним, щоб не мати однаковий колір. І основні недоліки ідеї, що призводять до основних кольорових візерунків та однакових відтінків.


Використовуючи CIELab2000 Колірний простір та відстань, щоб випадково вибрати та спробувати 10 тис. Різних кольорів та знайти максимально віддалену мінімальну відстань від попередніх кольорів (майже у визначенні запиту) дозволяє уникнути конфлікту довше, ніж вищезазначене рішення:

Макс. Кольорова відстань

Що можна було б просто назвати статичним списком для «Легкого шляху». На створення 729 записів пішло півтори години:

#9BC4E5
#310106
#04640D
#FEFB0A
#FB5514
#E115C0
#00587F
#0BC582
#FEB8C8
#9E8317
#01190F
#847D81
#58018B
#B70639
#703B01
#F7F1DF
#118B8A
#4AFEFA
#FCB164
#796EE6
#000D2C
#53495F
#F95475
#61FC03
#5D9608
#DE98FD
#98A088
#4F584E
#248AD0
#5C5300
#9F6551
#BCFEC6
#932C70
#2B1B04
#B5AFC4
#D4C67A
#AE7AA1
#C2A393
#0232FD
#6A3A35
#BA6801
#168E5C
#16C0D0
#C62100
#014347
#233809
#42083B
#82785D
#023087
#B7DAD2
#196956
#8C41BB
#ECEDFE
#2B2D32
#94C661
#F8907D
#895E6B
#788E95
#FB6AB8
#576094
#DB1474
#8489AE
#860E04
#FBC206
#6EAB9B
#F2CDFE
#645341
#760035
#647A41
#496E76
#E3F894
#F9D7CD
#876128
#A1A711
#01FB92
#FD0F31
#BE8485
#C660FB
#120104
#D48958
#05AEE8
#C3C1BE
#9F98F8
#1167D9
#D19012
#B7D802
#826392
#5E7A6A
#B29869
#1D0051
#8BE7FC
#76E0C1
#BACFA7
#11BA09
#462C36
#65407D
#491803
#F5D2A8
#03422C
#72A46E
#128EAC
#47545E
#B95C69
#A14D12
#C4C8FA
#372A55
#3F3610
#D3A2C6
#719FFA
#0D841A
#4C5B32
#9DB3B7
#B14F8F
#747103
#9F816D
#D26A5B
#8B934B
#F98500
#002935
#D7F3FE
#FCB899
#1C0720
#6B5F61
#F98A9D
#9B72C2
#A6919D
#2C3729
#D7C70B
#9F9992
#EFFBD0
#FDE2F1
#923A52
#5140A7
#BC14FD
#6D706C
#0007C4
#C6A62F
#000C14
#904431
#600013
#1C1B08
#693955
#5E7C99
#6C6E82
#D0AFB3
#493B36
#AC93CE
#C4BA9C
#09C4B8
#69A5B8
#374869
#F868ED
#E70850
#C04841
#C36333
#700366
#8A7A93
#52351D
#B503A2
#D17190
#A0F086
#7B41FC
#0EA64F
#017499
#08A882
#7300CD
#A9B074
#4E6301
#AB7E41
#547FF4
#134DAC
#FDEC87
#056164
#FE12A0
#C264BA
#939DAD
#0BCDFA
#277442
#1BDE4A
#826958
#977678
#BAFCE8
#7D8475
#8CCF95
#726638
#FEA8EB
#EAFEF0
#6B9279
#C2FE4B
#304041
#1EA6A7
#022403
#062A47
#054B17
#F4C673
#02FEC7
#9DBAA8
#775551
#835536
#565BCC
#80D7D2
#7AD607
#696F54
#87089A
#664B19
#242235
#7DB00D
#BFC7D6
#D5A97E
#433F31
#311A18
#FDB2AB
#D586C9
#7A5FB1
#32544A
#EFE3AF
#859D96
#2B8570
#8B282D
#E16A07
#4B0125
#021083
#114558
#F707F9
#C78571
#7FB9BC
#FC7F4B
#8D4A92
#6B3119
#884F74
#994E4F
#9DA9D3
#867B40
#CED5C4
#1CA2FE
#D9C5B4
#FEAA00
#507B01
#A7D0DB
#53858D
#588F4A
#FBEEEC
#FC93C1
#D7CCD4
#3E4A02
#C8B1E2
#7A8B62
#9A5AE2
#896C04
#B1121C
#402D7D
#858701
#D498A6
#B484EF
#5C474C
#067881
#C0F9FC
#726075
#8D3101
#6C93B2
#A26B3F
#AA6582
#4F4C4F
#5A563D
#E83005
#32492D
#FC7272
#B9C457
#552A5B
#B50464
#616E79
#DCE2E4
#CF8028
#0AE2F0
#4F1E24
#FD5E46
#4B694E
#C5DEFC
#5DC262
#022D26
#7776B8
#FD9F66
#B049B8
#988F73
#BE385A
#2B2126
#54805A
#141B55
#67C09B
#456989
#DDC1D9
#166175
#C1E29C
#A397B5
#2E2922
#ABDBBE
#B4A6A8
#A06B07
#A99949
#0A0618
#B14E2E
#60557D
#D4A556
#82A752
#4A005B
#3C404F
#6E6657
#7E8BD5
#1275B8
#D79E92
#230735
#661849
#7A8391
#FE0F7B
#B0B6A9
#629591
#D05591
#97B68A
#97939A
#035E38
#53E19E
#DFD7F9
#02436C
#525A72
#059A0E
#3E736C
#AC8E87
#D10C92
#B9906E
#66BDFD
#C0ABFD
#0734BC
#341224
#8AAAC1
#0E0B03
#414522
#6A2F3E
#2D9A8A
#4568FD
#FDE6D2
#FEE007
#9A003C
#AC8190
#DCDD58
#B7903D
#1F2927
#9B02E6
#827A71
#878B8A
#8F724F
#AC4B70
#37233B
#385559
#F347C7
#9DB4FE
#D57179
#DE505A
#37F7DD
#503500
#1C2401
#DD0323
#00A4BA
#955602
#FA5B94
#AA766C
#B8E067
#6A807E
#4D2E27
#73BED7
#D7BC8A
#614539
#526861
#716D96
#829A17
#210109
#436C2D
#784955
#987BAB
#8F0152
#0452FA
#B67757
#A1659F
#D4F8D8
#48416F
#DEBAAF
#A5A9AA
#8C6B83
#403740
#70872B
#D9744D
#151E2C
#5C5E5E
#B47C02
#F4CBD0
#E49D7D
#DD9954
#B0A18B
#2B5308
#EDFD64
#9D72FC
#2A3351
#68496C
#C94801
#EED05E
#826F6D
#E0D6BB
#5B6DB4
#662F98
#0C97CA
#C1CA89
#755A03
#DFA619
#CD70A8
#BBC9C7
#F6BCE3
#A16462
#01D0AA
#87C6B3
#E7B2FA
#D85379
#643AD5
#D18AAE
#13FD5E
#B3E3FD
#C977DB
#C1A7BB
#9286CB
#A19B6A
#8FFED7
#6B1F17
#DF503A
#10DDD7
#9A8457
#60672F
#7D327D
#DD8782
#59AC42
#82FDB8
#FC8AE7
#909F6F
#B691AE
#B811CD
#BCB24E
#CB4BD9
#2B2304
#AA9501
#5D5096
#403221
#F9FAB4
#3990FC
#70DE7F
#95857F
#84A385
#50996F
#797B53
#7B6142
#81D5FE
#9CC428
#0B0438
#3E2005
#4B7C91
#523854
#005EA9
#F0C7AD
#ACB799
#FAC08E
#502239
#BFAB6A
#2B3C48
#0EB5D8
#8A5647
#49AF74
#067AE9
#F19509
#554628
#4426A4
#7352C9
#3F4287
#8B655E
#B480BF
#9BA74C
#5F514C
#CC9BDC
#BA7942
#1C4138
#3C3C3A
#29B09C
#02923F
#701D2B
#36577C
#3F00EA
#3D959E
#440601
#8AEFF3
#6D442A
#BEB1A8
#A11C02
#8383FE
#A73839
#DBDE8A
#0283B3
#888597
#32592E
#F5FDFA
#01191B
#AC707A
#B6BD03
#027B59
#7B4F08
#957737
#83727D
#035543
#6F7E64
#C39999
#52847A
#925AAC
#77CEDA
#516369
#E0D7D0
#FCDD97
#555424
#96E6B6
#85BB74
#5E2074
#BD5E48
#9BEE53
#1A351E
#3148CD
#71575F
#69A6D0
#391A62
#E79EA0
#1C0F03
#1B1636
#D20C39
#765396
#7402FE
#447F3E
#CFD0A8
#3A2600
#685AFC
#A4B3C6
#534302
#9AA097
#FD5154
#9B0085
#403956
#80A1A7
#6E7A9A
#605E6A
#86F0E2
#5A2B01
#7E3D43
#ED823B
#32331B
#424837
#40755E
#524F48
#B75807
#B40080
#5B8CA1
#FDCFE5
#CCFEAC
#755847
#CAB296
#C0D6E3
#2D7100
#D5E4DE
#362823
#69C63C
#AC3801
#163132
#4750A6
#61B8B2
#FCC4B5
#DEBA2E
#FE0449
#737930
#8470AB
#687D87
#D7B760
#6AAB86
#8398B8
#B7B6BF
#92C4A1
#B6084F
#853B5E
#D0BCBA
#92826D
#C6DDC6
#BE5F5A
#280021
#435743
#874514
#63675A
#E97963
#8F9C9E
#985262
#909081
#023508
#DDADBF
#D78493
#363900
#5B0120
#603C47
#C3955D
#AC61CB
#FD7BA7
#716C74
#8D895B
#071001
#82B4F2
#B6BBD8
#71887A
#8B9FE3
#997158
#65A6AB
#2E3067
#321301
#FEECCB
#3B5E72
#C8FE85
#A1DCDF
#CB49A6
#B1C5E4
#3E5EB0
#88AEA7
#04504C
#975232
#6786B9
#068797
#9A98C4
#A1C3C2
#1C3967
#DBEA07
#789658
#E7E7C6
#A6C886
#957F89
#752E62
#171518
#A75648
#01D26F
#0F535D
#047E76
#C54754
#5D6E88
#AB9483
#803B99
#FA9C48
#4A8A22
#654A5C
#965F86
#9D0CBB
#A0E8A0
#D3DBFA
#FD908F
#AEAB85
#A13B89
#F1B350
#066898
#948A42
#C8BEDE
#19252C
#7046AA
#E1EEFC
#3E6557
#CD3F26
#2B1925
#DDAD94
#C0B109
#37DFFE
#039676
#907468
#9E86A5
#3A1B49
#BEE5B7
#C29501
#9E3645
#DC580A
#645631
#444B4B
#FD1A63
#DDE5AE
#887800
#36006F
#3A6260
#784637
#FEA0B7
#A3E0D2
#6D6316
#5F7172
#B99EC7
#777A7E
#E0FEFD
#E16DC5
#01344B
#F8F8FC
#9F9FB5
#182617
#FE3D21
#7D0017
#822F21
#EFD9DC
#6E68C4
#35473E
#007523
#767667
#A6825D
#83DC5F
#227285
#A95E34
#526172
#979730
#756F6D
#716259
#E8B2B5
#B6C9BB
#9078DA
#4F326E
#B2387B
#888C6F
#314B5F
#E5B678
#38A3C6
#586148
#5C515B
#CDCCE1
#C8977F

Використовуючи грубу силу для (тестування всіх 16 777 216 кольорів RGB за допомогою CIELab Delta2000 / починаючи з чорного), виходить серія. Що починає зіткнення приблизно в 26, але може досягти 30 або 40 за допомогою візуального огляду та ручного видалення (що неможливо зробити за допомогою комп’ютера). Отже, досягнення абсолютного максимуму, який можна програмно, дає лише кілька десятків різних кольорів. Окремий список - найкращий вибір. Зі списком ви отримаєте більше дискретних кольорів, ніж програмно. Простий спосіб є найкращим рішенням, почніть змішувати та поєднувати з іншими способами змінити ваші дані, крім кольору.

Максимально різний

#000000
#00FF00
#0000FF
#FF0000
#01FFFE
#FFA6FE
#FFDB66
#006401
#010067
#95003A
#007DB5
#FF00F6
#FFEEE8
#774D00
#90FB92
#0076FF
#D5FF00
#FF937E
#6A826C
#FF029D
#FE8900
#7A4782
#7E2DD2
#85A900
#FF0056
#A42400
#00AE7E
#683D3B
#BDC6FF
#263400
#BDD393
#00B917
#9E008E
#001544
#C28C9F
#FF74A3
#01D0FF
#004754
#E56FFE
#788231
#0E4CA1
#91D0CB
#BE9970
#968AE8
#BB8800
#43002C
#DEFF74
#00FFC6
#FFE502
#620E00
#008F9C
#98FF52
#7544B1
#B500FF
#00FF78
#FF6E41
#005F39
#6B6882
#5FAD4E
#A75740
#A5FFD2
#FFB167
#009BFF
#E85EBE

Оновлення: Я продовжував це приблизно місяць, отже, з 1024 грубими силами. 1024

public static final String[] indexcolors = new String[]{
        "#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
        "#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
        "#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
        "#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
        "#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
        "#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
        "#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
        "#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
        "#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
        "#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
        "#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
        "#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
        "#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C",
        "#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800",
        "#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51",
        "#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58",
        "#7A7BFF", "#D68E01", "#353339", "#78AFA1", "#FEB2C6", "#75797C", "#837393", "#943A4D",
        "#B5F4FF", "#D2DCD5", "#9556BD", "#6A714A", "#001325", "#02525F", "#0AA3F7", "#E98176",
        "#DBD5DD", "#5EBCD1", "#3D4F44", "#7E6405", "#02684E", "#962B75", "#8D8546", "#9695C5",
        "#E773CE", "#D86A78", "#3E89BE", "#CA834E", "#518A87", "#5B113C", "#55813B", "#E704C4",
        "#00005F", "#A97399", "#4B8160", "#59738A", "#FF5DA7", "#F7C9BF", "#643127", "#513A01",
        "#6B94AA", "#51A058", "#A45B02", "#1D1702", "#E20027", "#E7AB63", "#4C6001", "#9C6966",
        "#64547B", "#97979E", "#006A66", "#391406", "#F4D749", "#0045D2", "#006C31", "#DDB6D0",
        "#7C6571", "#9FB2A4", "#00D891", "#15A08A", "#BC65E9", "#FFFFFE", "#C6DC99", "#203B3C",
        "#671190", "#6B3A64", "#F5E1FF", "#FFA0F2", "#CCAA35", "#374527", "#8BB400", "#797868",
        "#C6005A", "#3B000A", "#C86240", "#29607C", "#402334", "#7D5A44", "#CCB87C", "#B88183",
        "#AA5199", "#B5D6C3", "#A38469", "#9F94F0", "#A74571", "#B894A6", "#71BB8C", "#00B433",
        "#789EC9", "#6D80BA", "#953F00", "#5EFF03", "#E4FFFC", "#1BE177", "#BCB1E5", "#76912F",
        "#003109", "#0060CD", "#D20096", "#895563", "#29201D", "#5B3213", "#A76F42", "#89412E",
        "#1A3A2A", "#494B5A", "#A88C85", "#F4ABAA", "#A3F3AB", "#00C6C8", "#EA8B66", "#958A9F",
        "#BDC9D2", "#9FA064", "#BE4700", "#658188", "#83A485", "#453C23", "#47675D", "#3A3F00",
        "#061203", "#DFFB71", "#868E7E", "#98D058", "#6C8F7D", "#D7BFC2", "#3C3E6E", "#D83D66",
        "#2F5D9B", "#6C5E46", "#D25B88", "#5B656C", "#00B57F", "#545C46", "#866097", "#365D25",
        "#252F99", "#00CCFF", "#674E60", "#FC009C", "#92896B", "#1E2324", "#DEC9B2", "#9D4948",
        "#85ABB4", "#342142", "#D09685", "#A4ACAC", "#00FFFF", "#AE9C86", "#742A33", "#0E72C5",
        "#AFD8EC", "#C064B9", "#91028C", "#FEEDBF", "#FFB789", "#9CB8E4", "#AFFFD1", "#2A364C",
        "#4F4A43", "#647095", "#34BBFF", "#807781", "#920003", "#B3A5A7", "#018615", "#F1FFC8",
        "#976F5C", "#FF3BC1", "#FF5F6B", "#077D84", "#F56D93", "#5771DA", "#4E1E2A", "#830055",
        "#02D346", "#BE452D", "#00905E", "#BE0028", "#6E96E3", "#007699", "#FEC96D", "#9C6A7D",
        "#3FA1B8", "#893DE3", "#79B4D6", "#7FD4D9", "#6751BB", "#B28D2D", "#E27A05", "#DD9CB8",
        "#AABC7A", "#980034", "#561A02", "#8F7F00", "#635000", "#CD7DAE", "#8A5E2D", "#FFB3E1",
        "#6B6466", "#C6D300", "#0100E2", "#88EC69", "#8FCCBE", "#21001C", "#511F4D", "#E3F6E3",
        "#FF8EB1", "#6B4F29", "#A37F46", "#6A5950", "#1F2A1A", "#04784D", "#101835", "#E6E0D0",
        "#FF74FE", "#00A45F", "#8F5DF8", "#4B0059", "#412F23", "#D8939E", "#DB9D72", "#604143",
        "#B5BACE", "#989EB7", "#D2C4DB", "#A587AF", "#77D796", "#7F8C94", "#FF9B03", "#555196",
        "#31DDAE", "#74B671", "#802647", "#2A373F", "#014A68", "#696628", "#4C7B6D", "#002C27",
        "#7A4522", "#3B5859", "#E5D381", "#FFF3FF", "#679FA0", "#261300", "#2C5742", "#9131AF",
        "#AF5D88", "#C7706A", "#61AB1F", "#8CF2D4", "#C5D9B8", "#9FFFFB", "#BF45CC", "#493941",
        "#863B60", "#B90076", "#003177", "#C582D2", "#C1B394", "#602B70", "#887868", "#BABFB0",
        "#030012", "#D1ACFE", "#7FDEFE", "#4B5C71", "#A3A097", "#E66D53", "#637B5D", "#92BEA5",
        "#00F8B3", "#BEDDFF", "#3DB5A7", "#DD3248", "#B6E4DE", "#427745", "#598C5A", "#B94C59",
        "#8181D5", "#94888B", "#FED6BD", "#536D31", "#6EFF92", "#E4E8FF", "#20E200", "#FFD0F2",
        "#4C83A1", "#BD7322", "#915C4E", "#8C4787", "#025117", "#A2AA45", "#2D1B21", "#A9DDB0",
        "#FF4F78", "#528500", "#009A2E", "#17FCE4", "#71555A", "#525D82", "#00195A", "#967874",
        "#555558", "#0B212C", "#1E202B", "#EFBFC4", "#6F9755", "#6F7586", "#501D1D", "#372D00",
        "#741D16", "#5EB393", "#B5B400", "#DD4A38", "#363DFF", "#AD6552", "#6635AF", "#836BBA",
        "#98AA7F", "#464836", "#322C3E", "#7CB9BA", "#5B6965", "#707D3D", "#7A001D", "#6E4636",
        "#443A38", "#AE81FF", "#489079", "#897334", "#009087", "#DA713C", "#361618", "#FF6F01",
        "#006679", "#370E77", "#4B3A83", "#C9E2E6", "#C44170", "#FF4526", "#73BE54", "#C4DF72",
        "#ADFF60", "#00447D", "#DCCEC9", "#BD9479", "#656E5B", "#EC5200", "#FF6EC2", "#7A617E",
        "#DDAEA2", "#77837F", "#A53327", "#608EFF", "#B599D7", "#A50149", "#4E0025", "#C9B1A9",
        "#03919A", "#1B2A25", "#E500F1", "#982E0B", "#B67180", "#E05859", "#006039", "#578F9B",
        "#305230", "#CE934C", "#B3C2BE", "#C0BAC0", "#B506D3", "#170C10", "#4C534F", "#224451",
        "#3E4141", "#78726D", "#B6602B", "#200441", "#DDB588", "#497200", "#C5AAB6", "#033C61",
        "#71B2F5", "#A9E088", "#4979B0", "#A2C3DF", "#784149", "#2D2B17", "#3E0E2F", "#57344C",
        "#0091BE", "#E451D1", "#4B4B6A", "#5C011A", "#7C8060", "#FF9491", "#4C325D", "#005C8B",
        "#E5FDA4", "#68D1B6", "#032641", "#140023", "#8683A9", "#CFFF00", "#A72C3E", "#34475A",
        "#B1BB9A", "#B4A04F", "#8D918E", "#A168A6", "#813D3A", "#425218", "#DA8386", "#776133",
        "#563930", "#8498AE", "#90C1D3", "#B5666B", "#9B585E", "#856465", "#AD7C90", "#E2BC00",
        "#E3AAE0", "#B2C2FE", "#FD0039", "#009B75", "#FFF46D", "#E87EAC", "#DFE3E6", "#848590",
        "#AA9297", "#83A193", "#577977", "#3E7158", "#C64289", "#EA0072", "#C4A8CB", "#55C899",
        "#E78FCF", "#004547", "#F6E2E3", "#966716", "#378FDB", "#435E6A", "#DA0004", "#1B000F",
        "#5B9C8F", "#6E2B52", "#011115", "#E3E8C4", "#AE3B85", "#EA1CA9", "#FF9E6B", "#457D8B",
        "#92678B", "#00CDBB", "#9CCC04", "#002E38", "#96C57F", "#CFF6B4", "#492818", "#766E52",
        "#20370E", "#E3D19F", "#2E3C30", "#B2EACE", "#F3BDA4", "#A24E3D", "#976FD9", "#8C9FA8",
        "#7C2B73", "#4E5F37", "#5D5462", "#90956F", "#6AA776", "#DBCBF6", "#DA71FF", "#987C95",
        "#52323C", "#BB3C42", "#584D39", "#4FC15F", "#A2B9C1", "#79DB21", "#1D5958", "#BD744E",
        "#160B00", "#20221A", "#6B8295", "#00E0E4", "#102401", "#1B782A", "#DAA9B5", "#B0415D",
        "#859253", "#97A094", "#06E3C4", "#47688C", "#7C6755", "#075C00", "#7560D5", "#7D9F00",
        "#C36D96", "#4D913E", "#5F4276", "#FCE4C8", "#303052", "#4F381B", "#E5A532", "#706690",
        "#AA9A92", "#237363", "#73013E", "#FF9079", "#A79A74", "#029BDB", "#FF0169", "#C7D2E7",
        "#CA8869", "#80FFCD", "#BB1F69", "#90B0AB", "#7D74A9", "#FCC7DB", "#99375B", "#00AB4D",
        "#ABAED1", "#BE9D91", "#E6E5A7", "#332C22", "#DD587B", "#F5FFF7", "#5D3033", "#6D3800",
        "#FF0020", "#B57BB3", "#D7FFE6", "#C535A9", "#260009", "#6A8781", "#A8ABB4", "#D45262",
        "#794B61", "#4621B2", "#8DA4DB", "#C7C890", "#6FE9AD", "#A243A7", "#B2B081", "#181B00",
        "#286154", "#4CA43B", "#6A9573", "#A8441D", "#5C727B", "#738671", "#D0CFCB", "#897B77",
        "#1F3F22", "#4145A7", "#DA9894", "#A1757A", "#63243C", "#ADAAFF", "#00CDE2", "#DDBC62",
        "#698EB1", "#208462", "#00B7E0", "#614A44", "#9BBB57", "#7A5C54", "#857A50", "#766B7E",
        "#014833", "#FF8347", "#7A8EBA", "#274740", "#946444", "#EBD8E6", "#646241", "#373917",
        "#6AD450", "#81817B", "#D499E3", "#979440", "#011A12", "#526554", "#B5885C", "#A499A5",
        "#03AD89", "#B3008B", "#E3C4B5", "#96531F", "#867175", "#74569E", "#617D9F", "#E70452",
        "#067EAF", "#A697B6", "#B787A8", "#9CFF93", "#311D19", "#3A9459", "#6E746E", "#B0C5AE",
        "#84EDF7", "#ED3488", "#754C78", "#384644", "#C7847B", "#00B6C5", "#7FA670", "#C1AF9E",
        "#2A7FFF", "#72A58C", "#FFC07F", "#9DEBDD", "#D97C8E", "#7E7C93", "#62E674", "#B5639E",
        "#FFA861", "#C2A580", "#8D9C83", "#B70546", "#372B2E", "#0098FF", "#985975", "#20204C",
        "#FF6C60", "#445083", "#8502AA", "#72361F", "#9676A3", "#484449", "#CED6C2", "#3B164A",
        "#CCA763", "#2C7F77", "#02227B", "#A37E6F", "#CDE6DC", "#CDFFFB", "#BE811A", "#F77183",
        "#EDE6E2", "#CDC6B4", "#FFE09E", "#3A7271", "#FF7B59", "#4E4E01", "#4AC684", "#8BC891",
        "#BC8A96", "#CF6353", "#DCDE5C", "#5EAADD", "#F6A0AD", "#E269AA", "#A3DAE4", "#436E83",
        "#002E17", "#ECFBFF", "#A1C2B6", "#50003F", "#71695B", "#67C4BB", "#536EFF", "#5D5A48",
        "#890039", "#969381", "#371521", "#5E4665", "#AA62C3", "#8D6F81", "#2C6135", "#410601",
        "#564620", "#E69034", "#6DA6BD", "#E58E56", "#E3A68B", "#48B176", "#D27D67", "#B5B268",
        "#7F8427", "#FF84E6", "#435740", "#EAE408", "#F4F5FF", "#325800", "#4B6BA5", "#ADCEFF",
        "#9B8ACC", "#885138", "#5875C1", "#7E7311", "#FEA5CA", "#9F8B5B", "#A55B54", "#89006A",
        "#AF756F", "#2A2000", "#576E4A", "#7F9EFF", "#7499A1", "#FFB550", "#00011E", "#D1511C",
        "#688151", "#BC908A", "#78C8EB", "#8502FF", "#483D30", "#C42221", "#5EA7FF", "#785715",
        "#0CEA91", "#FFFAED", "#B3AF9D", "#3E3D52", "#5A9BC2", "#9C2F90", "#8D5700", "#ADD79C",
        "#00768B", "#337D00", "#C59700", "#3156DC", "#944575", "#ECFFDC", "#D24CB2", "#97703C",
        "#4C257F", "#9E0366", "#88FFEC", "#B56481", "#396D2B", "#56735F", "#988376", "#9BB195",
        "#A9795C", "#E4C5D3", "#9F4F67", "#1E2B39", "#664327", "#AFCE78", "#322EDF", "#86B487",
        "#C23000", "#ABE86B", "#96656D", "#250E35", "#A60019", "#0080CF", "#CAEFFF", "#323F61",
        "#A449DC", "#6A9D3B", "#FF5AE4", "#636A01", "#D16CDA", "#736060", "#FFBAAD", "#D369B4",
        "#FFDED6", "#6C6D74", "#927D5E", "#845D70", "#5B62C1", "#2F4A36", "#E45F35", "#FF3B53",
        "#AC84DD", "#762988", "#70EC98", "#408543", "#2C3533", "#2E182D", "#323925", "#19181B",
        "#2F2E2C", "#023C32", "#9B9EE2", "#58AFAD", "#5C424D", "#7AC5A6", "#685D75", "#B9BCBD",
        "#834357", "#1A7B42", "#2E57AA", "#E55199", "#316E47", "#CD00C5", "#6A004D", "#7FBBEC",
        "#F35691", "#D7C54A", "#62ACB7", "#CBA1BC", "#A28A9A", "#6C3F3B", "#FFE47D", "#DCBAE3",
        "#5F816D", "#3A404A", "#7DBF32", "#E6ECDC", "#852C19", "#285366", "#B8CB9C", "#0E0D00",
        "#4B5D56", "#6B543F", "#E27172", "#0568EC", "#2EB500", "#D21656", "#EFAFFF", "#682021",
        "#2D2011", "#DA4CFF", "#70968E", "#FF7B7D", "#4A1930", "#E8C282", "#E7DBBC", "#A68486",
        "#1F263C", "#36574E", "#52CE79", "#ADAAA9", "#8A9F45", "#6542D2", "#00FB8C", "#5D697B",
        "#CCD27F", "#94A5A1", "#790229", "#E383E6", "#7EA4C1", "#4E4452", "#4B2C00", "#620B70",
        "#314C1E", "#874AA6", "#E30091", "#66460A", "#EB9A8B", "#EAC3A3", "#98EAB3", "#AB9180",
        "#B8552F", "#1A2B2F", "#94DDC5", "#9D8C76", "#9C8333", "#94A9C9", "#392935", "#8C675E",
        "#CCE93A", "#917100", "#01400B", "#449896", "#1CA370", "#E08DA7", "#8B4A4E", "#667776",
        "#4692AD", "#67BDA8", "#69255C", "#D3BFFF", "#4A5132", "#7E9285", "#77733C", "#E7A0CC",
        "#51A288", "#2C656A", "#4D5C5E", "#C9403A", "#DDD7F3", "#005844", "#B4A200", "#488F69",
        "#858182", "#D4E9B9", "#3D7397", "#CAE8CE", "#D60034", "#AA6746", "#9E5585", "#BA6200"
    };

8
ІМХО набагато краще прийнятої відповіді. І +1 для наочних прикладів та попередньо обчислених списків!
Griddo

1
Я також провев вичерпний пошук, щоб максимізувати CIEDE2000 між доданим кольором та кольорами, які вже є в наборі, з чорно-білим як заздалегідь визначеними кольорами. Як і ти, я рано отримую два "відтінки шкіри": # ff9d25 (має тенденцію до помаранчевого) і # ffb46c (має тенденцію до рожевого). Я думаю, що вони виглядають дуже схожими, тому, можливо, CIEDE2000 і не такий хороший показник різниці кольорів. На даний момент немає нічого кращого там, хоча. Спокусливо почати робити власні експерименти з помітною різницею, можливо, спочатку із сіткою sRGB 16x16x16 ...
Оллі Ніємітало,

Я піднявся до 1024, але це зайняло у мене більше місяця. Ви можете однаково запустити це з іншими наборами кольорів, у мене їх безліч різноманітних гамм. І насправді CIEDE2000 насправді найкращий. Однією з виправлень у dE2k є колір шкіри, вони виглядають для нас більш різними і важливі для багатьох функцій. Стандартний dE має їх більше, ніж вони насправді повинні бути. А абрикосовий і тьмяно-жовтий виглядають досить несхоже. godsnotwheregodsnot.blogspot.com/2012/09 / ...
Tatarize

Єдиним серйозним покращенням, яке я міг побачити, було б статичні списки. Знайти найдальший від усіх інших кольорів насправді може бути не оптимальним, якщо вам потрібно лише 20 кольорів. Ви могли б отримати кращі результати, якщо зробили кластеризацію і виявили 20 кольорів, для яких відстань кольорів максимально збільшена між усіма кольорами в наборі. Це може насправді перетворитися на продавця-подорожнього, а груба форсинг (2 ^ 24) ^ 20 через дуже дорогий алгоритм кольорової відстані може зайняти досить багато часу. Хоча хороший алгоритм кластеризації може швидко дати вам хороший результат.
Татарізувати

1
Насправді під час перевірки я, можливо, навіть не зробив цього протягом останніх двох на розміщеному графіку. Він виробляв його і створював щоразу новий образ. Але на той момент це був фактично довгий блок часу для кожного нового кольору. І повне розуміння того, що вони не були надзвичайно корисними.
Татарізувати

24

Я виклав сторінку в Інтернеті для процедурного генерування візуально різних кольорів:
http://phrogz.net/css/distinct-colors.html

На відміну від інших відповідей тут, які рівномірно перетинають простір RGB або HSV (де існує нелінійна залежність між значеннями осі та перцептивними різницями ), моя сторінка використовує стандартний CMI (I: c) алгоритм кольорової відстані , щоб запобігти надто двом кольорам візуально близько.

Кінцева вкладка сторінки дозволяє сортувати значення кількома способами, а потім чергувати їх (впорядковане перемішування), щоб отримати дуже чіткі кольори, розташовані поруч.

На момент написання статті він працює добре лише в Chrome і Safari, з обробкою для Firefox; він використовує в інтерфейсі повзунки діапазону HTML5, які IE9 та Firefox ще не підтримують.


1
Це чудовий інструмент, дякую вам за його створення. Я використав його для створення 145 різних кольорів, і я дуже задоволений результатами, створеними вашим інструментом різних кольорів.
Малахі

Ідея звучить добре, але я не розумію, як працює інтерфейс. Скажімо, я хочу сформувати 64 кольори, віддалені в просторі L a b, яке налаштування слід використовувати? Я не можу отримати більше 50 кольорів.
віп

1
@wil Налаштування за замовчуванням на сторінці "Лабораторія" починають із 480 кольорів на вибір. Коли ви переходите на вкладку Уточнити, відрегулюйте поріг, щоб бачити більше або менше зразків.
Фрогц

З 36 кольорами я все ще отримую кілька дуже схожих кольорів.
Немо

8

Я думаю, що простір HSV (або HSL) має тут більше можливостей. Якщо ви не заперечуєте над додатковим перетворенням, досить легко пройти всі кольори, просто повернувши значення відтінку. Якщо цього недостатньо, ви можете змінити значення насиченості / значення / освітленості і знову пройти обертання. Або ви завжди можете змістити значення відтінку або змінити кут "кроку" і повернути більше разів.


2
Однак зауважте, що навіть рівномірне крокування по відтінку виробляє субідеальне перцептивне розділення.
Фрогц

4

У попередніх рішеннях RGB є недолік. Вони не використовують весь колірний простір, оскільки використовують значення кольору і 0 для каналів:

#006600
#330000
#FF00FF

Натомість вони повинні використовувати всі можливі значення кольорів для створення змішаних кольорів, які можуть мати до 3 різних значень у колірних каналах:

#336600
#FF0066
#33FF66

Використовуючи повний колірний простір, ви можете генерувати більш чіткі кольори. Наприклад, якщо у вас є 4 значення на канал, то можна створити 4 * 4 * 4 = 64 кольори. За іншої схеми лише 4 * 7 + 1 = 29 можна генерувати кольорів.

Якщо вам потрібно N кольорів, тоді кількість значень на канал потрібна: ceil (cube_root (N))

Потім ви можете визначити можливі значення (діапазон 0-255) (python):

max = 255
segs = int(num**(Decimal("1.0")/3))
step = int(max/segs)
p = [(i*step) for i in xrange(segs)]
values = [max]
values.extend(p)

Тоді ви можете переглядати кольори RGB (це не рекомендується):

total = 0
for red in values:
  for green in values:
    for blue in values:
      if total <= N:
        print color(red, green, blue)
      total += 1

Вкладені цикли працюватимуть, але не рекомендуються, оскільки вони надають перевагу синьому каналу, а результуючі кольори не матимуть достатньо червоного (N, швидше за все, буде меншим за кількість усіх можливих значень кольору).

Ви можете створити кращий алгоритм для циклів, де кожен канал обробляється однаково, а більш чіткі значення кольорів віддаються перевазі малим.

У мене є рішення, але я не хотів його публікувати, оскільки воно не найпростіше зрозуміти чи ефективно. Але ви можете переглянути рішення, якщо вам дуже хочеться.

Ось зразок 64 згенерованих кольорів: 64 кольори


3

Мені потрібна була та сама функціональність, у простій формі.

Мені потрібно було створити якомога унікальніші кольори із зростаючого значення індексу.

Ось код у C # (Будь-яка інша мовна реалізація повинна бути дуже схожою)

Механізм дуже простий

  1. Шаблон color_writers генерується із значень indexA від 0 до 7.

  2. Для індексів <8 ці кольори = color_writer [indexA] * 255.

  3. Для індексів від 8 до 15 ці кольори = color_writer [indexA] * 255 + (color_writer [indexA + 1]) * 127

  4. Для індексів від 16 до 23 ці кольори = color_writer [indexA] * 255 + (color_writer [indexA + 1]) * 127 + (color_writer [indexA + 2]) * 63

І так далі:

Генератор кольорів Rand

    private System.Drawing.Color GetRandColor(int index)
    {
        byte red = 0;
        byte green = 0;
        byte blue = 0;

        for (int t = 0; t <= index / 8; t++)
        {
            int index_a = (index+t) % 8;
            int index_b = index_a / 2;

            //Color writers, take on values of 0 and 1
            int color_red = index_a % 2;
            int color_blue = index_b % 2;
            int color_green = ((index_b + 1) % 3) % 2;

            int add = 255 / (t + 1);

            red = (byte)(red+color_red * add);
            green = (byte)(green + color_green * add);
            blue = (byte)(blue + color_blue * add);
        }

        Color color = Color.FromArgb(red, green, blue);
        return color;
    }

Примітка: Щоб уникнути створення яскравих і важко помітних кольорів (у цьому прикладі: жовтий на білому тлі), ви можете змінити його за допомогою рекурсивного циклу:

    int skip_index = 0;
    private System.Drawing.Color GetRandColor(int index)
    {
        index += skip_index;
        byte red = 0;
        byte green = 0;
        byte blue = 0;

        for (int t = 0; t <= index / 8; t++)
        {
            int index_a = (index+t) % 8;
            int index_b = index_a / 2;

            //Color writers, take on values of 0 and 1
            int color_red = index_a % 2;
            int color_blue = index_b % 2;
            int color_green = ((index_b + 1) % 3) % 2;

            int add = 255 / (t + 1);

            red = (byte)(red + color_red * add);
            green = (byte)(green + color_green * add);
            blue = (byte)(blue + color_blue * add);
        }

        if(red > 200 && green > 200)
        {
            skip_index++;
            return GetRandColor(index);
        }

        Color color = Color.FromArgb(red, green, blue);
        return color;
    }

1

Я б почав із заданої яскравості 100% і спочатку обійшов основні кольори:

FF0000, 00FF00, 0000FF

то комбінації

FFFF00, FF00FF, 00FFFF

далі, наприклад, зменшити вдвічі яскравість і зробити те саме. Дійсно не дуже багато чітко виражених кольорів, після них я б почав змінювати ширину лінії та робити пунктирні / пунктирні лінії тощо.


1
+1 за чудову пропозицію використовувати різні стилі ліній замість кольорів.
Iiridayn

1

Я реалізував цей алгоритм коротше

void ColorValue::SetColorValue( double r, double g, double b, ColorType myType )
{
   this->c[0] = r;
   this->c[1] = g;
   this->c[2] = b;

   this->type = myType;
}


DistinctColorGenerator::DistinctColorGenerator()
{
   mFactor = 255;
   mColorsGenerated = 0;
   mpColorCycle = new ColorValue[6];
   mpColorCycle[0].SetColorValue( 1.0, 0.0, 0.0, TYPE_RGB);
   mpColorCycle[1].SetColorValue( 0.0, 1.0, 0.0, TYPE_RGB);
   mpColorCycle[2].SetColorValue( 0.0, 0.0, 1.0, TYPE_RGB);
   mpColorCycle[3].SetColorValue( 1.0, 1.0, 0.0, TYPE_RGB);
   mpColorCycle[4].SetColorValue( 1.0, 0.0, 1.0, TYPE_RGB);
   mpColorCycle[5].SetColorValue( 0.0, 1.0, 1.0, TYPE_RGB);
}

//----------------------------------------------------------

ColorValue DistinctColorGenerator::GenerateNewColor()
{
   int innerCycleNr = mColorsGenerated % 6;
   int outerCycleNr = mColorsGenerated / 6;
   int cycleSize = pow( 2, (int)(log((double)(outerCycleNr)) / log( 2.0 ) ) );
   int insideCycleCounter = outerCycleNr % cyclesize;

   if ( outerCycleNr == 0)
   {
      mFactor = 255;
   }
   else
   {
      mFactor = ( 256 / ( 2 * cycleSize ) ) + ( insideCycleCounter * ( 256 / cycleSize ) );
   }

   ColorValue newColor = mpColorCycle[innerCycleNr] * mFactor;

   mColorsGenerated++;
   return newColor;
}

0

Ви також можете уявити кольоровий простір як усі комбінації з трьох чисел від 0 до 255 включно. Це базове представлення числа від 0 до 255 ^ 3, змушене мати три знаки після коми (додайте нулі до кінця, якщо потрібно).

Отже, щоб сформувати x кількість кольорів, ви обчислили б x рівномірно розміщені відсотки, від 0 до 100. Отримайте числа, помноживши ці відсотки на 255 ^ 3, перетворивши ці числа на основу 255 і додавши нулі, як уже згадувалося раніше.

Базовий алгоритм перетворення для довідки (у псевдокоді, який досить близький до C #):

int num = (number to convert);
int baseConvert = (desired base, 255 in this case);
(array of ints) nums = new (array of ints);
int x = num;
double digits = Math.Log(num, baseConvert); //or ln(num) / ln(baseConvert)
int numDigits = (digits - Math.Ceiling(digits) == 0 ? (int)(digits + 1) : (int)Math.Ceiling(digits)); //go up one if it turns out even
for (int i = 0; i < numDigits; i++)
{
  int toAdd = ((int)Math.Floor(x / Math.Pow((double)convertBase, (double)(numDigits - i - 1))));
  //Formula for 0th digit: d = num / (convertBase^(numDigits - 1))
  //Then subtract (d * convertBase^(numDigits - 1)) from the num and continue
  nums.Add(toAdd);
  x -= toAdd * (int)Math.Pow((double)convertBase, (double)(numDigits - i - 1));
}
return nums;

Можливо, вам також доведеться щось зробити, щоб трохи зменшити діапазон, щоб уникнути білого і чорного, якщо хочете. Ці цифри насправді не є плавною кольоровою шкалою, але вони генерують окремі кольори, якщо їх не надто багато.

Це питання має більше на основі базового перетворення в .NET.


0

для отримання n-го кольору. Просто такого коду було б достатньо. Це я використовую у своїй проблемі кластеризації opencv. Це створить різні кольори при зміні кольорів.

for(int col=1;col<CLUSTER_COUNT+1;col++){
switch(col%6)
   {
   case 1:cout<<Scalar(0,0,(int)(255/(int)(col/6+1)))<<endl;break;
   case 2:cout<<Scalar(0,(int)(255/(int)(col/6+1)),0)<<endl;break;
    case 3:cout<<Scalar((int)(255/(int)(col/6+1)),0,0)<<endl;break;
    case 4:cout<<Scalar(0,(int)(255/(int)(col/6+1)),(int)(255/(int)(col/6+1)))<<endl;break;
    case 5:cout<<Scalar((int)(255/(int)(col/6+1)),0,(int)(255/(int)(col/6+1)))<<endl;break;
    case 0:cout<<Scalar((int)(255/(int)(col/6)),(int)(255/(int)(col/6)),0)<<endl;break;
   }
}

0

Якщо комусь потрібно створити випадковий середній і високий темний колір для білого переднього плану в C #, ось код.

[DllImport("shlwapi.dll")]
public static extern int ColorHLSToRGB(int H, int L, int S);

public static string GetRandomDarkColor()
{
    int h = 0, s = 0, l = 0;
    h = (RandomObject.Next(1, 2) % 2 == 0) ? RandomObject.Next(0, 180) : iApp.RandomObject.Next(181, 360);
    s = RandomObject.Next(90, 160);
    l = RandomObject.Next(80, 130);

    return System.Drawing.ColorTranslator.FromWin32(ColorHLSToRGB(h, l, s)).ToHex();
}

private static string ToHex(this System.Drawing.Color c)
{
    return "#" + c.R.ToString("X2") + c.G.ToString("X2") + c.B.ToString("X2");
}

Ви можете замінити RandomObjectвласним Randomоб’єктом класу.


-3

Ви можете отримати випадковий набір зі своїх 3 255 значень і порівняти його з останнім набором із 3 значень, переконавшись, що кожен із них принаймні на X віддалений від старих значень, перш ніж використовувати їх.

СТАРИЙ: 190, 120, 100

НОВЕ: 180, 200, 30

Якщо X = 20, тоді новий набір буде відновлений знову.


Мені майже цікаво розрахуватись і підрахувати, скільки часу в середньому пройде, перш ніж цей алгоритм перейде в нескінченний цикл, коли подальших рішень неможливо.
Татарізувати

Хм Як не дивно, ваша відповідь говорить, що будь-яке значення r, занадто наближене до іншого значення R, призведе до регенерації, воно в кращому випадку менше 12. Хоча це, як не дивно, називає червоний і синій кольори занадто близькими, тому що обидва мають зелений 0, який не перевищує 20. Я маю на увазі буквально ваш приклад говорить: colorcodehex.com/be7864 colorcodehex.com/b4c81e Надто близько один до одного і їх слід регенерувати.
Татарізувати
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.