กระบวนการทำซ้ำเป็นสิ่งที่สำคัญที่สุดอย่างหนึ่งในการเขียนโปรแกรม ไม่ว่าจะเขียนขึ้นเพื่อใช้ทำอะไรก็ตาม เพราะสาเหตุหลักที่คนเราจำเป็นต้องพึ่งพาคอมพิวเตอร์ก็คือต้องการทำอะไรบาง อย่างที่ซ้ำซากโดยอาจมีกฎเกณฑ์บางอย่างที่ตายตัว
ไม่ว่าจะเขียนโปรแกรมด้วยภาษาอะไรก็ตาม ย่อมต้องมีคำสั่งสำหรับให้โปรแกรมทำการวนซ้ำ โดยอาจจะใช้คำสั่งที่ต่างกันออกไป
สำหรับ ในภาษาส่วนใหญ่แล้วมักจะมีคำสั่ง while และ for ซึ่งหลักการก็มักจะคล้ายๆกันในแต่ละภาษา ในไพธอนก็ใช้คำสั่ง while และ for ในการทำซ้ำเช่นกัน
สำหรับคำสั่ง while ในไพธอนจะไม่ต่างไปจากภาษาซีหรือภาษาอื่นๆนัก หลักการจะคล้ายๆกัน แต่สำหรับคำสั่ง for แล้วจะค่อนข้างแตกต่างออกไป ใช้งานได้กว้างขวางกว่าในภาษาอื่นๆ
สำหรับในบทนี้จะกล่าวถึงเฉพาะคำสั่ง while ซึ่งเป็นคำสั่งพื้นฐานกว่า เข้าใจง่ายกว่า ส่วน for จะกล่าวถึงในบทถัดๆไป
โดย ทั่วไปแล้ว while กับ for สามารถใช้แทนกันได้ ดังนั้นรู้แค่วิธีใช้ while โดยไม่จำเป็นต้องใช้ for เลยก็ไม่มีปัญหา อย่างไรก็ตามในหลายกรณีถ้าใช้ for จะทำให้การเขียนดูกะทัดรัดขึ้น สะดวกในการใช้งานมากกว่า
อนึ่ง เนื่องจากบทความนี้ไม่ได้เขียนขึ้นเพื่อสอนไพธอนโดยเฉพาะ ดังนั้นจะเน้นเฉพาะส่วนที่ประยุกต์ใช้กับโปรแกรมมายา ส่วนรายละเอียดกว่านั้นอ่านได้ใน
https://phyblas.hinaboshi.com/tsuchinoko07 คำสั่ง while มีรูปแบบการใช้ดังนี้
while(เงื่อนไข):
โค้ดที่ต้องการทำซ้ำ
โค้ดหลังจากทำซ้ำเสร็จ
ในการใช้ while นั้นส่วนที่จะทำซ้ำนั้นจะถูกเขียนอยู่ในบรรทัดต่อจากคำสั่ง while โดยที่จะต้องมีการร่นโดยการเคาะวรรค (spacebar)
เงื่อนไขซึ่งใส่อยู่ระหว่างคำว่า while กับโคลอน : จะมีวงเล็บครอบหรือไม่ก็ได้ แต่หากไม่ใส่วงเล็บก็ต้องเว้นวรรคหลังคำว่า while ด้วย
การร่นนั้นจะทำด้วยการเคาะกี่ครั้งก็ได้ หรือจะใช้ tab ก็ได้เช่นกัน แต่ไม่ว่าจะเคาะกี่ครั้งก็ตาม ต้องให้เท่ากันตลอด
โดย ปกติถ้าเขียนในโปรแกรมที่ใช้เขียนภาษาไพธอนโดยเฉพาะ (รวมถึงสคริปต์อีดิเตอร์ในมายาด้วย) เวลาที่กด tab มันจะไม่ได้เว้นช่องแบบทั่วไปแต่มีค่าเท่ากับการพิมพ์วรรค ๔ ครั้ง นี่เป็นมาตรฐานที่นิยมใช้ปกติ
หรือแม้แต่เวลาที่พิมพ์โคลอน : แล้วพอเคาะขึ้นบรรทัดใหม่ตำแหน่งของข้อความตัวแรกจะถูกร่นไป ๔ ช่อง
หลังจากที่เขียนคำสั่งที่ต้องการให้วนซ้ำจนจบแล้ว คำสั่งต่อไปจะต้องกลับมาอยู่ในตำแหน่งเดียวกับ while คือลบสเปซบาร์ทิ้งไป
ที่ เป็นวิธีการเขียนที่เป็นเอกลักษณ์เฉพาะของภาษาไพธอน เป็นสิ่งที่ดูเป็นระเบียบมาก ทำให้โค้ดสามารถเข้าใจได้ง่าย เป็นลำดับขั้นชัดเจน
อนึ่ง สำหรับเรื่องเกี่ยวกับรูปแบบการเขียนเงื่อนไขอ่านเพิ่มเติมได้ใน
https://phyblas.hinaboshi.com/tsuchinoko06 ขอเริ่มยกตัวอย่างด้วยการวนซ้ำเพื่อสร้างวัตถุหลายๆอันโดยวางตำแหน่งต่างกัน
import maya.cmds as mc
i=1 # ค่า i เริ่มต้นที่ 1
while(i<6): # วนซ้ำโดยค่า i เปลี่ยนไปเรื่อยๆในแต่ละรอบ
mc.polyCube(w=1,h=1,d=1) # สร้างลูกบาศก์
mc.move(2*i,0,0) # เคลื่อนย้ายไปตำแหน่งต่างกันขึ้นกับ i
i+=1 # ในแต่ละรอบค่า i จะเพิ่มทีละ 1
จะได้ลูกบาศก์ ๕ อันวางเรียงอยู่ตามแนวแกน x
จะ เห็นว่าในแต่ละการวนซ้ำมีค่า i ที่ต่างกันไป โดยไล่ตั้งแต่ 0 ไปจนถึง 5 พอเป็น 6 ก็จะหยุดการทำซ้ำ ค่า i ที่ต่างกันนี้มีผลต่อฟังก์ชัน move() ด้านใน ซึ่งใส่พิกัดแกน x เป็น 2*i ดังนั้นลูกบาศก์ในแต่ละรอบจึงถูกจัดเรียงตามแนวแกน x โดยห่างกัน 2 หน่วยไปเรื่อยๆ
นอกจากนี้อาจลองเขียน while ซ้อนกันเป็น ๒ ชั้นได้ เช่น
i=1
while(i<6):
j=1
while(j<6):
mc.polyCube(w=1,h=1,d=1)
mc.move(2*i,2*j,0)
j+=1
i+=1
คราวนี้ในฟังก์ชัน move() เพิ่มค่าพิกัดในแนวแกน y เข้ามาเป็น 2*j ผลคือจะได้ลูกบาศก์ ๒๕ ลูก วางเรียงตามแนวแกน x และ y
และสามารถเขียน while ซ้อนกันเป็น ๓ ชั้นก็ได้
i=1
while(i<6):
j=1
while(j<6):
k=1
while(k<6):
mc.polyCube(w=1,h=1,d=1)
mc.move(2*i,2*j,2*k)
k+=1
j+=1
i+=1
จะได้ลูกบาศก์ ๑๒๕ ลูก วางเรียงทั้งในแกน x, y และ z
หรือจะซ้อนกันกี่ชั้นก็ได้ แต่ต้องเข้าใจโครงสร้างว่าซ้อนกี่ชั้นก็ต้องเคาะเว้นร่นไปเท่านั้น และพอกลับมาสู่ลำดับขั้นต่อไปก็ต้องร่นกลับ โค้ดทั้งหมดมีลำดับขั้นชัดเจน
หลักการก็มีอยู่เพียงเท่านี้ ที่เหลือก็ขึ้นอยู่กับว่าจะประยุกต์อย่างไรต่อไป
อาจลองให้ค่าในแต่ละรอบกำหนดรูปร่างของวัตถุที่สร้างไปด้วย เช่น
i=1
while(i<7):
mc.polyCube(w=2*i,h=2,d=2*i)
mc.move(0,2*(6.5-i),0)
i+=1
แบบนี้จะได้พีรามิดขั้นบันได ๖ ชั้น
ความรู้เพิ่มเติม: พีรามิดที่เก่าแก่ที่สุดในโลกสร้างขึ้นเมื่อประมาณ 2600 ปีก่อน ค.ศ. เป็นแบบขั้นบันได อยู่ที่เมืองซักการา ประเทศอียิปต์ สร้างขึ้นเพื่อเป็นสุสานของฟาโรห์โจเซอร์
https://th.wikipedia.org/wiki/พีระมิดอียิปต์ เราอาจนำมาใช้สร้างเป็นอะไรที่คล้ายๆการวาดกราฟได้ เช่น ลองให้ระนาบ xz เป็นกราฟ แล้ว z เป็นฟังก์ชันของ x
x=-50
while(x<=50):
mc.polySphere(r=1)
z=25-(x**2)/50.
mc.move(x,0,z)
x+=1
ในที่นี้จะได้กราฟพาราโบลา
และสามารถพล็อตในสามมิติได้
z=-50
while(z<=50):
x=-50
while(x<=50):
mc.polySphere(r=2,sx=8,sy=8)
y=25-(x**2+z**2)/50.
mc.move(x,y,z)
x+=2
z+=2
คราวนี้ได้เป็นทรงพาราโบลาหัวคว่ำ
อาจลองใช้คู่กับ if เพื่อกำหนดเงื่อนไขให้มีการสร้างจุดขึ้นแค่ที่บางส่วน เช่น
z=-50
while(z<=50):
x=-50
while(x<=50):
if(x**2+z**2>=1600): # คัดเฉพาะที่ห่างจากใจกลางมากกว่า 40 หน่วย
mc.polySphere(r=2,sx=8,sy=8)
y=25-(x**2+z**2)/50.
mc.move(x,y,z)
x+=2
z+=2
จะเห็นว่าตรงกลางแหว่งไปเนื่องจากไม่เข้าเงื่อนไขที่ว่า x**2+z**2>=1600 หรือก็คือห่างจากใจกลางเกินกว่า 40 หน่วย
ในภาษาไพธอนใช้ and กับ or เพื่อแสดงเงื่อนไข "และ" กับ "หรือ" เช่น
z=-50
while(z<=50):
x=-50
while(x<=50):
if((x%20>5 and x%20<15) or (z%20>5 and z%20<15)):
mc.polySphere(r=2,sx=8,sy=8)
y=25-(x**2+z**2)/50.
mc.move(x,y,z)
x+=2
z+=2
กรณีข้อนี้ใช้เลขเศษเหลือจากการหาร 20 เป็นเงื่อนไข โดยถ้า x หรือแกน z อย่างใดอย่างหนึ่งหารเหลือเศษอยู่ในช่วง 6 ถึง 14 จึงจะสร้างทรงกลมขึ้น
หรืออีกนัยหนึ่งก็คือถ้าหากหาร 20 แล้วได้ 0 ถึง 5 หรือ 15 ถึง 19 ทั้ง x และ z แล้วละก็จะไม่มีการสร้างทรงกลม จึงได้โหว่เป็นช่วงๆอย่างที่เห็น
หลัง if สามารถเติมเงื่อนไขต่อได้โดยใช้ elif และเมื่อเงื่อนไขเป็นเท็จแล้วไม่ตั้งเงื่อนไขอะไรต่อก็ใช้ else
ลองใช้โครงสร้าง if elif else แล้วก็ซ้อนกัน
z=-50
while(z<=50):
x=-50
while(x<=50):
y=25-(x**2+z**2)/50.
if(y==25):
mc.polySphere(r=10,sx=8,sy=8) # กรณีอยู่ที่ใจกลางพอดี ให้สร้างลูกใหญ่ r=10
mc.move(x,y,z)
else:
mc.polySphere(r=2,sx=8,sy=8) # กรณีอื่นสร้างลูกเล็ก r=2
if(y>0):
mc.move(x,y,z) #กรณี y ต่ำกว่า 0 แต่ไม่มากกว่า -25
elif(y>-25):
mc.move(x,-y,z) #กรณี y น้อยกว่า -25
else:
mc.move(x,37.5+y/2,z) # กรณี y ไม่ต่ำกว่า 0
x+=2
z+=2
โครงสร้างยิ่งซ้อนกันก็อาจจะยิ่งดูแล้วเข้าใจยาก แต่หากทำความคุ้นเคยและเข้าใจมันได้แล้วจะทำอะไรได้มากมาย ซึ่งหลายอย่างก็ไม่อาจทำได้โดยง่ายด้วยการแค่เพียงจับหน้าจอควบคุม
การวนซ้ำเป็นสิ่งที่จะต้องใช้มากถึงมากที่สุดในการเขียนโปรแกรม ใครที่อ่านตรงนี้แล้วยังงงๆอยู่พออ่านบทต่อๆไปเรื่อยๆก็จะเจออีกเรื่อยๆก็อาจค่อยๆซึมซับไปทีละนิด
ยิ่งลองทำดูก็จะยิ่งสนุกขึ้นเรื่อยๆ