จากภาพแสดงให้เห็นชนิดของ conics มี 4 ชนิดคือ
Circle คือ เซตของจุดที่อยู่ห่างจากจุดคงที่จุดหนึ่งเป็นระยะทางเท่ากัน จุดคงที่จุดนั้นเรียกว่า จุดศูนย์กลาง นิยมเขียนแทนด้วย C และระยะทางคงที่นั้นเรียกว่า รัศมี (radius) นิยมเขียนแทนด้วย r
Ellipse คือ เซตของจุดที่อยู่ห่างจากจุดคงที่สองจุด (F, G) โดยผลรวมของระยะห่างระหว่างจุดกับจุดคงที่ทั้งสองมีค่าคงที่
Parabola คือเซตของจุดที่อยู่ห่างจากสิ่งสองสิ่งเป็นระยะทางเท่ากัน สองสิ่งที่ว่าคือ
- จุดคงที่เรียกว่า Focus
- เส้นตรงเรียกว่า Directrix
Hyperbola [3] เกิดจากการตัดกรวยสองกรวยที่ยอดมาชนกัน ดังภาพ
By Melikamp - Own work, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=25108128 |
การทำความเข้าใจเรื่องภาคตัดกรวยหรือ conics ที่ง่ายและรวดเร็วทางหนึ่งก็คือการวาดรูปขึ้นมาประกอบการจดจำนิยามและสมการ ในตอนนี้จะใช้ Python library ชื่อ matplolib [4] มาช่วยสร้างรูปร่างต่าง ๆ ที่เกิดจากสมการ conics ทั้งนี้ก็เพื่อให้การเขียน Python script สั้นและง่ายจนไม่น่าจะเป็นภาระ อีกทั้งทำให้เกิดการเรียนรู้แบบ interactive อีกด้วย
ติดตั้ง matplotlib
1. Raspberry Pi 3 Model B ติดตั้ง Raspbian และอุปกรณ์อื่นให้พร้อมใช้งาน2. ใช้ python 3.5
3. ติดตั้ง matplotlib [4] ใช้คำสั่ง
$ sudo apt-get install python3-matplotlib
วงกลมและวงรี
หากพิจารณาจากรูปแล้ววงกลมและวงรีแทบจะเหมือนกันทุกประการ ดังนั้นเราจึงใช้สมการเดียวกันได้ คือ
เมื่อ a,b คือ scale factor [7] สำหรับแกน x และ y ตามลำดับ และ r คือระยะห่างจากจุดศูนย์กลาง
เขียน Python script
ขั้นตอนที่ 1 นำเข้า module ที่ต้องใช้
import matplotlib.pyplot as plt
import numpy as np
เรานำ module เข้ามาในโปรแกรม (script) 2 modules คือ pyplot จาก matplotlib แล้วกำหนดชื่ออ้างอิงใน script เป็น plt (matplotlib เป็นกลุ่มของ module หลาย module และ pyplot เป็นหนึ่งในนั้น) และ numpy และกำหนดชื่อเป็น np (ไม่อยากเขียนยาว) เป็น module ที่ช่วยอำนวยความสะดวกในการทำงานกับตัวแปรที่มีหลายค่า (array)
x = np.linspace(-20,20,400)
y = np.linspace(-20,20,400)
x,y = np.meshgrid(x,y)
คำสั่ง np.linspace(-20,20,400) เป็นการสั่งให้ numpy ช่วยสร้างตัวแปรแบบ array ให้ โดยค่าเริ่มต้นคือ -20 ไปจนถึง 20 โดยมีสมาชิกทั้งหมด 400 ตัว หากแสดงค่าของสมาชิกของ x หรือ y จะได้ดังภาพ จะเห็นได้ว่าค่าของ x, y เป็น array ของจำนวนจริง
x,y = np.meshgrid(x,y) เป็นคำสั่งที่ให้ numpy สร้างโครงสร้างข้อมูลแบบ grid หรือ coordinate หรือ คู่อันดับ ขึ้นมา โดยใช้ข้อมูลจาก x, y ไปสร้าง ผลที่ได้จากคำสั่งนี้คือจะได้ คู่อันดับจำนวน 400 x 400 = 160,000 คู่อันดับ (หากเขียนด้วยมือคงไม่ไหวแน่)
ทำไมต้องทำเป็นคู่อันดับ ก็เพราะเรากำลังนำข้อมูลไปเขียนกราฟหรือแสดงความสัมพันธ์ระหว่างตัวแปรสองตัว ในที่นี้แทนด้วย x และ y
ขั้นตอนที่ 3 กำหนด parameter อื่นที่เกี่ยวข้อง
a = 1
b = 1
r = 1
ct = (0,0)
จากสมการจะเห็นว่านอกจาก x และ y ซึ่งจะถูกนำไป plot แล้ว ก็ยังต้องมี a, b, r อีก และเพิ่มมาอีกหนึ่งคือ ct หรือ ตำแหน่งของ จุดศูนย์กลาง (นึกถึงนิยามวงกลม)
ขั้นตอนที่ 4 สร้างพื้นที่สำหรับการ plot
ax = plt.axes()
ax.axis('equal')
ax.grid()
ax = plt.axes() เป็นคำสั่งบอกให้ pyplot สร้างพื้นที่สำหรับ plot ขึ้นมา โดย ax จะเป็นตัวแปรในการอ้างถึงแกน x และ แกน y ซึ่งเราจะสามารถปรับแต่งได้ต่อไป
ax.axis('equal') เป็นคำสั่งให้ pyplot สร้างแกนนอนและแกนตั้งด้วยอัตราส่วนที่เท่ากัน
ax.grid() เป็นคำสั่งให้ pyplot สร้างเส้น grid ให้ด้วย ผลออกมาจะคล้ายกับการใช้กระดาษกร๊าฟ
ขั้นตอนที่ 5 การกำหนดความสัมพันธ์ด้วยสมการ
ax.contour(x,y,(x**2/a**2 + y**2/b**2),[r**2],color='green')
ดูเหมือนจะวุ่นวายสักหน่อยสำหรับคำสั่งนี้ แต่ไม่มีอะไรพิเศษ เป็นการสั่งให้ pyplot ทำการวาดเส้น contour [5] บนเงื่อนไขที่กำหนดให้ ซึ่งเงื่อนไขก็คือสมการแสดงความสัมพันธ์ระหว่างตัวแปรที่จะนำไป plot ในกรณีนี้ก็คือนำเอาสมการวงกลมหรือวงรีมาใส่ไว้นั่นเอง
ขั้นตอนที่ 6 สั่งวาดภาพ
plt.show()
ผลที่ได้คือ วงกลมที่มีรัศมี (r) 1 หน่วย เป็นวงกลมเพราะกำหนด scale ของ X และ Y ผ่านตัวแปร a, b ให้มีค่าเท่ากัน
script ที่เต็มรูปคือ
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-20,20,400)
y = np.linspace(-20,20,400)
x,y = np.meshgrid(x,y)
a = 1
b = 1
r = 1
ct =(0,0)
ax = plt.axes()
ax.grid()
ax.axis('equal')
ax.contour(x+ct[0],y+ct[1],x**2/a**2 + y**2/b**2, [r**2],color='green')
plt.show()
สั้นมาก ไม่มีอะไรซับซ้อน !ทำการทดลองเปลี่ยนค่า parameter
1. เพิ่มค่า r เป็น r = 5 scale ของ X และ Y เท่ากัน แสดงความเร็วในการเปลี่ยนแปลงเท่ากัน
2. a = 3 b = 1 เพิ่ม scale ของค่า X แสดงว่า ค่า X จะเปลี่ยนเร็วกว่าค่า Y
3. a = 1, b = 3 เพิ่ม scale ของค่า Y แสดงว่าค่า Y จะเปลี่ยนเร็วกว่าค่า X
4. เปลี่ยนตำแหน่ง ct = (3,3) เนื่องจากการเปลี่ยนตำแหน่งจุดศูนย์กลางจะมีผลในขั้นตอนของการวาด แต่รูปแบบความสัมพันธ์ยังคงเหมือนเดิม เราจึงไปแก้ไขในคำสั่ง contour เป็น
ax.contour(x+ct[0],y+ct[1],x**2/a**2 + y**2/b**2, [r**2],color='green')
5. อ้างอิงสมการ 2D rotation [6] ทดลองทำการหมุนภาพไป 30 องศา
theta = [np.pi/6]
กำหนดองศาที่จะหมุน เนื่องจาก function geometry ใน Python ใช้มุมในหน่วยของ radian จึงต้องแปลงหน่วยให้เรียบร้อยก่อน
ax.contour(x*np.cos(theta) - y*np.sin(theta),
x*np.sin(theta)+y*np.cos(theta),
x**2/a**2 + y**2/b**2,
[r**2],
color='green')
ทำการหมุนจุดทุกจุดก่อนการ plot
เราจะเรียนรู้ไม่ได้เต็มที่หากไม่ได้ทดลองเปลี่ยนแปลงอะไร ดังนั้นผู้อ่านควรไปทดลองเปลี่ยนแปลงค่า parameter ต่าง ๆแล้วดูผลลัพธ์ที่เปลี่ยนไป ในตอนต่อไปจะกล่าวถึงเรื่องของ parabola และ hyperbola กันครับ
เอกสารอ้างอิง
[1] https://en.wikipedia.org/wiki/Apollonius_of_Perga[2] https://en.wikipedia.org/wiki/Conic_section
[3] https://en.wikipedia.org/wiki/Hyperbola
[4] https://matplotlib.org/
[5] https://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.contour
[6] https://somchaisom.blogspot.com/2018/03/computer-graphics-2-d-rotation.html
[7] https://somchaisom.blogspot.com/2018/03/computer-graphics-2d-scaling.html
Sign up here with your email
ConversionConversion EmoticonEmoticon