[解決済み] RGBの色が異なるグラフの生成
質問
グラフを作成し、異なるデータセットを表示する場合、通常、色でセットを区別するのが良い方法です。つまり、ある線は赤で、次の線は緑というように。問題は、データセットの数が未知の場合、これらの色をランダムに生成する必要があり、しばしば互いに非常に近い色になってしまうことです (たとえば、緑、薄緑など)。
これをどのように解決し、どのようにはっきりと異なる色を生成することが可能かについて、何かアイデアはありますか。
私は、どんな例でも(あなたがより簡単に見つけるなら、例なしで問題と解決策を議論するのは自由です)C#とRGBベースの色であったなら、素晴らしいです。
どのように解決するのですか?
0~255 R、G、Bの3つのカラーチャンネルを持っています。
最初に通過する
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 で開始し、前述のパターンに従って値を生成する強度ジェネレーターがあります。パターン ジェネレーターは、7 つのカラー パターンをループするだけです。
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;
}
}
}
}
関連
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】5.7.57 SMTP - MAIL FROMエラー時に匿名メールを送信するためにクライアントが認証されない
-
[解決済み】aspNetCore 2.2.0 - AspNetCoreModuleV2 エラー
-
[解決済み] JavaScriptでランダムな文字列/文字を生成する
-
[解決済み] 乱数(int)を生成する方法を教えてください。
-
[解決済み] JavaScriptで2つの数値の間の乱数を生成する
-
[解決済み] 英数字のランダムな文字列を生成する方法
-
[解決済み] 0から9までのランダムな整数を生成する
-
[解決済み] ランダムな英数字の文字列を生成するにはどうすればよいですか?
-
[解決済み] パワーメーターの赤と緑の間の色を生成する?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】SmtpException: トランスポート接続からデータを読み取れません:net_io_connectionclosed
-
[解決済み】ソケットのアドレス(プロトコル/ネットワークアドレス/ポート)は、通常1つしか使用できない?
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み】Swashbuckle/Swagger + ASP.Net Core: "Failed to load API definition" (API定義の読み込みに失敗しました
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み】「...は'型'であり、与えられたコンテキストでは有効ではありません」を解決するにはどうすればよいですか?(C#)
-
[解決済み】ユーザー設定値を別のユーザー設定値で設定する
-
[解決済み】N個の「はっきりした」色を自動的に生成するには?
-
[解決済み] JavaScriptで文字列をもとに16進数の色を作成する
-
[解決済み] .NETで10進数を任意の進数に変換する最速の方法とは?