生成随机颜色的问题-asp.net和c#
我需要在asp.net应用程序中生成十六进制值的随机颜色来绘制图形生成随机颜色的问题-asp.net和c#,c#,asp.net,colors,C#,Asp.net,Colors,我需要在asp.net应用程序中生成十六进制值的随机颜色来绘制图形 Random random = new Random(); color = String.Format("#{0:X6}", random.Next(0x1000000)); 上述代码生成随机颜色代码。但我的问题是,有一段时间,它产生的颜色几乎与以前的颜色相似。因为我使用它的图形目的,我需要生成完全不同的颜色。有什么想法吗……试试看 Color.FromArgb(random.Next(0, 255), random.N
Random random = new Random();
color = String.Format("#{0:X6}", random.Next(0x1000000));
上述代码生成随机颜色代码。但我的问题是,有一段时间,它产生的颜色几乎与以前的颜色相似。因为我使用它的图形目的,我需要生成完全不同的颜色。有什么想法吗……试试看
Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));
--编辑--
根据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));
}
}
用法:
colorRandom.GetNext();
Random r=new Random();
var newCol=(r.Next(0256)我看的代码不够多,但如果我对代码的结构猜测正确,这应该会有所帮助……它应该澄清为什么数字是相同的,或者接近它,因为我有一个类似的问题,下面是我如何解决它的,以及为什么我认为这是解决方案
我有一些生成随机数的代码,看起来像这样(大大简化了)
当执行此操作时,它实际上为循环的一部分创建了完全相同的数字(比如8次迭代),然后切换到一个新的数字,重复9次迭代,等等。我将其更改为如下所示:
Random r = new Random();
for (some loop logic)
{
int myRandomNumber = Random.Next()
}
我相信其他人会说得更好,但是通过在循环外声明Random,Random类的实例能够跟踪生成的最后一个随机数,并确保下一个随机数实际上是随机数每次迭代都会创建一个新的随机对象,所以它只使用任何逻辑(我假设是基于时间的)来生成一个随机数,而不知道不同的实例刚刚生成了相同的数
男孩,我希望这是有意义的…现在已经晚了,我没有解释清楚,但我认为你的问题可能是你正在循环逻辑中创建一个随机类的新实例,你需要在循环之外声明它
编辑-添加
本文介绍了这种情况的原因:
我可能误解了这个问题……
如果问题是为了避免随着时间的推移产生类似的颜色序列,请参阅KMan的回答,我认为这是第一个建议,通过从同一个生成器生成所有随机值(而不是每次生成一个新的生成器),可以避免生成与以前使用的生成器具有相同种子的生成器的风险
如果问题是避免在一行中绘制两种“相似”的颜色,那么下面的响应应该可以
- 使用一些数学逻辑(但有一种风险,即使用的函数无法像一个像样的随机数生成器那样覆盖所有可能的颜色光谱)
- 绘制真实的随机颜色,但当它们被认为相似时拒绝它们(并重新尝试)
第二种方法如以下片段所示。
风格是直接的,颜色接受标准有些随意,但这应该是一个好主意。
此外,通过重用单个随机数生成器(RNG),如果每次都以某种方式创建了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);
}
为什么这种方法不能保证在一行中产生两种相似的颜色
函数根据种子生成随机数,只要您重用随机对象。例如,在您的RandomColor类的构造函数中。@KMan:您是对的。但是,从统计上看,没有什么可以阻止您建议的代码段在第二次调用时生成与前一种颜色相似的颜色。确实发生这种情况的概率与同时绘制所有3个组件值的概率相同,正如在OP的代码段中所做的那样。@mjv:否则您将如何生成(*useRandom
*)它?请参见我的编辑。@KMan。重用随机生成器只能确保[出于某些奇怪的原因]新生成的生成器没有相同的种子,因此生成相同的序列。为了防止在一行中生成两种相似的颜色,必须a)测试相似性并重新绘制,或者b)对各种组件使用特定的数学运算。然而,后一个选项可能会减少可能访问的颜色列表。为什么这种方法不能确保在一行中生成两种相似的颜色?@Mjv:如果在同一时间窗口中为每次使用创建一种新的颜色,那么最终将得到几个种子相似的随机对象,结果相同。
Random r = new Random();
for (some loop logic)
{
int myRandomNumber = Random.Next()
}
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);
}