2010-12-03 15 views
5

Necesito generar para generar colores aleatorios en valores hexadecimales en mi aplicación asp.net para dibujar un gráfico.Problema al generar colores aleatorios: asp.net yC#

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

El código anterior genera códigos de color aleatorios. Pero mi problema es que en algún momento genera colores casi similares a sus colores anteriores. Debido a que lo estoy usando para fines gráficos, necesito generar colores completamente diferentes. Cualquier idea ....

Respuesta

4

que puede haber entendido mal la pregunta ...
Si el problema para evitar similares secuencias de colores producidos con el tiempo, véase la respuesta de Kman que creo que fue el primero en sugerir que mediante la producción de todos los valores aleatorios fuera del mismo generador (en lugar de producir un nuevo generador cada vez) , uno evita el riesgo de producir un generador con la misma semilla que un generador usado previamente.

Si la preocupación es evitar dibujar dos colores "similares" seguidos, la siguiente respuesta debería hacer. Evitando dos colores similares en una fila implica ya sea

  • el uso de un poco de lógica matemática (pero existe el riesgo de que las funciones utilizadas no cubriría el espectro de todos los colores posibles como un decente generador de números aleatorios haría)
  • dibujando verdaderos colores aleatorios, pero negándolos (y probándolos de nuevo) cuando se consideran similares.

El segundo enfoque es lo que se ilustra en el siguiente fragmento.
El estilo es a mano, y los criterios de aceptación del color son algo arbitrarios, pero esto debería proporcionar una buena idea.
Por otra parte, mediante la reutilización de un único generador de números aleatorios (RNG), uno a evitar el riesgo de repetir secuencias si de alguna manera el RNG se crea cada vez, y por casualidad se utilizó la misma semilla ...

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

Trate

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

--EDIT--

actualización sobre el comentario de MJV:

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

Uso:

colorRandom.GetNext(); 
+0

¿por qué este enfoque no garantizar la producción de dos colores similares en una fila? – mjv

+0

La función 'Random()' genera números aleatorios basados ​​en la semilla, siempre y cuando *** reutilice *** el objeto Random. Por ejemplo, en el constructor de su clase RandomColor. –

+0

@KMan: tienes razón. Sin embargo, estadísticamente, no hay nada que evite que el fragmento sugiera, cuando se invoca por segunda vez, para producir un color similar al color anterior. De hecho, la probabilidad de que esto ocurra es la misma que cuando se dibujan los 3 valores compoment a la vez, como se hace en el fragmento del OP. – mjv

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

Si quieren colores más brillantes, la posibilidad de elevar el parámetro mínimo de Next

+1

¿Por qué este enfoque garantizaría no producir dos colores similares en una fila? – mjv

+0

@Mjv: Si creara uno nuevo para cada uso en la misma ventana de tiempo, terminará con varios objetos 'Aleatorios' con semillas similares, teniendo el mismo resultado. –

3

no puedo ver lo suficiente de su código, pero esto debería ayudar si estoy acertar acerca de cómo está estructurado el código. .. debería aclarar por qué los números son los mismos, o cerca de él, porque tuve un problema similar y así es cómo lo resolví y por qué creo que esta fue la solución.

que tenían un código que genera randoms que se parecía a esto (muy simplificado)

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

Cuando esto ejecutado realmente creó los mismos números exactos para una parte del bucle, (digamos 8 iteraciones) y luego conmutada a un nuevo número repetido durante 9 iteraciones, etc. lo resuelto cambiándola a tener este aspecto:

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

estoy seguro de que otros frase que mejor, pero si se declara al azar fuera del bucle, la instancia de la clase Random fue capaz de realizar un seguimiento de la última ra número de ndom generado, y asegurarse de que el siguiente fuera realmente aleatorio. Al tenerlo en el ciclo (como en el primer ejemplo) cada iteración creó un nuevo objeto Aleatorio, por lo que simplemente usó cualquier lógica (basada en el tiempo, supongo) para generar un número aleatorio sin saber que una instancia diferente acababa de generar el mismo número.

Muchacho, espero que tenga sentido ... Ya es tarde, y no estoy explicando claramente, pero creo que su problema puede ser que está creando una nueva instancia de la clase aleatoria en su lógica de bucle y debes declararlo fuera del ciclo.

Editar - añadió

Este artículo cubre por qué este es el caso:

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

+1

+1: ¡Has dado en el clavo! –

Cuestiones relacionadas