日期:2020/10/30
前言
我在上一篇文章〈擺線與軌跡〉中說明使用 GeoGebra 繪製擺線的方法,這次我改用 VPython 畫出純滾動的圓柱上某個點的軌跡,一樣可以畫出擺線。以下是使用 VPython 模擬的畫面截圖以及 GlowScript 網站動畫連結。
使用 VPython 繪製的擺線,淺藍色曲線為擺線理論值,紅色曲線為圓柱邊線某個點純滾動軌跡
VPython 程式碼
"""
VPython教學: 擺線與軌跡 VPython 版
日期: 2020/10/30
作者: 王一哲
"""
from vpython import *
"""
1. 參數設定, 設定變數及初始值
"""
r, v = 1, 1 # 圓柱半徑, 質心移動速度
omega = v/r # 圓柱轉動角速度
T = 2*pi/omega # 圓柱轉動週期
L, D = 22, 5 # 地板長度, 寬度
t, dt = 0, 0.001 # 時間, 時間間隔
# 擺線理論值資料
num = 500
data = []
for i in range(num):
tmp = (L-2*r)/(v*T)*2*pi/num*i
x = r*(tmp - sin(tmp)) - 0.5*L + r
y = r*(1 - cos(tmp)) - r
data.append(vec(x, y, 0.455*D))
"""
2. 畫面設定
"""
# 動畫視窗
scene = canvas(title="Cycloid", width=1200, height=300, x=0, y=0,
background=color.black, range=0.2*L, center=vec(0, r, 0))
# 地板
floor = box(pos=vec(0, -r-0.005*L, 0), size=vec(L, 0.01*L, D), color=color.blue)
# 圓柱及標示軌跡用的紅點
circ = cylinder(pos=vec(-0.5*L+r, 0, 0.45*D), axis=vec(0, 0, -0.9*D), radius=r,
texture=textures.wood_old)
dot = cylinder(pos=vec(-0.5*L+r, -r, 0.455*D), axis=vec(0, 0, -0.91*D), radius=0,
color=color.red, make_trail=True, trail_radius=0.05*r)
# 擺線理論值
cycloid = curve(pos=data, color=color.cyan, radius=0.02*r, opacity=0.8)
"""
3. 物體運動部分
"""
while circ.pos.x+r <= 0.5*L:
rate(1000)
circ.pos.x += v*dt
circ.rotate(angle=omega*dt)
dot.pos.x += v*dt
dot.rotate(angle=omega*dt, axis=vec(0, 0, -1), origin=circ.pos)
t += dt
計算擺線理論值
由於以原點作為起始點的擺線參數式為$x = r(t - \sin(t)), ~y = r(1 - \cos(t))$,但在這個動畫中的起始位置為 $(-0.5*r - L, -r)$,需要將算式修改成第25、26行的樣子。其中 t 個這變數已經被用來作為時間,因此程式碼中使用了另一個變數 tmp。 假設取 num = 500,利用 for 迴圈將500個點代入參數式中計算對應的位置,再將位置儲存到串列 data 當中。為了計算出純滾動的點對應的位置,先將圓柱前進的距離 $L - 2r$ 除以速度 v 得到前進的時間,再將時間除以週期 T 得到經過的週期次數,每經過一個週期對應的角度為 $2 \pi$,最後將所有對應的角度除以取點數 num、乘上點的索引值 i。
畫面設定
- 第36、37行:產生圓柱體 circ,為了比較容易看出圓柱旋轉的效果,建議採用貼圖材質而不是指定顏色。
- 第38、39行:產生標示軌跡用的點,為了簡化計算位置的算式,建議將半徑設定為0,再用 trail_radius=0.05*r 設定軌跡的半徑即可。
- 第42行:使用 curve 物件繪製擺線理論值。
物體運動
- 第49行:將圓柱的中心向右平移一段距離 v*dt。
- 第50行:將圓柱旋轉一個角度 omega*dt,預設的轉軸方向為自己的軸方向,預設的旋轉中心為自己的位置,如果寫成以下這樣效果相等。
circ.rotate(angle=omega*dt, axis=vec(0, 0, -1), origin=circ.pos)
- 第51行:將點的位置向右平移一段距離 v*dt。
- 第52行:將點繞著圓柱中心旋轉一個角度 omega*dt。
結語
VPython 有將多個物件合併為一個物件的功能 (compound) 合併之後這幾個物件可以一起移動,但是這樣就沒辦法畫出其中一個物件的軌跡,將圓柱和圓周上的點分開處理會比較方便。此外,由於 VPython 動畫為了表現出立體感,畫面的兩側會有點變形,畫出來的擺線看起來會和平面上的擺線有點不一樣,這是無法避免的。
HackMD 版本連結:https://hackmd.io/@yizhewang/HJpQSet_w
沒有留言:
張貼留言