Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem in generating random colors - asp.net and c#

Tags:

c#

asp.net

colors

I need to generate to generate random colors in Hex values in my asp.net application to draw a graph .

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

The above code generates random color codes . But my problem is some time it generate almost similar colors to its previous colors. Because of i am using it for graph purpose i need to generate completely different colors. Any ideas....

like image 467
Null Pointer Avatar asked Dec 03 '10 05:12

Null Pointer


3 Answers

I may have misunderstood the question...
If the issue to avoid similar sequences of colors produced over time, see KMan's response which I think was the first one to suggest that by producing all random values out of the same generator (rather than producing one new generator each time), one avoids the risk of producing a generator with the same seed as a generator previously used.

If the concern is to avoid drawing two "similar" colors in a row, the following response should do. Avoiding two similar colors in a row implies either

  • the use of some mathematical logic (but there is a risk that the functions used would not cover the spectrum of all possible colors as a decent Random Number Generator would)
  • drawing true random colors, but refusing them (and trying anew) when they are deemed to similar.

The second approach is what is illustrated in the following snippet.
The style is longhand, and the color acceptance criteria is somewhat arbitrary but this should provide a good idea.
Furthermore, by reusing a single Random Number Generator (RNG), one avoid the risk of repeating sequences if somehow the RNG was created each time, and by chance the same seed was used...

  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);
  }
like image 106
mjv Avatar answered Sep 29 '22 00:09

mjv


Try

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

--EDIT--

Update upon mjv's comment:

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

Usage:

colorRandom.GetNext();
like image 44
KMån Avatar answered Sep 29 '22 00:09

KMån


I can't see enough of your code, but this should help if I'm guessing right about how the code is structured... it should clarify why the numbers are the same, or close to it, because I had a similar problem and here's how I solved it and why I think this was the solution.

I had some code that generated randoms that looked like this (vastly simplified)

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

When this executed it actually created the exact same numbers for a part of the loop, (say 8 iterations) then switched to a new number repeated for 9 iterations, etc. I solved it by changing it to look like this:

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

I'm sure others will phrase it better, but by declaring the Random outside the loop, the instance of the Random class was able to keep track of the last random number generated, and ensure that the next was actually random. By having it IN the loop (as in the first example) each iteration created a new Random object, so it just used whatever logic (time-based I assume) to generate a random number not knowing that a different instance had just generated the same number.

Boy, I hope that made sense... It's late here, and I'm not explaining clearly, but I think that your issue may be that you're creating a new instance of the random class in your loop logic, and you need to declare it outside the loop.

Edit - added

This article covers why this is the case:

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

like image 43
David Avatar answered Sep 28 '22 22:09

David