Ban đầu tôi sẽ có câu trả lời giống như những người khác và đưa ra vấn đề này rand()
. Tuy nhiên, tôi nghĩ tốt hơn khi làm như vậy và thay vào đó phân tích phân phối mà toán học của bạn thực sự tạo ra.
TL; DR: Mẫu bạn thấy không liên quan gì đến trình tạo số ngẫu nhiên cơ bản và thay vào đó chỉ đơn giản là do cách chương trình của bạn đang thao tác các số.
Tôi sẽ sử dụng chức năng màu xanh của bạn vì tất cả đều giống nhau.
uint8_t blue(uint32_t x, uint32_t y) {
return (rand() % 2) ? (x + y) % rand() :
((x * y % 1024) % rand()) % 2 ? (x - y) % rand() :
rand();
}
Mỗi giá trị điểm ảnh được lựa chọn từ một trong ba chức năng: (x + y) % rand()
, (x - y) % rand()
, và rand()
;
Chúng ta hãy nhìn vào hình ảnh được tạo ra bởi mỗi một mình.
Đây là những gì bạn mong đợi, chỉ là tiếng ồn. Gọi đây là "Hình ảnh C"
Ở đây bạn đang thêm các tọa độ pixel lại với nhau và lấy phần còn lại từ chia cho một số ngẫu nhiên. Nếu hình ảnh là 1024x1024 thì tổng số nằm trong phạm vi [0-2046]. Số ngẫu nhiên bạn đang lặn nằm trong phạm vi [0, RAND_MAX], trong đó RAND_MAX có ít nhất 32 nghìn và trên một số hệ thống là 2 tỷ. Nói cách khác, có ít nhất 1 trên 16 cơ hội rằng phần còn lại không chỉ (x + y)
. Vì vậy, đối với hầu hết các phần, chức năng này sẽ chỉ tạo ra một dải màu xanh lam tăng dần theo hướng + x + y.
Tuy nhiên, bạn chỉ sử dụng 8 bit thấp nhất, vì bạn trả về a uint8_t
, do đó, bạn sẽ có các dải màu rộng 256 pixel.
Gọi đây là "Hình ảnh A"
Ở đây bạn làm một cái gì đó tương tự, nhưng với phép trừ. Miễn là x lớn hơn y, bạn sẽ có một cái gì đó tương tự như hình ảnh trước đó. Nhưng trong trường hợp y lớn hơn, kết quả là một con số rất lớn bởi vì x
và y
không dấu (kết quả âm tính bao quanh đỉnh của phạm vi không dấu), và sau đó các % rand()
cú đá vào và bạn thực sự bị nhiễu.
Gọi đây là "Hình ảnh B"
Mỗi pixel trong hình ảnh cuối cùng của bạn được lấy từ một trong ba hình ảnh này bằng cách sử dụng các chức năng rand() % 2
và ((x * y % 1024) % rand()) % 2
. Đầu tiên trong số này có thể được đọc là lựa chọn với xác suất 50% (bỏ qua các vấn đề với rand()
và các bit thứ tự thấp của nó.)
Đây là rand() % 2
ảnh chụp gần đúng nơi (pixel trắng) để Image A được chọn.
Hàm thứ hai ((x * y % 1024) % rand()) % 2
một lần nữa có vấn đề rand()
thường lớn hơn thứ bạn đang chia, (x * y % 1024)
nhiều nhất là 1023. Sau đó, (x*y%1024)%2
không tạo ra 0 và 1 thường xuyên như nhau. Bất kỳ số lẻ nào nhân với bất kỳ số chẵn nào là số chẵn. Bất kỳ số chẵn nào nhân với bất kỳ số chẵn nào cũng là số chẵn. Chỉ một số lẻ nhân với một số lẻ là số lẻ, và cứ như vậy, %2
các giá trị chẵn ba phần tư thời gian sẽ tạo ra 0 ba phần tư thời gian.
Đây là một cái nhìn cận cảnh về nơi ((x * y % 1024) % rand()) % 2
là đúng để có thể chọn Image B. Nó chọn chính xác nơi cả hai tọa độ là số lẻ.
Và đây là một cái nhìn cận cảnh về nơi Image C có thể được chọn:
Cuối cùng kết hợp các điều kiện ở đây, nơi Hình ảnh B được chọn:
Và nơi Image C được chọn:
Sự kết hợp có thể được đọc là:
Với xác suất 50%, sử dụng pixel từ Ảnh A. Thời gian còn lại chọn giữa Ảnh B và Ảnh C, B trong đó cả hai tọa độ là số lẻ, C trong đó một trong hai là số chẵn.
Cuối cùng, vì bạn đang làm giống nhau cho ba màu khác nhau, nhưng với các hướng khác nhau, các mẫu được định hướng khác nhau trong mỗi màu và tạo ra các dải chéo hoặc mẫu lưới mà bạn nhìn thấy.