ผมได้รับในตอนแรกจะมีคำตอบเช่นเดียวกับคนอื่น ๆ 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()
;
ลองดูที่ภาพที่ผลิตโดยสิ่งเหล่านี้เพียงอย่างเดียว
นี่คือสิ่งที่คุณคาดหวังเพียงแค่เสียงรบกวน เรียกสิ่งนี้ว่า "Image C"
ที่นี่คุณกำลังเพิ่มพิกัดพิกเซลพร้อมกันและดึงส่วนที่เหลือจากการหารด้วยตัวเลขสุ่ม หากภาพเป็น 1024x1024 แสดงว่าผลรวมอยู่ในช่วง [0-2046] ตัวเลขสุ่มที่คุณดำน้ำนั้นอยู่ในช่วง [0, RAND_MAX] โดยที่ RAND_MAX อย่างน้อย 32k และในบางระบบคือ 2 พันล้าน กล่าวอีกนัยหนึ่งมีโอกาส 1 ใน 16 ที่ดีที่สุดที่เหลือไม่ใช่แค่(x + y)
โอกาสที่เหลือไม่ได้เป็นเพียง ดังนั้นส่วนใหญ่ฟังก์ชั่นนี้จะสร้างการไล่ระดับสีฟ้าที่เพิ่มขึ้นไปยังทิศทาง + x + y
อย่างไรก็ตามคุณจะใช้บิตต่ำสุดเพียง 8 เพราะคุณส่งคืน uint8_t
ดังนั้นคุณจึงมีแถบกว้างไล่ระดับสี 256 พิกเซล
เรียกสิ่งนี้ว่า "Image A"
ที่นี่คุณทำสิ่งที่คล้ายกัน แต่มีการลบ ตราบใดที่ x มากกว่า y คุณจะมีบางอย่างคล้ายกับภาพก่อนหน้า แต่ถ้า y มากขึ้นผลลัพธ์จะเป็นจำนวนมากเพราะx
และy
ไม่ได้ลงนาม (ผลลัพธ์เชิงลบจะถูกล้อมรอบด้านบนของช่วงของประเภทที่ไม่ได้ลงชื่อ) จากนั้นการ% rand()
เตะเข้าและคุณจะได้รับเสียงรบกวน
เรียกสิ่งนี้ว่า "Image B"
แต่ละพิกเซลในภาพสุดท้ายของคุณนั้นมาจากหนึ่งในสามภาพนี้โดยใช้ฟังก์ชั่นrand() % 2
และ((x * y % 1024) % rand()) % 2
และครั้งแรกของสิ่งเหล่านี้สามารถอ่านได้ตามที่เลือกด้วยความน่าจะเป็น 50% (ละเว้นปัญหากับrand()
และบิตลำดับต่ำ)
นี่คือระยะใกล้ที่rand() % 2
เป็นจริง (พิกเซลสีขาว) เพื่อเลือก Image A
ฟังก์ชั่นที่สอง((x * y % 1024) % rand()) % 2
อีกครั้งมีปัญหาที่rand()
มักจะมากกว่าสิ่งที่คุณหาร(x * y % 1024)
ซึ่งมากที่สุดคือ 1,023 แล้ว(x*y%1024)%2
ไม่ผลิต 0 และ 1 เท่ากัน จำนวนคี่ใด ๆ คูณด้วยจำนวนคู่ใด ๆ คือเลขคู่ จำนวนคู่ใด ๆ ที่คูณด้วยจำนวนคู่ใด ๆ ก็จะเท่ากับ เฉพาะจำนวนคี่คูณด้วยจำนวนคี่เป็นคี่และอื่น ๆ%2
ค่าที่แม้แต่สามในสี่ของเวลาจะผลิต 0 สามในสี่ของเวลา
นี่คือระยะใกล้ของที่((x * y % 1024) % rand()) % 2
เป็นจริงเพื่อให้สามารถเลือกรูปภาพ B มันกำลังเลือกตำแหน่งที่พิกัดทั้งคู่แปลก
และนี่คือภาพโคลสอัพที่สามารถเลือก Image C:
ในที่สุดก็รวมเงื่อนไขที่นี่คือที่เลือกภาพ B:
และตำแหน่งที่เลือกรูปภาพ C:
การรวมกันที่เกิดขึ้นสามารถอ่านได้เป็น:
ด้วยความน่าจะเป็น 50% ให้ใช้พิกเซลจาก Image A เวลาที่เหลืออยู่ระหว่าง Image B และ Image C, B ซึ่งทั้งสองพิกัดนั้นแปลก, C โดยที่ทั้งคู่เป็นคู่
ในที่สุดเนื่องจากคุณทำแบบเดียวกันกับสามสีที่แตกต่างกัน แต่ด้วยการวางแนวที่แตกต่างกันรูปแบบจะเน้นไปที่แต่ละสีแตกต่างกันออกไป