gpt4 book ai didi

c - 为什么在使用 rand() 时会得到这种特殊的颜色模式?

转载 作者:太空狗 更新时间:2023-10-29 16:14:09 25 4
gpt4 key购买 nike

我尝试创建一个图像文件,如下所示:

uint8_t raw_r[pixel_width][pixel_height];
uint8_t raw_g[pixel_width][pixel_height];
uint8_t raw_b[pixel_width][pixel_height];
uint8_t blue(uint32_t x, uint32_t y)
{
return (rand()%2)? (x+y)%rand() : ((x*y%1024)%rand())%2 ? (x-y)%rand() : rand();
}
uint8_t green(uint32_t x, uint32_t y)
{
return (rand()%2)? (x-y)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();
}
uint8_t red(uint32_t x, uint32_t y)
{
return (rand()%2)? (y-x)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand();
}

for (y=0; y<pixel_height; ++y)
{
for (x=0; x<pixel_width; ++x)
{
raw_b[x][y]=blue(x, y);
raw_g[x][y]=green(x, y);
raw_r[x][y]=red(x, y);
}
}

我希望得到一些随机的东西(白噪声)。然而,输出很有趣:



你知道原因吗?

编辑

现在,很明显它与 rand()无关。 .

也试试这个代码:
for (x=0; x<pixel_width; ++x)
for (y=0; y<pixel_height; ++y)
{
r[x][y] = (x+y);
g[x][y] = (y-x);
/* b[x][y] = rand()%2? x : y; */
}

最佳答案

我最初打算和其他人一样得到相同的答案,并将其归结为 rand() 的问题。 .但是,我认为这样做更好,而是分析了您的数学实际产生的分布。

TL;DR:您看到的模式与底层随机数生成器无关,而仅仅是由于您的程序处理数字的方式。

我会坚持你的蓝色功能,因为它们都很相似。

uint8_t blue(uint32_t x, uint32_t y) {
return (rand() % 2) ? (x + y) % rand() :
((x * y % 1024) % rand()) % 2 ? (x - y) % rand() :
rand();
}

每个像素值是从以下三个函数之一中选择的: (x + y) % rand() , (x - y) % rand() , 和 rand() ;

让我们来看看这些单独产生的图像。
  • rand()

  • 这就是您所期望的,只是噪音。称之为“图像 C”

    enter image description here

  • (x + y) % rand()

  • 在这里,您将像素坐标相加,并从除以随机数中得到余数。如果图像是 1024x1024,那么总和在 [0-2046] 范围内。您所使用的随机数在 [0,RAND_MAX] 范围内,其中 RAND_MAX 至少为 32k,在某些系统上为 20 亿。换句话说,剩下的不只是 (x + y) 的可能性最多为 16 分之一。 .所以在大多数情况下,这个函数只会产生一个向 +x +y 方向增加蓝色的梯度。

    但是,您只使用了最低的 8 位,因为您返回了 uint8_t ,因此您将拥有 256 像素宽的渐变条纹。

    称之为“图像 A”

    enter image description here

  • (x - y) % rand()

  • 在这里你做一些类似的事情,但用减法。只要 x 大于 y,您就会得到与上一张图像类似的东西。但是当 y 更大时,结果是一个非常大的数,因为 xy是无符号的(负结果环绕到无符号类型范围的顶部),然后是 % rand()开始,您实际上会听到噪音。

    称之为“图像 B”

    enter image description here

    最终图像中的每个像素都是使用函数 rand() % 2 从这三个图像之一中获取的。和 ((x * y % 1024) % rand()) % 2 .其中第一个可以理解为以 50% 的概率进行选择(忽略 rand() 及其低位的问题。)

    这是 rand() % 2 的特写为真(白色像素),因此选择了图像 A。

    enter image description here

    第二个函数 ((x * y % 1024) % rand()) % 2又出现了 rand() 的问题通常大于你要除的东西, (x * y % 1024) ,最多为 1023。然后 (x*y%1024)%2不会同样频繁地产生 0 和 1。任何奇数乘以任何偶数都是偶数。任何偶数乘以任何偶数也是偶数。只有奇数乘以奇数才是奇数,所以 %2甚至四分之三时间的值将在四分之三的时间内产生 0。

    这是 ((x * y % 1024) % rand()) % 2 的特写为真,因此可以选择图像 B。它准确地选择了两个坐标都是奇数的地方。

    enter image description here

    这是可以选择图像 C 的特写:

    enter image description here

    最后结合这里的条件是选择图像 B 的地方:

    enter image description here

    选择图像 C 的地方:

    enter image description here

    由此产生的组合可以理解为:

    有 50% 的概率使用图像 A 中的像素。其余时间在图像 B 和图像 C 之间选择,B 两个坐标都是奇数,C 中的一个是偶数。

    最后,由于您对三种不同的颜色执行相同操作,但方向不同,因此每种颜色的图案方向不同,并产生您所看到的交叉条纹或网格图案。

    关于c - 为什么在使用 rand() 时会得到这种特殊的颜色模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52451998/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com