BLOG main image
FunnyPR (32)
OpenGL (20)
PatternRecognition (7)
Tips (2)
XML (1)
DataMining (1)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
2014. 7. 29. 17:23

 Generate distinctly different RGB colors in graphs


그래프에 뚜렷한 구분을 가지는 RGB 색상 만들기 

- 머.... 그래프 작업에 필수적인 요소이지만 미뤄왔던 일이다. 오늘도 할일은 있지만 해결하고 가야겠지...돈도 안주는 일인데 하자니...땍!!!

우선 진행해 보자. 먼저 자료를 찾았다. 

http://stackoverflow.com/questions/309149/generate-distinctly-different-rgb-colors-in-graphs

위 링크를 따라가보면 이글 제목과 같이 질문을 올렸다. 


질문을 정리하면 

"아놔 랜덤으로 뚜렷하게 구분되는 RGB 색상을 어떻게 만들어??"


답변을 보면 다음과 같다. 

You have three colour channels 0 to 255 R, G and B.

너는 3개의 RGB 채널을 가지고 있어

First go through: 먼저 다음과 같이 가자

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

Then go through: 그리고 다음과 같이 가는거야

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

Then divide by 2 => 128 and start again: 그리고 2로 나누자고 ==> 128이지? 그럼 또 나눠

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

Divide by 2 => 64 : 자 그럼 64야 

Next time add 64 to 128 => 192 : 자 다음으로 64와 128을 더해 그럼 192잖아 

follow the pattern.위와 같은 패턴을 따라봐

Straightforward to program and gives you fairly distinct colours. ; 프로그램하는것도 간단하고, 너에게 뚜렷한 RGB 색상을 주게 될꺼얌~~~

EDIT: Request for code sample: 코드 샘플에 대한 요청(유후~~~)

Also - adding in the additional pattern as below if gray is an acceptable colour:

그레이 색상을 허용하려면 아래와 같이 추가적인 패턴을 넣어봐

255, 255, 255
128, 128, 128 

There are a number of ways you can handle generating these in code.

여기 코드에는 RGB 색상을 만들기 위해 여러가지 방법이 있다오~~

The Easy Way:: 쉬운 방법이야!!!

If you can guarantee that you will never need more than a fixed number of colours, just generate an array of colours following this pattern and use those: 그냥 배열을 만들어서 쓰셈~~!!

    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", 
    };

The Hard Way:: 흠 좀 어렵겠군!!! +___+ 췌 

If you don't know how many colours you are going to need, the code below will generate up to 896 colours using this pattern. (896 = 256 * 7 / 2) 256 is the colour space per channel, we have 7 patterns and we stop before we get to colours separated by only 1 colour value.

얼마나 많은 RGB 컬러가 필요할지 모르지? 아래 코드는 896개의 색상을 만드는 소스 코드야~. 256은 채널당 색공간(colour space) 이야, 우리는 7개의 패턴을 가지고 있엉, 우리는 오직 1 색공간에 의해 나뉘지는  색을 가지기 전에 그만 둘것이야(먼 예기야~ 흠 아무래도 나뉘지지 않게 되면 정지 요런 느낌!!???) 소스 코드 보면 분명해지겠지 

I've probably made harder work of this code than I needed to. First, there is an intensity generator which starts at 255, then generates the values as per the pattern described above. The pattern generator just loops through the seven colour patterns.

나도 이게 필요해서 열심히 만들었어. 처음, intensity generator(255에서 시작하는)가 있어, 그리고 위에 묘사된 패턴별로 값들을 만들엉. 패턴 발생기는 7개의 패턴을 따라 루프를 도는거만 하징..

아놔 C# 이넹 난 C/C++ 코드가 필요한뎅 ㅠㅠ 으아앙

할 수 없지... 변환해서 써보자 

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;
            }

        }
    }
}





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace RandomDistinctlyRGB
{
    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}";
                defaultthrow 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(thisthis.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;
                }
 
            }
        }
    }
}
 










'Tips' 카테고리의 다른 글

Tip: Scaling a range of numbers with a known min and max value  (0) 2014.05.25