在 NumPy 中確定靜態平衡#

在分析物理結構時,了解使其保持穩定的力學原理至關重要。施加在地板、樑或任何其他結構上的力會產生反作用力和力矩。這些反作用力是結構在不破壞的情況下抵抗移動的力量。在結構即使受到力作用也不會移動的情況下,牛頓第二定律指出,系統中所有方向的加速度和力總和都必須為零。您可以使用 NumPy 陣列來表示和解決這個概念。

您將會做什麼:#

  • 在本教學中,您將使用 NumPy 透過 NumPy 陣列建立向量和力矩

  • 解決涉及電纜和地板支撐結構的問題

  • 編寫 NumPy 矩陣以隔離未知數

  • 使用 NumPy 函數執行線性代數運算

您將會學到什麼:#

  • 如何使用 NumPy 表示點、向量和力矩。

  • 如何找到向量的法線

  • 使用 NumPy 計算矩陣運算

您需要的東西:#

使用以下指令匯入

import numpy as np
import matplotlib.pyplot as plt

在本教學中,您將使用以下 NumPy 工具

使用牛頓第二定律解靜態平衡#

您的模型包含一個樑,樑上作用著力和力矩的總和。您可以從牛頓第二定律開始分析這個系統

\[\sum{\text{力}} = \text{質量} \times \text{加速度}.\]

為了簡化所檢視的範例,假設它們是靜態的,加速度 \(=0\)。由於我們的系統存在於三個維度中,因此請考慮在每個維度中施加的力。這表示您可以將這些力表示為向量。對於力矩,您也可以得出相同的結論,力矩是從距離物體質心一定距離處施加的力產生的。

假設力 \(F\) 表示為三維向量

\[F = (F_x, F_y, F_z)\]

其中三個分量中的每一個都表示在每個對應方向上施加的力的大小。也假設向量中的每個分量

\[r = (r_x, r_y, r_z)\]

是力各分量的施力點與系統形心之間的距離。那麼,力矩可以透過以下方式計算

\[r \times F = (r_x, r_y, r_z) \times (F_x, F_y, F_z).\]

從一些簡單的力向量範例開始

forceA = np.array([1, 0, 0])
forceB = np.array([0, 1, 0])
print("Force A =", forceA)
print("Force B =", forceB)
Force A = [1 0 0]
Force B = [0 1 0]

這將 forceA 定義為在 \(x\) 方向上大小為 1 的向量,將 forceB 定義為在 \(y\) 方向上大小為 1 的向量。

視覺化這些力可能有助於更好地了解它們如何相互作用。Matplotlib 是一個具有視覺化工具的函式庫,可用於此目的。Quiver 圖將用於示範三維向量,但該函式庫也可用於二維示範

fig = plt.figure()

d3 = fig.add_subplot(projection="3d")

d3.set_xlim(-1, 1)
d3.set_ylim(-1, 1)
d3.set_zlim(-1, 1)

x, y, z = np.array([0, 0, 0])  # defining the point of application.  Make it the origin

u, v, w = forceA  # breaking the force vector into individual components
d3.quiver(x, y, z, u, v, w, color="r", label="forceA")

u, v, w = forceB
d3.quiver(x, y, z, u, v, w, color="b", label="forceB")

plt.legend()
plt.show()
../_images/c7651372231d591461078eafb0c196d44432b3ca068fbd04f750a7811581c8b5.png

有兩個力從一個點發出。為了簡化這個問題,您可以將它們加在一起以找到力的總和。請注意,forceAforceB 都是三維向量,NumPy 將其表示為具有三個分量的陣列。由於 NumPy 旨在簡化和最佳化向量之間的運算,因此您可以輕鬆地計算這兩個向量的總和,如下所示

forceC = forceA + forceB
print("Force C =", forceC)
Force C = [1 1 0]

力 C 現在充當代表 A 和 B 的單個力。您可以繪製它以查看結果。

fig = plt.figure()

d3 = fig.add_subplot(projection="3d")

d3.set_xlim(-1, 1)
d3.set_ylim(-1, 1)
d3.set_zlim(-1, 1)

x, y, z = np.array([0, 0, 0])

u, v, w = forceA
d3.quiver(x, y, z, u, v, w, color="r", label="forceA")
u, v, w = forceB
d3.quiver(x, y, z, u, v, w, color="b", label="forceB")
u, v, w = forceC
d3.quiver(x, y, z, u, v, w, color="g", label="forceC")

plt.legend()
plt.show()
../_images/112d32efc8c6d7f6aaaaa87942381d1d384d310443a829e28328872ff885d100.png

但是,目標是平衡。這表示您希望力的總和為 \((0, 0, 0)\),否則您的物體將會經歷加速度。因此,需要有另一個力來抵消先前的力。

您可以將此問題寫成 \(A+B+R=0\),其中 \(R\) 是解決問題的反作用力。

在此範例中,這表示

\[(1, 0, 0) + (0, 1, 0) + (R_x, R_y, R_z) = (0, 0, 0)\]

分解為 \(x\)\(y\)\(z\) 分量,這會給您

\[\begin{split}\begin{cases} 1+0+R_x=0\\ 0+1+R_y=0\\ 0+0+R_z=0 \end{cases}\end{split}\]

求解 \(R_x\)\(R_y\)\(R_z\) 會給您向量 \(R\),即 \((-1, -1, 0)\)

如果繪製出來,先前範例中看到的力應該會被抵消。只有在沒有剩餘力的情況下,系統才被視為處於平衡狀態。

R = np.array([-1, -1, 0])

fig = plt.figure()

d3.set_xlim(-1, 1)
d3.set_ylim(-1, 1)
d3.set_zlim(-1, 1)

d3 = fig.add_subplot(projection="3d")

x, y, z = np.array([0, 0, 0])

u, v, w = forceA + forceB + R  # add them all together for sum of forces
d3.quiver(x, y, z, u, v, w)

plt.show()
../_images/012531526a9f68790dbf2195c8f3af4722d4f1e064e28c2bb57849ea2eb7e54e.png

空白圖形表示沒有異常力。這表示系統處於平衡狀態。

將平衡解為力矩總和#

接下來,讓我們進入更複雜的應用。當力不是都施加在同一個點時,就會產生力矩。

與力類似,這些力矩的總和也必須為零,否則會產生旋轉加速度。與力總和類似,這會為空間中三個座標方向中的每一個建立線性方程式。

一個簡單的範例是將力施加到固定在地面的靜止桿上。桿子不會移動,因此它必須施加反作用力。桿子也不會旋轉,因此它也必須產生反作用力矩。求解反作用力和力矩。

假設在桿子底部上方 2 公尺處垂直施加 5 牛頓的力。

f = 5  # Force in newtons
L = 2  # Length of the pole

R = 0 - f
M = 0 - f * L
print("Reaction force =", R)
print("Reaction moment =", M)
Reaction force = -5
Reaction moment = -10

尋找具有物理性質的值#

假設力不是垂直作用於樑上,而是透過也連接到地面的電線施加到桿子上。給定此繩索的張力,您只需解決此問題的物件的物理位置即可。

Image representing the problem

為了響應作用在桿子上的力,底部在 x 和 y 方向產生反作用力,以及反作用力矩。

將桿子的底部表示為原點。現在,假設繩索連接到地面,在 x 方向上 3 公尺處,並連接到桿子,在 z 方向上 2 公尺處。

將這些點在空間中定義為 NumPy 陣列,然後使用這些陣列尋找方向向量。

poleBase = np.array([0, 0, 0])
cordBase = np.array([3, 0, 0])
cordConnection = np.array([0, 0, 2])

poleDirection = cordConnection - poleBase
print("Pole direction =", poleDirection)
cordDirection = cordBase - cordConnection
print("Cord direction =", cordDirection)
Pole direction = [0 0 2]
Cord direction = [ 3  0 -2]

為了在與力相關的方面使用這些向量,您需要將它們轉換為單位向量。單位向量的大小為 1,並且僅傳達力的方向。

cordUnit = cordDirection / np.linalg.norm(cordDirection)
print("Cord unit vector =", cordUnit)
Cord unit vector = [ 0.83205029  0.         -0.5547002 ]

然後,您可以將此方向乘以力的大小,以找到力向量。

假設繩索的張力為 5 牛頓

cordTension = 5
forceCord = cordUnit * cordTension
print("Force from the cord =", forceCord)
Force from the cord = [ 4.16025147  0.         -2.77350098]

為了找到力矩,您需要力向量和半徑的外積。

momentCord = np.cross(forceCord, poleDirection)
print("Moment from the cord =", momentCord)
Moment from the cord = [ 0.         -8.32050294  0.        ]

現在您只需要找到反作用力和力矩即可。

equilibrium = np.array([0, 0, 0])
R = equilibrium - forceCord
M = equilibrium - momentCord
print("Reaction force =", R)
print("Reaction moment =", M)
Reaction force = [-4.16025147  0.          2.77350098]
Reaction moment = [0.         8.32050294 0.        ]

另一個範例#

讓我們看看稍微複雜的模型。在此範例中,您將觀察一個樑,該樑具有兩條電纜和一個施加的力。這次您需要找到繩索中的張力和樑的反作用力。(來源:Vector Mechanics for Engineers: Statics,問題 4.106)

image.png

將距離 a 定義為 3 公尺

和以前一樣,首先將每個相關點的位置定義為陣列。

A = np.array([0, 0, 0])
B = np.array([0, 3, 0])
C = np.array([0, 6, 0])
D = np.array([1.5, 0, -3])
E = np.array([1.5, 0, 3])
F = np.array([-3, 0, 2])

從這些方程式開始,您可以使用單位向量確定向量方向。

AB = B - C
AC = C - A
BD = D - B
BE = E - B
CF = F - C

UnitBD = BD / np.linalg.norm(BD)
UnitBE = BE / np.linalg.norm(BE)
UnitCF = CF / np.linalg.norm(CF)

RadBD = np.cross(AB, UnitBD)
RadBE = np.cross(AB, UnitBE)
RadCF = np.cross(AC, UnitCF)

這可讓您將作用在系統上的張力 (T) 和反作用力 (R) 表示為

\[\begin{split}\left[ \begin{array} ~1/3 & 1/3 & 1 & 0 & 0\\ -2/3 & -2/3 & 0 & 1 & 0\\ -2/3 & 2/3 & 0 & 0 & 1\\ \end{array} \right] \left[ \begin{array} ~T_{BD}\\ T_{BE}\\ R_{x}\\ R_{y}\\ R_{z}\\ \end{array} \right] = \left[ \begin{array} ~195\\ 390\\ -130\\ \end{array} \right]\end{split}\]

力矩為

\[\begin{split}\left[ \begin{array} ~2 & -2\\ 1 & 1\\ \end{array} \right] \left[ \begin{array} ~T_{BD}\\ T_{BE}\\ \end{array} \right] = \left[ \begin{array} ~780\\ 1170\\ \end{array} \right]\end{split}\]

其中 \(T\) 是各個繩索中的張力,\(R\) 是各個方向上的反作用力。然後您只有六個方程式

\(\sum F_{x} = 0 = T_{BE}/3+T_{BD}/3-195+R_{x}\)

\(\sum F_{y} = 0 = (-\frac{2}{3})T_{BE}-\frac{2}{3}T_{BD}-390+R_{y}\)

\(\sum F_{z} = 0 = (-\frac{2}{3})T_{BE}+\frac{2}{3}T_{BD}+130+R_{z}\)

\(\sum M_{x} = 0 = 780+2T_{BE}-2T_{BD}\)

\(\sum M_{z} = 0 = 1170-T_{BE}-T_{BD}\)

您現在有五個未知數和五個方程式,可以求解

\(\ T_{BD} = 780N\)

\(\ T_{BE} = 390N\)

\(\ R_{x} = -195N\)

\(\ R_{y} = 1170N\)

\(\ R_{z} = 130N\)

總結#

您已經學習了如何使用陣列來表示三維空間中的點、力和力矩。陣列中的每個條目都可用於表示分解為方向分量的物理性質。然後可以使用 NumPy 函數輕鬆地操作它們。

其他應用#

相同的過程可以應用於動力學問題或任意維度。本教學中完成的範例假設了靜態平衡中的三維問題。這些方法可以輕鬆地用於更多樣化的問題。更多或更少的維度需要更大或更小的陣列來表示。在經歷加速度的系統中,速度和加速度也可以類似地表示為向量。

參考文獻#

  1. Vector Mechanics for Engineers: Statics (Beer & Johnston & Mazurek)

  2. NumPy 參考文獻