ต่อจาก
บทที่ ๑๘
ในบทนี้จะเป็นเรื่องของการวางระบบพิกัดลงในภาพเพื่อใช้แสดงกราฟ
การสร้างแกนกราฟ
การใส่แกนกราฟลงในภาพทำได้โดยสร้างออบเจ็กต์คลาส Axes ส่วนตัวเลขแสดงพิกัดเติมได้โดยใช้เมธอด .add_coordinate_labels() ที่ตัวออบเจ็กต์กราฟ
ลองเริ่มจากสร้างแกนกราฟขึ้นมาเฉยๆโดยไม่ได้ปรับแต่งอะไรเลยดู
import manimlib as mnm
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.Axes()
axes.add_coordinate_labels()
self.play(
mnm.Write(axes),
run_time=2
)
การปรับแต่งแกนกราฟ
แกนกราฟมีค่าต่างๆที่สามารถปรับได้ เช่นตำแหน่งขีด ขนาดความกว้างและสูง ฯลฯ
สำหรับการปรับส่วนของเส้นแกนนั้นอาจปรับด้วยคีย์เวิร์ด axis_config เพื่อเป็นการปรับเส้นแกน x และ y ไปพร้อมๆกัน หรืออาจแยกเป็น x_axis_config กับ y_axis_config สำหรับส่วนที่ต้องการให้แกน x กับ y ต่างกัน
ส่วนตัวเลขแสดงพิกัดก็สามารถปรับได้โดยใส่คีย์เวิร์ดแบบเดียวกับที่ใช้สร้างออบเจ็กต์ DecimalNumber
ตัวอย่าง
import manimlib as mnm
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.Axes(x_range=(-2,4,0.4), # ตำแหน่งขีดแกน x
y_range=(-1,3.1,0.5), # ตำแหน่งขีดแกน y
width=13, # ความกว้าง
height=7, # ความสูง
axis_config={'stroke_width':3}, # ความหนาเส้น
x_axis_config={'stroke_color':'#e7b0ef', # สีเส้น
'line_to_number_direction':mnm.UP, # ตำแหน่งที่วางตัวเลข
'include_tip':False}, # วาดลูกศรที่ปลายหรือไม่
y_axis_config={'stroke_color':'#bbefb0',
'line_to_number_direction':mnm.RIGHT,
'line_to_number_buff':1, # ระยะห่างระหว่างตัวเลขกับแกน
'include_ticks':False}) # วาดขีดหรือไม่
axes.add_coordinate_labels(font_size=25, # ขนาดอักษร
num_decimal_places=1, # จำนวนเลขทศนิยม
include_sign=True, # ใส่เครื่องหมาย + หรือไม่
color='#b0dbef') # สีตัวหนังสือ
self.play(
mnm.Write(axes),
run_time=1.5
)
self.wait(0.5)
การแปลงพิกัดจากระนาบแกนเป็นตำแหน่งในภาพ
หากต้องการจะวางวัตถุอะไรในระบบพิกัดแกนกราฟจะต้องทำการแปลงระบบพิกัดจากตำแหน่ง x,y ในระนาบแกนนั้นมาเป็นตำแหน่งภายในภาพ
การแปลงสามารถทำได้โดยใช้เมธอด .c2p() ที่ตัวกราฟ โดยใส่ค่าพิกัด x,y ลงไปแล้วจะได้ค่าพิกัดตำแหน่งภายในภาพ จากนั้นก็นำมาใช้เพื่อวางจุดตามที่ต้องการได้
ตัวอย่าง ลองวาดจุดขึ้นมาที่ตำแหน่งหนึ่งบนแกนกราฟ แล้วย้ายไปอีกตำแหน่ง
import manimlib as mnm
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.Axes(x_range=(0,50,5),
y_range=(0,35,5))
axes.add_coordinate_labels(font_size=32)
p1 = axes.c2p(0,5) # ตำแหน่งจุดเริ่มต้น
chut = mnm.Dot(p1) # วัตถุจุด
p2 = axes.c2p(35,15) # ตำแหน่งจุดที่จะย้ายไป
self.add(axes)
self.play(
chut.animate.move_to(p2),
run_time=1.5
)
self.wait(0.5)
การแปลงตำแหน่งในภาพไปเป็นพิกัดระนาบแกน
ในทางตรงกันข้ามกับ .c2p() หากต้องการแปลงค่าตำแหน่งจากในภาพไปเป็นตำแหน่งในพิกัดระนาบแกนก็ทำได้โดยใช้เมธอด .p2c()
ตัวอย่างเช่น เมื่อต้องการใส่ตัวเลขที่แสดงตำแหน่งภายในระบบแกนกราฟก็อาจใช้ .c2p() ได้ เช่น
import manimlib as mnm
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.Axes(x_range=(0,70,5),
y_range=(0,55,5))
axes.add_coordinate_labels(font_size=28)
p1 = axes.c2p(15,20) # จุดเริ่มต้น
chut = mnm.Dot(p1) # วัตถุจุด
# ฟังก์ชันสร้างเลขแสดงตำแหน่ง
def sailek():
# เอาค่าตำแหน่งจุดภายในภาพมาแปลงเป็นพิกัดในระนาบแกน
x,y = axes.p2c(chut.get_center())
xy = mnm.Text(f'({x:.0f},{y:.0f})')
xy.next_to(chut,mnm.DOWN) # วางไว้ด้านล่างของจุด
return xy
# ตัวเลขแสดงตำแหน่ง ให้สร้างใหม่ทุกเฟรม
text = mnm.always_redraw(sailek)
p2 = axes.c2p(55,45) # จุดที่จะย้ายไป
self.add(axes,text)
self.play(
chut.animate.move_to(p2),
run_time=1.5
)
self.wait(0.5)
การลากเส้นจากจุดไปยังแกน
ออบเจ็กต์แกนมีเมธอด .get_h_line() และ .get_v_line() ซึ่งใช้ลากเส้นแนวนอนและแนวตั้งจากจุดที่กำหนดไปยังแกน
ตัวอย่าง
import manimlib as mnm
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.Axes(x_range=(-30,25,5),
y_range=(0,25,5),
axis_config={'stroke_width':5,'color':'#908ecb'})
axes.add_coordinate_labels(font_size=36,color='#908ecb')
p1 = axes.c2p(15,20)
chut = mnm.Dot(p1,radius=0.2,color='#82c5b8')
def f_non():
return axes.get_h_line(chut.get_center(),color='#dfb0ef',stroke_width=4)
sen_non = mnm.always_redraw(f_non)
def f_tang():
return axes.get_v_line(chut.get_center(),color='#efd7b0',stroke_width=3)
sen_tang = mnm.always_redraw(f_tang)
p2 = axes.c2p(-20,5)
self.add(axes,sen_non,sen_tang)
self.play(
chut.animate.move_to(p2),
run_time=1.5
)
การวาดเส้นแสดงพิกัดระนาบของตำแหน่งภายในภาพ
หากต้องการแสดงระบบพิกัดของตำแหน่งภายในภาพก็สามารถทำได้โดยสร้างออบเจ็กต์คลาส NumberPlane
ตัวอย่าง ลองใส่กราฟแสดงพิกัดของตำแหน่งในภาพขึ้นมา
import manimlib as mnm
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.NumberPlane()
axes.add_coordinate_labels()
self.play(
mnm.Write(axes),
run_time=1.5
)
self.wait(0.5)
NumberPlane ประกอบไปด้วยเส้นตาราง โดยเส้นหลักที่ขีดที่ค่าจำนวนเต็มจะอยู่ที่ .background_lines เส้นรองอยู่ที่ .faded_lines สามารถปรับแต่งขนาดหรือสีของเส้นได้เหมือนกับวัตถุคลาส Line
ลองปรับแต่งดู
import manimlib as mnm
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.NumberPlane()
axes.add_coordinate_labels(font_size=36,color='#908ecb')
# ปรับเส้นหลัก
axes.background_lines.set_style(stroke_color='#bcd6a6',
stroke_width=7)
# ปรับเส้นรอง
axes.faded_lines.set_style(stroke_color='#ebb4d6',
stroke_width=4)
self.add(axes)
# ลบเส้นรอง
self.play(
mnm.Uncreate(axes.faded_lines),
run_time=1
)
self.wait(0.25)
# ลบเส้นหลัก
self.play(
mnm.FadeOut(axes.background_lines),
run_time=0.5
)
self.wait(0.25)
เมื่อใช้ NumberPlane พิกัดของแกนกราฟตรงกับพิกัดในภาพ ดังนั้นหากวางวัตถุอะไรลงในภาพก็จะตรงกับตำแหน่งในระบบแกนนี้โดยไม่ต้องทำการแปลงใดๆ
ตัวอย่างเช่น
import manimlib as mnm
import numpy as np
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.NumberPlane()
axes.add_coordinate_labels(font_size=32,color='#e5abd8')
haliam = mnm.Polygon(np.array([-5,0,0]),
np.array([-1,3,0]),
np.array([1,3,0]),
np.array([5,0,0]),
np.array([0,-3,0]),
color='#bce5ab',
stroke_width=30)
self.add(axes)
self.play(
mnm.Write(haliam),
run_time=0.5
)
ระนาบเชิงซ้อน
ComplexPlane เป็นคลาสย่อยของ NumberPlane โดยจะต่างจาก NumberPlane ตรงที่จะสร้างเป็นระบบพิกัดเชิงซ้อน
ตัวอย่างการใช้
import manimlib as mnm
import numpy as np
class Manimala(mnm.Scene):
def construct(self):
axes = mnm.ComplexPlane()
axes.add_coordinate_labels()
chut = mnm.Dot(np.array([3,2,0]))
text = mnm.Text('3+2i')
text.next_to(chut,mnm.UP)
self.add(axes)
self.play(
mnm.FadeIn(chut),
mnm.Write(text),
run_time=1.5
)
อ่านบทถัดไป >>
บทที่ ๒๐