2010-12-03 22 views
5

私は、グラフを描画するために、私のasp.netアプリケーションで進値のランダムな色を生成するために生成する必要があります。問題 - asp.netとC#

Random random = new Random(); 
color = String.Format("#{0:X6}", random.Next(0x1000000)); 

上記のコードは、ランダムなカラーコードを生成します。しかし、私の問題は、それが以前の色とほぼ同じ色を生成するいくつかの時間です。私はグラフの目的のために私は完全に異なる色を生成する必要が使用しているため。任意のアイデア....

答えて

4

私は質問を誤解している可能性が...
同じようなことを避けるための問題のカラーは、時間の経過と共に生成されるKManの回答を参照してください。私は、最初に新しいジェネレータを生成するのではなく、以前に使用された発電機と同じ種子を有する発電機を製造する危険性を回避する。

行に2つの「類似の」色を描かないようにするには、次のような対応が必要です。行の2つの類似色を回避することは、いくつかの数学的なロジックの使用

  • のいずれかを意味し(ただし、使用する機能がまともな乱数発生器として、すべての可能な色のスペクトルをあろうカバーないという危険性がある)
  • は真のランダムな色を描きますが、それらが似ているとみなされたときにそれらを拒否します(そして再試行します)。

第2のアプローチは、次のスニペットに示されているものです。
スタイルは長さで、色の受け入れ基準はやや恣意的ですが、これは良い考えを提供するはずです。
さらに、単一の乱数発生器(RNG)を再利用することにより、1は何とかRNGが毎回作成された、と偶然同じシードを使用した場合のシーケンスを繰り返すの危険を避ける...

const int minTotalDiff = 200; // parameter used in new color acceptance criteria 
    const int okSingleDiff = 100; // id. 

    int prevR, prevG, prevB; // R, G and B components of the previously issued color. 
    Random RandGen = null; 

    public string GetNewColor() 
    { 
     int newR, newG, newB; 

     if (RandGen == null) 
     { 
      RandGen = new Random(); 
      prevR = prevG = prevB = 0; 
     } 

     bool found = false; 
     while (!found) 
     { 
      newR = RandGen.Next(255); 
      newG = RandGen.Next(255); 
      newB = RandGen.Next(255); 

      int diffR = Math.Abs(prevR - newR); 
      int diffG = Math.Abs(prevG - newG); 
      int diffB = Math.Abs(prevB - newB); 

      // we only take the new color if... 
      // Collectively the color components are changed by a certain 
      // minimum 
      // or if at least one individual colors is changed by "a lot". 
      if (diffR + diffG + diffB >= minTotalDiff 
       || diffR >= okSingleDiff 
       || diffR >= okSingleDiff 
       || diffR >= okSingleDiff 
     ) 
      found = true; 
     } 

     prevR = newR; 
     prevG = newG; 
     prevB = newB; 

     return String.Format("#{0:X2}{0:X2}{0:X2}", prevR, prevG, prevB); 
    } 
5

はMJVさんのコメントに応じ

Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)); 

--EDIT--

アップデートをお試しください:

public class RandomColor 
{ 
    Random _random; 
    public RandomColor() 
    { 
     _random = new Random(); 
    } 

    public Color GetNext() 
    { 
     return Color.FromArgb(_random.Next(0, 255), _random.Next(0, 255), _random.Next(0, 255)); 
    } 
} 

用途:

colorRandom.GetNext(); 
+0

を知るには、このリンク? – mjv

+0

'Random()'関数は、***ランダムオブジェクトを再利用する限り、シードに基づいて乱数を生成します。たとえば、あなたのRandomColorクラスのコンストラクタで。 –

+0

@Kman:そうです。しかし、統計的には、2回目に呼び出されたときに前の色と同じ色を生成するためのスニペットを防止するものは何もありません。実際、OPのスニペットで行われているように、3つのすべての値を同時に描画する場合と同じです。 – mjv

1
Random r=new Random(); 
var newCol=(r.Next(0,256)<<16)+(r.Next(0,256)<<8)+(r.Next(0,256)); 

あなたは明るい色をしたい場合、私はあなたのコードを十分に見ることはできませんが、私は、右のコードが構成されているかについて推測している場合、これは役立つはずNext

+1

このアプローチでは、2つの同様の色が連続して生成されないようにするのはなぜですか? – mjv

+0

@Mjv:同じ時間枠内で使用するたびに新しいものを作成する場合は、同じ結果を持つ同じ種子を持つ複数の「ランダム」オブジェクトになります。 –

3

の最小パラメータ引き上げを検討を。私は同様の問題を抱えていたし、ここで私はそれを解決し、なぜ私はこれが解決策だったと思う方法ですので、数字は、同じ、またはそれに近いなぜ...それは明確にすべき。

が、私は、これはそれが実際にループの一部の正確な同じ番号を作成し実行すると(非常に単純化された)このように見えたrandoms

for (some loop logic) 
{ 
    Random r = new Random(); 
    int myRandomNumber = Random.Next() 
} 

を生成したいくつかのコードを持っていた、(8回の繰り返し言う)を切り替えますなど9回の反復ごとに繰り返さ新しい番号に私はそれがこのように見えるように変更することで、それを解決:

Random r = new Random(); 
for (some loop logic) 
{ 
    int myRandomNumber = Random.Next() 
} 

私は他の人がフレーズそれよりよいが、ループの外ランダムを宣言することにより、インスタンスと確信していますランダムクラスの最後のraを追跡することができましたndom番号を生成し、次のものが実際にランダムであることを確認します。 (最初の例のように)ループでそれを持つことにより、各反復は新しいランダムなオブジェクトを作成し、それはちょうど別のインスタンスは、単にそれを生成したことを知らない乱数を生成するために、どのような論理(Iが想定時間ベースの)使用します数。

ボーイ、私が作った感が...それはここでは後半だし、私ははっきりと説明していないんだけど、私はあなたの問題はあなたのループロジックにランダムクラスの新しいインスタンスを作成していることであってもよいことだと思うことを願っていますそれをループの外で宣言する必要があります。

編集 - このような場合は、なぜこの記事ではカバーしてい

を追加しました:

http://geekswithblogs.net/kakaiya/archive/2005/11/27/61273.aspx

+1

+1:あなたは爪を打つ! –