[解決済み] rand()を使用すると、なぜこのような特殊な色パターンになるのですか?
質問
このような画像ファイルを作成しようとしました。
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();
}
各画素の値は3つの関数から選択される。
(x + y) % rand()
,
(x - y) % rand()
および
rand()
;
それぞれ単独で生成される画像を見てみましょう。
-
rand()
これは期待通りのもので、ただのノイズです。これをイメージCと呼びます。
-
(x + y) % rand()
ここでは、ピクセル座標を足し合わせて、乱数で割った余りを取っています。画像のサイズが1024x1024の場合、合計値は[0-2046]の範囲になります。乱数は [0,RAND_MAX] の範囲にあり、RAND_MAX は少なくとも 32k で、システムによっては 20 億になるものもあります。言い換えれば、余りが単に「0」でない確率はせいぜい16分の1です。
(x + y)
. したがって、この関数は、ほとんどの場合、+x +y方向に向かって青色が増加するグラデーションを生成するだけです。
しかし、あなたは下位8ビットしか使っていません。
uint8_t
そのため、256ピクセル幅のグラデーションのストライプができます。
これをquot;画像A"と呼びます。
-
(x - y) % rand()
ここでは、似たようなことを引き算で行っています。xがyより大きい限り、前の画像と似たようなものになります。しかし、yの方が大きい場合、結果は非常に大きな数字になります。
x
と
y
は符号なし(負の結果は符号なし型の範囲の一番上まで回り込む)、次に
% rand()
が効いて、実際にノイズが出る。
これを「イメージB&Q」と呼びます。
最終的な画像の各ピクセルは、関数を使用してこれら3つの画像のうちの1つから取得されます。
rand() % 2
と
((x * y % 1024) % rand()) % 2
. このうち最初のものは、50%の確率で選ぶと読み取れます(
rand()
とその低次のビットがあります)。
のクローズアップです。
rand() % 2
が真(白いピクセル)であるため、画像Aが選択されます。
2つ目の機能
((x * y % 1024) % rand()) % 2
にも問題があります。
rand()
は通常、分割するものよりも大きい。
(x * y % 1024)
であり、最大でも1023である。そうすると
(x*y%1024)%2
は0と1を同じ頻度で生成するわけではありません。奇数と偶数の掛け算は偶数である。偶数と偶数の掛け算も偶数です。奇数に奇数を掛けたものだけが奇数です。
%2
の場合、4分の3が偶数なら、4分の3が0になる。
のクローズアップです。
((x * y % 1024) % rand()) % 2
が真になり、画像Bが選択されるようになりました。両方の座標が奇数であるところが正確に選択されています。
そして、画像Cを選択できる場所のクローズアップです。
最後に条件を組み合わせると、ここで画像Bが選択されます。
そして、画像Cが選択されているところ。
出来上がった組み合わせは、次のように読むことができます。
50%の確率で画像Aの画素を使用し、残りは画像Bと画像Cから選び、両方の座標が奇数の場合はB、どちらかが偶数の場合はCとする。
最後に、3色で同じことをしても、向きが違うので、パターンはそれぞれの色で異なる向きになり、あなたが見ているような交差した短冊や格子模様ができます。
関連
-
VSCodeでCプログラムを書くとエラーになる:ソースファイル "stdio.h" を開くことができない
-
警告: 'struct XXX' はパラメータリストの内部で宣言されています。
-
[解決済み] flexible array member not at end of structエラーの原因は何ですか?
-
[解決済み] C言語で%sを正しく使う - 超基本レベル
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み] 配列の場合、なぜ a[5] == 5[a] になるのでしょうか?
-
[解決済み] C言語における「static」の意味とは?
-
[解決済み] 配列のすべてのメンバーを同じ値で初期化するには?
-
[解決済み】なぜこれらのコンストラクトはプリインクリメントとポストインクリメントを使用して未定義の動作をしているのでしょうか?
-
[解決済み】rand()+rand()で負の数が出るのはなぜ?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
ポインタ定数および定数ポインタ
-
[解決済み] stdinとSTDIN_FILENOの違いは何ですか?
-
[解決済み] flexible array member not at end of structエラーの原因は何ですか?
-
[解決済み] なぜmemsetではなくbzeroを使用するのですか?
-
[解決済み] C言語では「?」演算子は何をするのですか?
-
[解決済み] Cプリプロセッサはなぜ "linux "という単語を定数 "1 "と解釈するのですか?
-
[解決済み] C言語でランダムなint型を生成するには?
-
[解決済み] FortranはC言語よりも重い計算を最適化しやすいですか?
-
[解決済み] 講師が書いたC言語のファイルは、なぜ最初の行に#が一つ付いているのですか?
-
[解決済み】"ランダム性 "を理解する