Try   HackMD

擺線與軌跡 VPython 版

作者:王一哲
日期:2020/10/30


前言

我在上一篇文章〈擺線與軌跡〉中說明使用 GeoGebra 繪製擺線的方法,這次我改用 VPython 畫出純滾動的圓柱上某個點的軌跡,一樣可以畫出擺線。以下是使用 VPython 模擬的畫面截圖以及 GlowScript 網站動畫連結

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
使用 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(tsin(t)), y=r(1cos(t)),但在這個動畫中的起始位置為
(0.5rL,r)
,需要將算式修改成第25、26行的樣子。其中 t 個這變數已經被用來作為時間,因此程式碼中使用了另一個變數 tmp。

假設取 num = 500,利用 for 迴圈將500個點代入參數式中計算對應的位置,再將位置儲存到串列 data 當中。為了計算出純滾動的點對應的位置,先將圓柱前進的距離

L2r 除以速度 v 得到前進的時間,再將時間除以週期 T 得到經過的週期次數,每經過一個週期對應的角度為
2π
,最後將所有對應的角度除以取點數 num、乘上點的索引值 i。


畫面設定

  1. 第36、37行:產生圓柱體 circ,為了比較容易看出圓柱旋轉的效果,建議採用貼圖材質而不是指定顏色。
  2. 第38、39行:產生標示軌跡用的點,為了簡化計算位置的算式,建議將半徑設定為0,再用 trail_radius=0.05*r 設定軌跡的半徑即可。
  3. 第42行:使用 curve 物件繪製擺線理論值。

物體運動

  1. 第49行:將圓柱的中心向右平移一段距離 v*dt。
  2. 第50行:將圓柱旋轉一個角度 omega*dt,預設的轉軸方向為自己的軸方向,預設的旋轉中心為自己的位置,如果寫成以下這樣效果相等。
    ​​​​circ.rotate(angle=omega*dt, axis=vec(0, 0, -1), origin=circ.pos)
    
  3. 第51行:將點的位置向右平移一段距離 v*dt。
  4. 第52行:將點繞著圓柱中心旋轉一個角度 omega*dt。

結語

VPython 有將多個物件合併為一個物件的功能 (compound),合併之後這幾個物件可以一起移動,但是這樣就沒辦法畫出其中一個物件的軌跡,將圓柱和圓周上的點分開處理會比較方便。此外,由於 VPython 動畫為了表現出立體感,畫面的兩側會有點變形,畫出來的擺線看起來會和平面上的擺線有點不一樣,這是無法避免的。



tags:VPython