Saya awalnya akan memiliki jawaban yang sama seperti yang dimiliki orang lain dan membahasnya sampai masalah rand()
. Namun, saya pikir lebih baik melakukannya dan bukannya menganalisis distribusi matematika Anda yang sebenarnya menghasilkan.
TL; DR: Pola yang Anda lihat tidak ada hubungannya dengan penghasil bilangan acak yang mendasarinya dan sebagai gantinya hanya karena cara program Anda memanipulasi angka-angka tersebut.
Saya akan tetap menggunakan fungsi biru Anda karena semuanya mirip.
uint8_t blue(uint32_t x, uint32_t y) {
return (rand() % 2) ? (x + y) % rand() :
((x * y % 1024) % rand()) % 2 ? (x - y) % rand() :
rand();
}
Setiap nilai pixel dipilih dari salah satu dari tiga fungsi: (x + y) % rand()
, (x - y) % rand()
, dan rand()
;
Mari kita lihat gambar yang dihasilkan oleh masing-masing ini saja.
Inilah yang Anda harapkan, hanya kebisingan. Sebut ini "Gambar C"
Di sini Anda menambahkan koordinat piksel bersama dan mengambil sisanya dari pembagian dengan angka acak. Jika gambar adalah 1024x1024 maka jumlahnya berada dalam kisaran [0-2046]. Angka acak yang Anda lewati berada dalam kisaran [0, RAND_MAX], di mana RAND_MAX setidaknya 32k dan pada beberapa sistem adalah 2 miliar. Dengan kata lain, paling tidak ada peluang 1 dari 16 bahwa sisanya tidak adil (x + y)
. Jadi untuk sebagian besar fungsi ini hanya akan menghasilkan gradien biru yang meningkat ke arah + x + y.
Namun Anda hanya menggunakan 8 bit terendah, karena Anda mengembalikan a uint8_t
, sehingga Anda akan memiliki garis gradien lebar 256 piksel.
Sebut ini "Gambar A"
Di sini Anda melakukan sesuatu yang serupa, tetapi dengan pengurangan. Selama x lebih besar dari y Anda akan memiliki sesuatu yang mirip dengan gambar sebelumnya. Tapi di mana y lebih besar, hasilnya adalah angka yang sangat besar karena x
dan y
tidak ditandatangani (hasil negatif membungkus ke bagian atas kisaran jenis unsigned), dan kemudian % rand()
tendangan masuk dan Anda benar-benar mendapatkan suara.
Sebut ini "Gambar B"
Setiap piksel dalam gambar akhir Anda diambil dari salah satu dari tiga gambar ini menggunakan fungsi rand() % 2
dan ((x * y % 1024) % rand()) % 2
. Yang pertama dapat dibaca sebagai memilih dengan probabilitas 50% (mengabaikan masalah dengan rand()
dan bit urutan rendahnya.)
Ini adalah closeup dari mana rand() % 2
true (white pixel) sehingga Gambar A dipilih.
Fungsi kedua ((x * y % 1024) % rand()) % 2
lagi memiliki masalah di mana rand()
biasanya lebih besar dari hal yang Anda bagikan (x * y % 1024)
, yaitu paling banyak 1023. Maka (x*y%1024)%2
tidak menghasilkan 0 dan 1 sama sering. Angka ganjil yang dikalikan dengan angka genap adalah genap. Angka genap mana pun dikalikan dengan angka genap juga genap. Hanya angka ganjil dikalikan dengan angka ganjil yang ganjil, dan begitu juga %2
nilai-nilai yang bahkan tiga perempat waktu akan menghasilkan 0 tiga perempat waktu.
Ini adalah closeup dari mana ((x * y % 1024) % rand()) % 2
benar sehingga Gambar B dapat dipilih. Itu memilih persis di mana kedua koordinat aneh.
Dan ini adalah gambar close-up di mana Gambar C dapat dipilih:
Akhirnya menggabungkan kondisi di sinilah Gambar B dipilih:
Dan di mana Gambar C dipilih:
Kombinasi yang dihasilkan dapat dibaca sebagai:
Dengan probabilitas 50%, gunakan piksel dari Gambar A. Sisa waktu memilih antara Gambar B dan Gambar C, B di mana kedua koordinatnya aneh, C di mana salah satu genap.
Akhirnya, karena Anda melakukan hal yang sama untuk tiga warna yang berbeda, tetapi dengan orientasi yang berbeda, polanya diorientasikan secara berbeda pada setiap warna dan menghasilkan garis silang atau pola kisi yang Anda lihat.