## Vpython-振盪
#### by 蘇昱全 Switch
---
### 第一部分:彈簧
---
### 物理世界
彈簧是一種奇妙的東西,遵守神奇的定律:
***虎克定律***
也就是其恢復力與形變量成正比。
----
其中,我們比較熟悉的應該是\\(F = k\cdot x\\),
其中$k$稱做彈力常數,$x$稱為形變量$\dots \dots$
# 但
這是純量形式
----
我們在VPython的世界裡,絕大多數都是向量
也就是說,原本的虎克定律其實應該長這樣
\\[
\vec{F}=-k\, \cdot \,\vec{x}
\\]
$\vec{x}\,$的意思是形變量的向量,也就是$\vec{l}-\vec{l_0}$
與空氣阻力一樣,負號代表力恆與形變方向相反
但要注意,兩向量的方向都是沿著彈簧的軸的方向
----
### 「質量」的重要性
你會發現,此時彈力\\(\vec{F}\\)就不再與質量有關了,
所以根據牛頓第二運動定律\\(\vec{F}=m\vec{a}\\),
$\vec{a}=\dfrac{\vec{F}}{m}=\dfrac{-k\cdot \vec{x}}{m}$,即質量與加速度成反比。
(這些話好像似曾相識)
(對,~~我從上一篇偷來的~~)
----
### 物理小教室:簡諧運動(S.H.M.)
當一個物體的受力與位移量為一次方關係且方向相反時,此時我們稱此物體進行簡諧運動。
英文:$\text{Simple Harmonic Motion}$
更高階的說法,當一個物體的運動模式(一維)滿足
\\(\overset{\cdot\cdot}{x}+{\omega}^{2} x = 0\\)
此時這個微分方程的解為
\\(x=A\cos (\omega t+\phi)\\)
---
## 實作技巧
----
### 新玩具
標題都叫做彈簧了,當然要來學彈簧
它的對應名稱叫做$\texttt{helix}$,一如既往,參數很多
```
spring = helix(pos=vec(x,y,z),axis=vec(a,b,c),radius=r,thickness=k,coils=t,color)
```
其中各參數的意義如下
----
* $\texttt{pos}$:彈簧「左端點」的位置
* $\texttt{axis}$:彈簧方向(及長度)
* $\texttt{radius}$:彈簧半徑
* $\texttt{thickness}$:彈簧粗細
* $\texttt{coils}$:彈簧匝數
----
幾項小提醒:
1. $\texttt{axis}$的長度將直接代表彈簧的長度,不過你也可以多設定一個$\texttt{length}$來訂定長度
2. 其實很多元素都有$\texttt{axis}$這個參數,你可以用之前的$\texttt{box}$試試看
---
## 實作部分
----
### 實作一:把球黏到彈簧上
----
彈簧跟球終究是兩個不同的物件,VPython也不像Microsoft一樣可以把物件組成群組,那要怎樣確保球一定會在彈簧上呢?
----
我們可以用「彈簧」的參數來定義「物體」的位置
```
spring = helix(pos = vec(x, y, z), axis = vec(a, b, c), radius = r, thickness = k, coils = t, color = color.red)
ball = sphere(pos = spring.pos + spring.axis, ...)
```
這樣就可以直接把球嵌在彈簧裡,而$\texttt{while}$裡,則會用「物體」跟「彈簧」的位置定義$\texttt{axis}$
```
while ...:
...
spring.axis = ball.pos - spring.pos
```
想一想,差異何在?
----
## 實作二:簡諧運動
----
這一次,除了地板以外,我們還需要一道牆,把彈簧貼上去
```
wall = box(pos = vec(-L/2 + 0.05*L/2, 0.05*L/2 + 0.05*L, 0), size = vec(0.05*L, 0.1*L, 0.5*L), color = vec(0.5, 0.5, 0))
```
也要記得定義一個彈簧原長
----
而在操作過程中,你可以給球一個初始速度,或是一個初始位移,讓模型開始振動
----
接下來就是重點,根據公式,\\(\vec{F} = -k\vec{x}\\)
```
while True:
...
spring.axis = ball.pos - spring.pos
F = -k*(mag(spring.axis) - l)*norm(spring.axis)
```
不直接向量相減是避免今天運動不是一維,相減出來的方向就不是彈力方向了,所以一樣的原則:
**計算量值 $\to$ 決定方向**
----
程式碼
```
r = 1
l = 20
L = 40
k = 10
v0 = vec(5, 0, 0)
x0 = vec(0, 0, 0)
m = 1
t = 0
dt = 0.001
scene = canvas(title = "helix", width = 400, height = 400, center = vec(0, 5, 0), background = color.cyan)
flr = box(pos = vec(0, 0, 0), size = vec(L, 0.05*L, 0.5*L), color = vec(0.5, 0.5, 0))
wall = box(pos = vec(-L/2 + 0.05*L/2, 0.05*L/2 + 0.05*L, 0), size = vec(0.05*L, 0.1*L, 0.5*L), color = vec(0.5, 0.5, 0))
spring = helix(pos = wall.pos, axis = vec(l, 0, 0), radius = r, coils = l/(2*0.1*l), thickness = 0.5*r, color = color.red)
ball = sphere(pos = spring.pos + spring.axis + x0, radius = r + 1, v = v0, a = vec(0, 0, 0), texture = textures.wood)
while True:
rate(1/dt)
spring.axis = ball.pos - spring.pos
F = -k*(mag(spring.axis) - l)*norm(spring.axis)
ball.a = F/m
ball.v += ball.a*dt
ball.pos += ball.v*dt
t += dt
```
---
[成果展示](https://www.glowscript.org/#/user/andysu960816/folder/MyPrograms/program/helix)
---
# 謝謝大家
{"title":"Vpython-振盪(一)","contributors":"[{\"id\":\"084e105f-92be-4605-b399-8d3c0ef40c64\",\"add\":5154,\"del\":2021}]","description":"彈簧是一種奇妙的東西,遵守神奇的定律:虎克定律也就是其恢復力與形變量成正比。"}