โดยปกติที่ผ่านมาเวลาที่ใช้คำสั่งทำอะไรก็ตาม ผลที่ได้ออกมาจะตายตัวเหมือนเดิมเสมอ ไม่ว่าจะทำกี่ครั้ง
แต่เราสามารถโปรแกรมทำอะไรที่ไม่ซ้ำกันได้เช่นกัน โดยอาศัยการสุ่ม
ฟังก์ชันคำสั่งสำหรับสุ่มนั้นมีอยู่ในมอดูลในตัวของภาษาไพธอน สามารถใช้ได้โดยพิมพ์
import random
ในมอดูลนี้มีฟังก์ชันอยู่หลายตัวที่สะดวกที่จะนำมาใช้เพื่อให้เกิดการสุ่มต่างๆ
ฟังก์ชันตัวที่พื้นฐานที่สุดคือ random.random() เป็นฟังก์ชันที่จะคืนค่าสุ่มเป็นจำนวนจริงซึ่งมีค่าในช่วง [0,1) คือตั้งแต่ 0 ขึ้นไปแต่ไม่ถึง 1
เช่นลอง
for i in range(100):
print(random.random())
จะได้ค่าออกมาไม่เหมือนกันเลยแต่ก็อยู่ในช่วงที่กำหนด
อาจลองใช้เพื่อสุ่มความสูงของพื้น สร้างพื้นผิวที่เป็นตะปุ่มตะป่ำ
mc.polyPlane(w=20,h=20,sx=20,sy=20,n='phuen')
for i in range(mc.polyEvaluate(v=1)):
mc.move(random.random(),'.vtx[%d]'%i,y=1)
หากอยากให้ช่วงการสุ่มกว้างขึ้นก็ทำได้โดยการคูณขอบเขตที่ต้องการเข้าไป เช่น random.random()*10+10 จะได้ค่าสุ่มในช่วง (10,20]
หรือง่ายกว่านั้น ใช้ฟังก์ชัน random.uniform() ซึ่งเป็นฟังก์ชันที่ให้ค่าสุ่มภายในช่วงขอบเขตที่กำหนด
โดย random.uniform(a,b) จะได้ผลเทียบเท่ากับ a+(b-a)*random.random()
ตัวอย่าง ลองใช้สุ่มตำแหน่งของวัตถุที่สร้างขึ้นมา
for i in range(1000):
mc.polySphere(r=1,sx=4,sy=4)
mc.move(random.uniform(0,40),random.uniform(0,40),random.uniform(0,40))
จะเห็นว่ามีการสุ่มวางทรงกลมกระจายอย่างสม่ำเสมอใน ๓ มิติ
หากต้องการเลขสุ่มเป็นจำนวนเต็มก็สามารถใช้ฟังก์ชัน random.randint()
โดย random.randint(a,b) เป็นการสุ่มค่าจำนวนเต็มทุกจำนวนตั้งแต่ a ไปถึง b
หาก ต้องการจำนวนเต็มที่มีการเว้นช่วงก็อาจใช้ฟังก์ชัน random.randrange() โดยที่ค่าที่ต้องใส่ในฟังก์ชันนี้จะเหมือนกับฟังก์ชัน range() คือ
random.randrange(a,b,c)
ก็จะได้ค่าสุ่มเป็นจำนวนเต็มที่อยู่ในช่วงตัวเลขที่เริ่มจาก a แล้วบวกเพิ่มไปทีละ c ไล่ไปเรื่อยๆจนถึงจำนวนที่ไม่ถึง b
ให้ระวังว่าจะต่างจาก randint ตรงที่ว่าค่าสุดท้ายจะไม่ถูกรวมด้วย
random.choice() เป็นฟังก์ชันสำหรับสุ่มสมาชิกมาตัวหนึ่งจากในลิสต์
จะเห็นได้ว่า random.randrange(a,b,c) มีผลเทียบเท่ากับ random.choice(range(a,b,c))
นอกจากนี้ยังมีฟังก์ชันที่ช่วยในการจัดเรียงลิสต์ใหม่
random.shuffle(ลิสต์)
ฟังก์ชันนี้จะทำการจัดเรียงสลับลำดับของสมาชิกในลิสต์ที่ใส่เข้าไป
ลอง
mc.polyPlane(w=20,h=20,sx=4,sy=4,n='phuen')
y = range(mc.polyEvaluate(f=1)) # สร้างลิสต์ของเลขดัชนีของผิวโพลิกอน 0 ถึง 15
random.shuffle(y) # ทำการสลับลำดับสมาชิกในลิสต์
for i in range(mc.polyEvaluate(f=1)):
mc.polyExtrudeFacet('.f[%d]'%i,ltz=y[i]+1) # ยื่นผิวทีละอัน แต่ละอันอาจสูงตั้งแต่ 1 จนถึง 16 โดยแต่ละอันไม่ซ้ำกันเลย
จะได้แท่งที่มีความสูงไม่เท่ากัน ไล่ตั้งแต่ 1 ถึง 16
นอกจากการสุ่มแบบแจกแจงสม่ำเสมอทั่วไปแล้วก็ยังมีคำสั่งที่สุ่มให้กระจายเป็นแบ บอื่นๆอีก เช่น random.gauss() เป็นการแจกแจงแบบเกาส์ หรืออาจเรียกว่าการแจกแจงแบบปกติ
random.gauss(μ, σ)
μ คือจุดกึ่งกลางของการกระจาย
σ คือความกว้างของการกระจาย ยิ่งมากขอบเขตการกระจายก็ยิ่งกว้าง
อ่านเพิ่มเติมได้ใน
https://th.wikipedia.org/wiki/การแจกแจงปรกติ ลองจำลองการกระจายในสามมิติรอบจุด (0,0,0) โดยมีค่า σ เป็น 10
for i in range(1000):
mc.polySphere(r=1,sx=4,sy=4)
mc.move(random.gauss(0,10),random.gauss(0,10),random.gauss(0,10))
จะเห็นว่าตรงกลางๆหนาแน่นและค่อยๆเบาบางลงเมื่อห่างจากใจกลางไป ไม่ได้กระจายอย่างสม่ำเสมอ
นอกจากนี้ก็มีการสุ่มอีกหลายแบบ ในนี้แค่ยกที่สำคัญมาบางส่วน สามารถนำไปประยุกต์ใช้ได้ตามที่ต้องการ
อ้างอิง