SymPy 1.13 中文文档(三十一)
向量:运动学
原文链接:
docs.sympy.org/latest/modules/physics/vector/kinematics.html
本文将为描述系统运动学背景及如何在sympy.physics.vector中表示运动学提供一些数学背景。
运动学介绍
第一个主题是刚体运动学。刚体是具有质量和转动惯量的物理对象的理想化表示。显然,刚体不是柔软的。我们可以将刚体运动分解为平移运动和旋转运动(在处理粒子时,我们只有平移运动)。旋转运动可以进一步分解为简单旋转和一般旋转。
刚体的平移是指在运动过程中,物体的方向不会改变;或者在运动过程中,任何线段在运动开始时都将保持平行于自身。
简单旋转是指物体的方向可能会改变,但总有一条线段在运动开始时保持平行于自身。
一般旋转是指在运动开始时并不总有一条线段平行于自身。
角速度
刚体的角速度是指其方向变化率。刚体的角速度写为:(^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}}),或者是(\mathbf{B})在(\mathbf{N})中的角速度,它是一个向量。请注意,这里使用了刚体这个术语,但参考系也可以有角速度。在描述代码表示时,稍后将进一步讨论刚体和参考系之间的区别。
角速度被定义为引起方向角增加的方向上为正(对于简单旋转或一系列简单旋转)。
B N ny nx nz nx NwB=q nx
角速度矢量表示方向的时间导数。作为时间导数矢量量,就像矢量和参考框架文档中所涵盖的那些一样,这个量(角速度)需要在一个参考框架中定义。这就是上述角速度定义中的 (\mathbf{N});角速度在其中定义的框架。
(\mathbf{N}) 中的 (\mathbf{B}) 的角速度也可以定义为:
[^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}} = (\frac{^{\mathbf{N}}d \mathbf{\hat{b}_y}}{dt}\cdot\mathbf{\hat{b}_z} )\mathbf{\hat{b}_x} + (\frac{^{\mathbf{N}}d \mathbf{\hat{b}_z}}{dt}\cdot \mathbf{\hat{b}_x})\mathbf{\hat{b}_y} + (\frac{^{\mathbf{N}}d \mathbf{\hat{b}_x}}{dt}\cdot\mathbf{\hat{b}_y})\mathbf{\hat{b}_z}]
一个物体的角速度通常也可以写成:
[^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}} = w_x \mathbf{\hat{b}_x} + w_y \mathbf{\hat{b}_y} + w_z \mathbf{\hat{b}_z}]
关于角速度还有一些额外重要的点。首先是角速度的加法定理,一种关联多个物体和参考系角速度的方式。该定理如下:
[^{\mathbf{N}}\mathbf{\omega}^{\mathbf{D}} = ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{A}} + ^{\mathbf{A}}\mathbf{\omega}^{\mathbf{B}} + ^{\mathbf{B}}\mathbf{\omega}^{\mathbf{C}} + ^{\mathbf{C}}\mathbf{\omega}^{\mathbf{D}}]
这也可以在以下示例中看到:
nx ny nz q1 q2 q3 ax bz cy A B C D N[\begin{split}^{\mathbf{N}}\mathbf{\omega}^{\mathbf{A}} &= 0\ ^{\mathbf{A}}\mathbf{\omega}^{\mathbf{B}} &= \dot{q_1} \mathbf{\hat{a}_x}\ ^{\mathbf{B}}\mathbf{\omega}^{\mathbf{C}} &= - \dot{q_2} \mathbf{\hat{b}_z}\ ^{\mathbf{C}}\mathbf{\omega}^{\mathbf{D}} &= \dot{q_3} \mathbf{\hat{c}_y}\ ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{D}} &= \dot{q_1} \mathbf{\hat{a}_x} - \dot{q_2} \mathbf{\hat{b}_z} + \dot{q_3} \mathbf{\hat{c}_y}\\end{split}]
注意角速度定义中使用的符号,这些符号与在这种情况下如何定义位移角有关。
该定理使得定义多体系统的角速度变得更加简单,因为链中每个体的角速度只需相对于前一个体定义即可(并且第一个体需要在所需的参考系中定义)。下图展示了使用该定理可以简化问题的示例。
image/svg+xml p1 w1 w2 p2 p3 w3
在这里,我们可以轻松地写出物体(\mathbf{D})在第一个物体(\mathbf{A})的参考系中的角速度:
[\begin{split}^\mathbf{A}\mathbf{\omega}^\mathbf{D} = w_1 \mathbf{\hat{p_1}} + w_2 \mathbf{\hat{p_2}} + w_3 \mathbf{\hat{p_3}}\\end{split}]
记住,只能用于角速度;不能用于点的速度。
还有一个常用的定理:导数定理。它提供了一种替代方法(可能更容易)来计算参考系中向量的时间导数:
[\frac{^{\mathbf{N}} d \mathbf{v}}{dt} = \frac{^{\mathbf{B}} d \mathbf{v}}{dt} + ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}} \times \mathbf{v}]
向量(\mathbf{v})可以是任何向量量:位置向量,速度向量,角速度向量等。而不是在(\mathbf{N})中取向量的时间导数,我们在(\mathbf{B})中取它,其中(\mathbf{B})可以是任何参考系或物体,通常是在其中容易对(\mathbf{v})取导数的一个。然后我们加上我们新参考系的角速度的叉乘积,(^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}}) 和我们的向量量(\mathbf{v})。同样,你可以为此选择任何替代参考系。以下是例子:
角加速度
角加速度指的是角速度向量的时间变化率。正如角速度向量是对于一个物体的,并且在一个参考系中指定一样,角加速度向量也是对于一个物体的,并且在一个参考系中指定:(^{\mathbf{N}}\mathbf{\alpha}^{\mathbf{B}}),或者是(\mathbf{B})在(\mathbf{N})中的角加速度,这是一个向量。
计算角加速度相对直接了当:
[^{\mathbf{N}}\mathbf{\alpha}^{\mathbf{B}} = \frac{^{\mathbf{N}} d ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}}}{dt}]
注意,可以用导数定理计算这个,当角速度在一个固定于物体的参考系中定义时,变得相当简单:
[ \begin{align}\begin{aligned}\begin{split}^{\mathbf{N}}\mathbf{\alpha}^{\mathbf{B}} &= \frac{^{\mathbf{N}} d ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}}}{dt}\\end{split}\\begin{split}^{\mathbf{N}}\mathbf{\alpha}^{\mathbf{B}} &= \frac{^{\mathbf{B}} d ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}}}{dt} + ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}} \times ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}}\\end{split}\\begin{split}\textrm{如果 } ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}} &= w_x \mathbf{\hat{b}_x} + w_y \mathbf{\hat{b}_y} + w_z \mathbf{\hat{b}z}\\end{split}\\begin{split}\textrm{那么 } ^{\mathbf{N}}\mathbf{\alpha}^{\mathbf{B}} &= \frac{^{\mathbf{B}} d ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}}}{dt} + \underbrace{^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}} \times ^{\mathbf{N}}\mathbf{\omega}^{\mathbf{B}}}{ \textrm{根据定义,这是 0}}\\end{split}\\begin{split}^{\mathbf{N}}\mathbf{\alpha}^{\mathbf{B}}&=\frac{d w_x}{dt}\mathbf{\hat{b}_x} + \frac{d w_y}{dt}\mathbf{\hat{b}_y} + \frac{d w_z}{dt}\mathbf{\hat{b}_z}\\end{split}\\begin{split}^{\mathbf{N}}\mathbf{\alpha}^{\mathbf{B}}&= \dot{w_x}\mathbf{\hat{b}_x} + \dot{w_y}\mathbf{\hat{b}_y} + \dot{w_z}\mathbf{\hat{b}_z}\\end{split}\end{aligned}\end{align} ]
再次强调,这仅适用于身体固定分量定义了角速度的情况。
点速度与加速度
考虑一个点 (P):我们可以定义该点的一些特性。首先,我们可以定义从其他点到 (P) 的位置矢量。其次,我们可以定义 (P) 在我们选择的参考系中的速度矢量。第三,我们可以定义 (P) 在我们选择的参考系中的加速度矢量。
这三个量读作:
[\begin{split}\mathbf{r}^{OP} \textrm{,从 } O \textrm{ 到 } P \textrm{ 的位置矢量}\ ^{\mathbf{N}}\mathbf{v}^P \textrm{,点 } P \textrm{ 在参考系 } \mathbf{N} \textrm{ 中的速度}\ ^{\mathbf{N}}\mathbf{a}^P \textrm{,点 } P \textrm{ 在参考系 } \mathbf{N} \textrm{ 中的加速度}\\end{split}]
注意,位置矢量没有与之关联的参考系;这是因为与速度和加速度矢量不同,它没有涉及时间导数。
对于一个简单的例子,我们可以轻松找到这些量。
image/svg+xml P O N rOP[\begin{split}\textrm{Let's define: } \mathbf{r}^{OP} &= q_x \mathbf{\hat{n}_x} + q_y \mathbf{\hat{n}_y}\ ^{\mathbf{N}}\mathbf{v}^P &= \frac{^{\mathbf{N}} d \mathbf{r}^{OP}}{dt}\ \textrm{then we can calculate: } ^{\mathbf{N}}\mathbf{v}^P &= \dot{q}_x\mathbf{\hat{n}_x} + \dot{q}_y\mathbf{\hat{n}_y}\ \textrm{and :} ^{\mathbf{N}}\mathbf{a}^P &= \frac{^{\mathbf{N}} d ^{\mathbf{N}}\mathbf{v}^P}{dt}\ ^{\mathbf{N}}\mathbf{a}^P &= \ddot{q}_x\mathbf{\hat{n}_x} + \ddot{q}_y\mathbf{\hat{n}_y}\\end{split}]
- 上述例子中,理解点 (O) 在参考系 (\mathbf{N}) 中固定是至关重要的。对于平移速度没有加法定理;后续将讨论替代方法。同时注意,不一定需要定义每个点的位置矢量来形成动力学运动方程。当你不想定义一个点的位置矢量时,可以先定义速度矢量。对于上述例子:
[\begin{split}\textrm{我们可以将速度向量定义为: } ^{\mathbf{N}}\mathbf{v}^P &= u_x \mathbf{\hat{n}_x} + u_y \mathbf{\hat{n}_y}\ \textrm{那么加速度可以写为: } ^{\mathbf{N}}\mathbf{a}^P &= \dot{u}_x \mathbf{\hat{n}_x} + \dot{u}_y \mathbf{\hat{n}_y}\\end{split}]
- 通常情况下,我们需要一个点的速度,同时已知相关点的速度。对于刚体上两个固定点的情况,我们使用 2 点定理:
image/svg+xml N B Ofixed in N Pfixed in B Sfixed in B
假设我们知道点(S)的速度和物体(\mathbf{B})的角速度,两者均定义在参考系(\mathbf{N})中。我们可以计算点(P)在(\mathbf{N})中的速度和加速度如下:
[\begin{split}^{\mathbf{N}}\mathbf{v}^P &= ^\mathbf{N}\mathbf{v}^S + ^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times \mathbf{r}^{SP}\ ^{\mathbf{N}}\mathbf{a}^P &= ^\mathbf{N}\mathbf{a}^S + ^\mathbf{N}\mathbf{\alpha}^\mathbf{B} \times \mathbf{r}^{SP} + ^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times (^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times \mathbf{r}^{SP})\\end{split}]
当两点中只有一个固定在物体上时,使用 1 点定理。
image/svg+xml B N O在 N 中固定 P在 B 中不固定 S在 B 中固定
在这里,点(S)的速度在参考系(\mathbf{N})中已知,(\mathbf{B})的角速度在(\mathbf{N})中已知,并且点(P)在与刚体(\mathbf{B})相关联的参考系中的速度也已知。因此,我们可以写出点(P)在(\mathbf{N})中的速度和加速度:
[ \begin{align}\begin{aligned}\begin{split}^{\mathbf{N}}\mathbf{v}^P &= ^\mathbf{B}\mathbf{v}^P + ^\mathbf{N}\mathbf{v}^S + ^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times \mathbf{r}^{SP}\\end{split}\\begin{split}^{\mathbf{N}}\mathbf{a}^P &= ^\mathbf{B}\mathbf{a}^S + ^\mathbf{N}\mathbf{a}^O + ^\mathbf{N}\mathbf{\alpha}^\mathbf{B} \times \mathbf{r}^{SP} + ^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times (^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times \mathbf{r}^{SP}) + 2 ^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times ^\mathbf{B} \mathbf{v}^P \\end{split}\end{aligned}\end{align} ]
应用一点定理和二点定理的示例。
image/svg+xml N nx ny nz B O P bz by bx rOP
本例中,一个圆盘在平面内进行平移和旋转。我们可以很容易地定义身体(\mathbf{B})的角速度和点(O)的速度:
[\begin{split}^\mathbf{N}\mathbf{\omega}^\mathbf{B} &= u_3 \mathbf{\hat{n}_z} = u_3 \mathbf{\hat{b}_z}\ ^\mathbf{N}\mathbf{v}^O &= u_1 \mathbf{\hat{n}_x} + u_2 \mathbf{\hat{n}_y}\\end{split}]
并且加速度可以写成:
[\begin{split}^\mathbf{N}\mathbf{\alpha}^\mathbf{B} &= \dot{u_3} \mathbf{\hat{n}_z} = \dot{u_3} \mathbf{\hat{b}_z}\ ^\mathbf{N}\mathbf{a}^O &= \dot{u_1} \mathbf{\hat{n}_x} + \dot{u_2} \mathbf{\hat{n}_y}\\end{split}]
现在我们可以使用两点定理来计算点(P)的速度和加速度。
[\begin{split}\mathbf{r}^{OP} &= R \mathbf{\hat{b}_x}\ ^\mathbf{N}\mathbf{v}^P &= ^\mathbf{N}\mathbf{v}^O + ^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times \mathbf{r}^{OP}\ ^\mathbf{N}\mathbf{v}^P &= u_1 \mathbf{\hat{n}_x} + u_2 \mathbf{\hat{n}_y} + u_3 \mathbf{\hat{b}_z} \times R \mathbf{\hat{b}_x} = u_1 \mathbf{\hat{n}_x} + u_2 \mathbf{\hat{n}_y} + u_3 R \mathbf{\hat{b}_y}\ ^{\mathbf{N}}\mathbf{a}^P &= ^\mathbf{N}\mathbf{a}^O + ^\mathbf{N}\mathbf{\alpha}^\mathbf{B} \times \mathbf{r}^{OP} + ^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times (^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times \mathbf{r}^{OP})\ ^{\mathbf{N}}\mathbf{a}^P &= \dot{u_1} \mathbf{\hat{n}_x} + \dot{u_2} \mathbf{\hat{n}_y} + \dot{u_3}\mathbf{\hat{b}_z}\times R \mathbf{\hat{b}_x} +u_3\mathbf{\hat{b}_z}\times(u_3\mathbf{\hat{b}_z}\times R\mathbf{\hat{b}_x})\ ^{\mathbf{N}}\mathbf{a}^P &= \dot{u_1} \mathbf{\hat{n}_x} + \dot{u_2} \mathbf{\hat{n}_y} + R\dot{u_3}\mathbf{\hat{b}_y} - R u_3² \mathbf{\hat{b}_x}\\end{split}]image/svg+xml nx ny bx by cx cy P Q <text xml:space="preserve" style="font-size:10px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:CurrentColor;fill-opacity:1;stroke:none;font-family:Skia;-inkscape-font-specification:Skia Bold" x="59.618443" y="935.51007"
在这个例子中,我们有一个双摆。我们可以在这里两次使用两点定理来找到点 (Q) 和 (P) 的速度;点 (O) 在 (\mathbf{N}) 中的速度为零。
[\begin{split}\mathbf{r}^{OQ} &= l \mathbf{\hat{b}_x}\ \mathbf{r}^{QP} &= l \mathbf{\hat{c}_x}\ ^\mathbf{N}\mathbf{\omega}^\mathbf{B} &= u_1 \mathbf{\hat{b}_z}\ ^\mathbf{N}\mathbf{\omega}^\mathbf{C} &= u_2 \mathbf{\hat{c}_z}\ ^\mathbf{N}\mathbf{v}^Q &= ^\mathbf{N}\mathbf{v}^O + ^\mathbf{N}\mathbf{\omega}^\mathbf{B} \times \mathbf{r}^{OQ}\ ^\mathbf{N}\mathbf{v}^Q &= u_1 l \mathbf{\hat{b}_y}\ ^\mathbf{N}\mathbf{v}^P &= ^\mathbf{N}\mathbf{v}^Q + ^\mathbf{N}\mathbf{\omega}^\mathbf{C} \times \mathbf{r}^{QP}\ ^\mathbf{N}\mathbf{v}^Q &= u_1 l \mathbf{\hat{b}_y} +u_2 \mathbf{\hat{c}_z} \times l \mathbf{\hat{c}_x}\ ^\mathbf{N}\mathbf{v}^Q &= u_1 l\mathbf{\hat{b}_y}+u_2 l\mathbf{\hat{c}_y}\\end{split}]image/svg+xml O P Q nx nz ny q1 q2 c<tspan style="font-size:65
在这个例子中,我们有一个粒子在环上运动;环由一个可以绕着(\mathbf{\hat{n}_x})轴旋转的杆支持。首先我们使用两点定理来找到环的中心点(Q)的速度,然后使用单点定理来找到环上粒子的速度。
[\begin{split}^\mathbf{N}\mathbf{\omega}^\mathbf{C} &= u_1 \mathbf{\hat{n}_x}\ \mathbf{r}^{OQ} &= -l \mathbf{\hat{c}_z}\ ^\mathbf{N}\mathbf{v}^Q &= u_1 l \mathbf{\hat{c}_y}\ \mathbf{r}^{QP} &= R(cos(q_2) \mathbf{\hat{c}_x} + sin(q_2) \mathbf{\hat{c}_y} )\ ^\mathbf{C}\mathbf{v}^P &= R u_2 (-sin(q_2) \mathbf{\hat{c}_x} + cos(q_2) \mathbf{\hat{c}_y} )\ ^\mathbf{N}\mathbf{v}^P &= ^\mathbf{C}\mathbf{v}^P +^\mathbf{N}\mathbf{v}^Q + ^\mathbf{N}\mathbf{\omega}^\mathbf{C} \times \mathbf{r}^{QP}\ ^\mathbf{N}\mathbf{v}^P &= R u_2 (-sin(q_2) \mathbf{\hat{c}_x} + cos(q_2) \mathbf{\hat{c}_y} ) + u_1 l \mathbf{\hat{c}_y} + u_1 \mathbf{\hat{c}_x} \times R(cos(q_2) \mathbf{\hat{c}_x} + sin(q_2) \mathbf{\hat{c}_y}\ ^\mathbf{N}\mathbf{v}^P &= - R u_2 sin(q_2) \mathbf{\hat{c}_x} + (R u_2 cos(q_2)+u_1 l)\mathbf{\hat{c}_y} + R u_1 sin(q_2) \mathbf{\hat{c}_z}\\end{split}]
描述点速度的最后一个主题是滚动,或者更确切地说,是不打滑地滚动。如果两个物体在另一个参考系中接触点的速度相同,则称它们是不打滑地滚动。参见下图:
这里是 SVG 标签中文本框的内容。
这通常用于形成一个物体上的点在另一个固定物体上滚动的速度,例如以下示例:
物理学中的运动学
现在应该清楚,这里的运动学主题主要描述了正确操作向量以表示点的速度的方式。在sympy.physics.vector中,有方便的方法来存储这些与参考系和点相关的速度。我们现在将重新访问上述示例,并展示如何在sympy中表示它们。
参考系创建的主题已经涵盖过了。但是,当创建ReferenceFrame时,它会自动使用 DCM 的时间导数和角速度定义来计算参考系的角速度。
>>> from sympy import Symbol, sin, cos
>>> from sympy.physics.vector import *
>>> init_vprinting(pretty_print=False)
>>> N = ReferenceFrame('N')
>>> q1 = dynamicsymbols('q1')
>>> A = N.orientnew('A', 'Axis', [q1, N.x])
>>> A.ang_vel_in(N)
q1'*N.x
注意,角速度可以以另一种方式定义:
>>> B = ReferenceFrame('B')
>>> u1 = dynamicsymbols('u1')
>>> B.set_ang_vel(N, u1 * B.y)
>>> B.ang_vel_in(N)
u1*B.y
>>> N.ang_vel_in(B)
- u1*B.y
在orientnew期间创建参考系和调用set_ang_vel时,如上所示,角速度在涉及的两个参考系中都设置了。
nx ny nz q1 q2 q3 ax bz cy A B C D N
这里我们有多个与彼此相关联的角速度定义的物体。这被编码为:
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> B = ReferenceFrame('B')
>>> C = ReferenceFrame('C')
>>> D = ReferenceFrame('D')
>>> u1, u2, u3 = dynamicsymbols('u1 u2 u3')
>>> A.set_ang_vel(N, 0)
>>> B.set_ang_vel(A, u1 * A.x)
>>> C.set_ang_vel(B, -u2 * B.z)
>>> D.set_ang_vel(C, u3 * C.y)
>>> D.ang_vel_in(N)
u1*A.x - u2*B.z + u3*C.y
在 sympy.physics.vector 中,在查找角速度时使用两个框架之间的最短路径。这意味着,如果我们回去并设置:
>>> D.set_ang_vel(N, 0)
>>> D.ang_vel_in(N)
0
刚刚定义的路径是使用的路径。然而,这可能会导致问题,因为现在角速度的定义不一致。建议避免这样做。
Points 是与旋转 ReferenceFrame 对应的平移模拟。创建一个 Point 可以通过两种方式完成,就像 ReferenceFrame 一样:
>>> O = Point('O')
>>> P = O.locatenew('P', 3 * N.x + N.y)
>>> P.pos_from(O)
3*N.x + N.y
>>> Q = Point('Q')
>>> Q.set_pos(P, N.z)
>>> Q.pos_from(P)
N.z
>>> Q.pos_from(O)
3*N.x + N.y + N.z
类似于 ReferenceFrame,两点之间的位置矢量是通过它们之间的最短路径(中间点的数量)找到的。与旋转运动不同的是,点的速度没有加法定理。为了在 ReferenceFrame 中有一个 Point 的速度,您必须设置该值。
>>> O = Point('O')
>>> O.set_vel(N, u1*N.x)
>>> O.vel(N)
u1*N.x
对于平移和旋转加速度,值是通过取适当速度的时间导数来计算的,除非用户另行设置。
>>> O.acc(N)
u1'*N.x
>>> O.set_acc(N, u2*u1*N.y)
>>> O.acc(N)
u1*u2*N.y
接下来是关于 sympy 中使用的两点和一点定理的描述。
image/svg+xml N nx ny nz B O P bz by bx rOP
首先是翻译、旋转的盘片。
>>> N = ReferenceFrame('N')
>>> u1, u2, u3 = dynamicsymbols('u1 u2 u3')
>>> R = Symbol('R')
>>> B = ReferenceFrame('B')
>>> O = Point('O')
>>> O.set_vel(N, u1 * N.x + u2 * N.y)
>>> P = O.locatenew('P', R * B.x)
>>> B.set_ang_vel(N, u3 * B.z)
>>> P.v2pt_theory(O, N, B)
u1*N.x + u2*N.y + R*u3*B.y
>>> P.a2pt_theory(O, N, B)
u1'*N.x + u2'*N.y - R*u3**2*B.x + R*u3'*B.y
我们还将涵盖 1 点定理的实现。
image/svg+xml O P Q nx nz ny q1 q2 cx cy <tspan sodipodi:role="line" id="tspan3519" x="184.87874" y="262.48218" style="font-size
这是粒子再次在一个环上运动。
>>> N = ReferenceFrame('N')
>>> u1, u2 = dynamicsymbols('u1 u2')
>>> q1, q2 = dynamicsymbols('q1 q2')
>>> l = Symbol('l')
>>> R = Symbol('R')
>>> C = N.orientnew('C', 'Axis', [q1, N.x])
>>> C.set_ang_vel(N, u1 * N.x)
>>> O = Point('O')
>>> O.set_vel(N, 0)
>>> Q = O.locatenew('Q', -l * C.z)
>>> P = Q.locatenew('P', R * (cos(q2) * C.x + sin(q2) * C.y))
>>> P.set_vel(C, R * u2 * (-sin(q2) * C.x + cos(q2) * C.y))
>>> Q.v2pt_theory(O, N, C)
l*u1*C.y
>>> P.v1pt_theory(Q, N, C)
- R*u2*sin(q2)*C.x + (R*u2*cos(q2) + l*u1)*C.y + R*u1*sin(q2)*C.z
物理学中的潜在问题/高级主题/未来功能/向量模块
原文链接:
docs.sympy.org/latest/modules/physics/vector/advanced.html
本文将描述此模块提供但不是“官方”接口的一些更高级功能。此外,将涵盖一些将来将实施的功能,以及关于正确功能的未解答问题。还将讨论常见问题及其解决方案。
二元向量
在 sympy.physics.mechanics 中,二元用于表示惯性 ([Kane1985], [WikiDyadics], [WikiDyadicProducts])。二元是由分量单位二元的线性多项式,类似于向量是由分量单位向量的线性多项式。二元是两个向量的外积,返回一个新的量,表示这两个向量的并置。例如:
[\begin{split}\mathbf{\hat{a}_x} \otimes \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x} \mathbf{\hat{a}_x}\ \mathbf{\hat{a}_x} \otimes \mathbf{\hat{a}_y} &= \mathbf{\hat{a}_x} \mathbf{\hat{a}_y}\\end{split}]
其中 (\mathbf{\hat{a}_x}\mathbf{\hat{a}_x}) 和 (\mathbf{\hat{a}_x}\mathbf{\hat{a}_y}) 是通过将左侧作为列向量乘以右侧作为行向量获得的外积。注意顺序很重要。
一些二元向量的额外属性包括:
[\begin{split}(x \mathbf{v}) \otimes \mathbf{w} &= \mathbf{v} \otimes (x \mathbf{w}) = x (\mathbf{v} \otimes \mathbf{w})\ \mathbf{v} \otimes (\mathbf{w} + \mathbf{u}) &= \mathbf{v} \otimes \mathbf{w} + \mathbf{v} \otimes \mathbf{u}\ (\mathbf{v} + \mathbf{w}) \otimes \mathbf{u} &= \mathbf{v} \otimes \mathbf{u} + \mathbf{w} \otimes \mathbf{u}\\end{split}]
参考系中的向量可以表示为 (\begin{bmatrix}a\b\c\end{bmatrix}) 或 (a \mathbf{\hat{i}} + b \mathbf{\hat{j}} + c \mathbf{\hat{k}})。类似地,二元可以用张量形式表示:
[\begin{split}\begin{bmatrix} a_{11} & a_{12} & a_{13} \ a_{21} & a_{22} & a_{23} \ a_{31} & a_{32} & a_{33} \end{bmatrix}\\end{split}]
或以二元形式:
[\begin{split}a_{11} \mathbf{\hat{a}_x}\mathbf{\hat{a}x} + a{12} \mathbf{\hat{a}_x}\mathbf{\hat{a}y} + a{13} \mathbf{\hat{a}_x}\mathbf{\hat{a}z} + a{21} \mathbf{\hat{a}_y}\mathbf{\hat{a}x} + a{22} \mathbf{\hat{a}_y}\mathbf{\hat{a}y} + a{23} \mathbf{\hat{a}_y}\mathbf{\hat{a}z} + a{31} \mathbf{\hat{a}_z}\mathbf{\hat{a}x} + a{32} \mathbf{\hat{a}_z}\mathbf{\hat{a}y} + a{33} \mathbf{\hat{a}_z}\mathbf{\hat{a}_z}\\end{split}]
就像向量一样,后续的表示使得可以跟踪张量与哪些参考系有关。此外,张量每项的两个分量不必在同一个参考系中。以下是有效的:
[\mathbf{\hat{a}_x} \otimes \mathbf{\hat{b}_y} = \mathbf{\hat{a}_x} \mathbf{\hat{b}_y}]
二阶张量也可以与向量进行叉乘和点乘;再次强调顺序的重要性:
[\begin{split}\mathbf{\hat{a}_x}\mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x}\ \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x} &= \mathbf{\hat{a}_y}\ \mathbf{\hat{a}_x}\mathbf{\hat{a}_y} \cdot \mathbf{\hat{a}_x} &= 0\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x}\mathbf{\hat{a}_x} &= \mathbf{\hat{a}_x}\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_x}\mathbf{\hat{a}_y} &= \mathbf{\hat{a}_y}\ \mathbf{\hat{a}_x} \cdot \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} &= 0\ \mathbf{\hat{a}_x} \times \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} &= \mathbf{\hat{a}_z}\mathbf{\hat{a}_x}\ \mathbf{\hat{a}_x} \times \mathbf{\hat{a}_x}\mathbf{\hat{a}_x} &= 0\ \mathbf{\hat{a}_y}\mathbf{\hat{a}_x} \times \mathbf{\hat{a}_z} &= - \mathbf{\hat{a}_y}\mathbf{\hat{a}_y}\\end{split}]
你也可以对二阶张量进行时间导数,或者在不同参考系中表示它们,就像对向量一样。
常见问题
在这里,可能会出现与数值积分代码、坐标和速度表示的 dynamicsymbols 选择、打印、微分和替换相关的问题。
打印
默认的打印选项是对Vector和Dyadic测量数使用排序,并且从vprint、vpprint和vlatex函数有未排序的输出。如果要打印大量内容,请使用这些函数之一,因为排序可能会将打印时间从几秒钟增加到几分钟。
替换
替换到大表达式中可能会很慢,并且需要几分钟的时间。
点的加速度
至少,点需要定义它们的速度,因为加速度可以通过在相同参考系中对速度的时间导数来计算。如果使用一点或两点定理来计算速度,那么速度表达式的时间导数很可能比使用一级和二级定理来计算的更复杂。使用加速度级别的方法可以在这一点上导致较短的表达式,这将在形成 Kane 方程时导致较短的表达式。
高级接口
这里我们将涵盖ReferenceFrame、dynamicsymbols和一些相关功能的高级选项。
参考系
ReferenceFrame 被显示为具有 .name 属性和 .x, .y, 和 .z 属性用于访问基向量,并且有一个相当严格定义的打印输出。如果你希望有一个不同的索引集定义,这也是可以的。这也将需要一个不同的接口来访问基向量。
>>> from sympy.physics.vector import ReferenceFrame, vprint, vpprint, vlatex
>>> N = ReferenceFrame('N', indices=['i', 'j', 'k'])
>>> N['i']
N['i']
>>> N.x
N['i']
>>> vlatex(N.x)
'\\mathbf{\\hat{n}_{i}}'
此外,latex 输出可以有自定义字符串;而不仅仅是指标,每个基向量的整体都可以指定。自定义 latex 字符串可以不带自定义指标而发生,也覆盖了如果有自定义指标则将使用的 latex 字符串。
>>> from sympy.physics.vector import ReferenceFrame, vlatex
>>> N = ReferenceFrame('N', latexs=['n1','\\mathbf{n}_2','cat'])
>>> vlatex(N.x)
'n1'
>>> vlatex(N.y)
'\\mathbf{n}_2'
>>> vlatex(N.z)
'cat'
动态符号
dynamicsymbols函数还具有‘隐藏’功能;与时间相关联的变量可以更改,以及用于打印导数的符号。
>>> from sympy import symbols
>>> from sympy.physics.vector import dynamicsymbols, vprint
>>> q1 = dynamicsymbols('q1')
>>> q1
q1(t)
>>> dynamicsymbols._t = symbols('T')
>>> q2 = dynamicsymbols('q2')
>>> q2
q2(T)
>>> q1
q1(t)
>>> q1d = dynamicsymbols('q1', 1)
>>> vprint(q1d)
q1'
>>> dynamicsymbols._str = 'd'
>>> vprint(q1d)
q1d
>>> dynamicsymbols._str = '\''
>>> dynamicsymbols._t = symbols('t')
注意,仅在更改后创建的动态符号不同。这对于(._str)属性并非如此;这仅影响打印输出,因此在更改前后创建的动态符号将以相同的方式打印。
还要注意,Vector的.dt方法使用dynamicsymbols的._t属性,以及其他一些重要的函数和方法。不要混合表示时间的符号。
解向量方程
要解决涉及向量的方程,不能直接使用向量上的解函数。相反,必须将向量转换为一组标量方程。
假设我们有两个框架N和A,其中A相对于N绕 z 轴旋转 30 度。
>>> from sympy import pi, symbols, solve
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame("N")
>>> A = ReferenceFrame("A")
>>> A.orient_axis(N, pi / 6, N.z)
假设我们有两个向量v1和v2,它们用不同的符号表示相同的向量。
>>> v1x, v1y, v1z = symbols("v1x v1y v1z")
>>> v2x, v2y, v2z = symbols("v2x v2y v2z")
>>> v1 = v1x * N.x + v1y * N.y + v1z * N.z
>>> v2 = v2x * A.x + v2y * A.y + v2z * A.z
我们的目标是找到v2中使用的符号与v1中使用的符号之间的关系。我们可以通过将向量转换为矩阵,然后使用sympy.solvers.solvers.solve()来实现这一点。
>>> solve((v1 - v2).to_matrix(N), [v2x, v2y, v2z])
{v2x: sqrt(3)*v1x/2 + v1y/2, v2y: -v1x/2 + sqrt(3)*v1y/2, v2z: v1z}
标量和矢量场功能
介绍
矢量和标量
在物理学中,我们处理两种量 - 标量和矢量。
标量是仅具有大小而没有方向的实体。标量量例如质量、电荷、温度、距离等。
另一方面,矢量是由大小和方向特征的实体。矢量量的例子包括位移、速度、磁场等。
标量可以仅用一个数字表示,例如 300K 的温度。另一方面,矢量量如加速度通常用矢量表示。给定一个矢量(\mathbf{V}),相应量的大小可以通过矢量本身的大小(\Vert \mathbf{V} \Vert)计算,而方向则由原始矢量方向上的单位矢量指定,(\mathbf{\hat{V}} = \frac{\mathbf{V}}{\Vert \mathbf{V} \Vert})。
例如,考虑位移为((3\mathbf{\hat{i}} + 4\mathbf{\hat{j}} + 5\mathbf{\hat{k}}))米,其中,按照标准惯例,(\mathbf{\hat{i}})、(\mathbf{\hat{j}})和(\mathbf{\hat{k}})分别代表(\mathbf{X})、(\mathbf{Y})和(\mathbf{Z})方向的单位矢量。因此,可以得出行程距离为(\Vert 3\mathbf{\hat{i}} + 4\mathbf{\hat{j}} + 5\mathbf{\hat{k}} \Vert)米 = (5\sqrt{2})米。行进方向由单位矢量(\frac{3}{5\sqrt{2}}\mathbf{\hat{i}} + \frac{4}{5\sqrt{2}}\mathbf{\hat{j}} + \frac{5}{5\sqrt{2}}\mathbf{\hat{k}})给出。
场
一般来说,一个(场)是可以作为位置函数在空间中的每个位置指定的矢量或标量量(注意,通常情况下场也可能依赖于时间和其他自定义变量)。在本模块中,我们只处理三维空间。因此,场被定义为(x)、(y)和(z)坐标的函数,对应于 3D 空间中的位置。
例如,三维空间中的温度(温度场)可以写为(T(x, y, z)) - 位置的标量函数。在电磁学中标量场的例子是电势。
类似地,矢量场可以定义为空间中任意点((x, y, z))位置的矢量函数。
例如,地球上的每一点都可以看作处于地球的重力场中。我们可以通过每个空间点处的加速度(即单位质量的力)(g(x, y, z))的大小和方向来指定场。
举例来说,考虑一个电动势形式为(2{x}^{2}y)的电势标量场在三维空间中。相应的保守电场可以计算为电势函数的梯度,并表示为(4xy\mathbf{\hat{i}} + 2{x}^{2}\mathbf{\hat{j}})。这个电场的大小可以进一步表示为形如(\sqrt{4{x}^{4} + 16{x}^{2}{y}^{2}})的标量场。
在sympy.physics.vector中的场的实现
在sympy.physics.vector模块中,每个ReferenceFrame实例都被分配了对应于(X)、(Y)和(Z)方向的基向量。这些可以通过分别命名为x、y和z的属性来访问。因此,要在给定的参考框架(\mathbf{R})中定义形式为(3\mathbf{\hat{i}} + 4\mathbf{\hat{j}} + 5\mathbf{\hat{k}})的向量(\mathbf{v}),你可以这样做:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> v = 3*R.x + 4*R.y + 5*R.z
有关向量及其对应的基本微积分操作,本模块文档的其他部分已经有详细阐述。
另一方面,基标量(或坐标变量)被实现为分配给每个参考框架的特殊 SymPy Symbol,每个方向从(X)、(Y)和(Z)各有一个。对于框架R,(X)、(Y)和(Z)基标量Symbol可以分别通过R[0]、R[1]和R[2]表达式访问。
因此,要生成上述电势场(2{x}^{2}y)的表达式,你需要这样做:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> electric_potential = 2*R[0]**2*R[1]
>>> electric_potential
2*R_x**2*R_y
在字符串表示中,R_x表示分配给ReferenceFrame R的(X)基标量。实质上,R_x是R[0]的字符串表示。
标量场可以像任何其他 SymPy 表达式一样用于任何数学/微积分功能。因此,要相对于(x)(即R[0])对上述电势进行微分,你需要使用diff函数。
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> electric_potential = 2*R[0]**2*R[1]
>>> from sympy import diff
>>> diff(electric_potential, R[0])
4*R_x*R_y
与向量(和向量场)类似,标量场也可以在除定义它们的框架之外的其他参考框架中重新表达,假设所涉及的框架之间存在方向关系。这可以使用sympy.physics.vector.vector.Vector.express方法完成,方法类似于向量,但variables参数设置为True。
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> electric_potential = 2*R[0]**2*R[1]
>>> from sympy.physics.vector import dynamicsymbols, express
>>> q = dynamicsymbols('q')
>>> R1 = R.orientnew('R1', rot_type = 'Axis', amounts = [q, R.z])
>>> express(electric_potential, R1, variables=True)
2*(R1_x*sin(q(t)) + R1_y*cos(q(t)))*(R1_x*cos(q(t)) - R1_y*sin(q(t)))**2
此外,考虑到标量也可以是时间的函数,就像矢量一样,可以进行时间微分。根据表达式中的Symbol和进行时间微分的参考框架,输出会改变/保持不变。
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> electric_potential = 2*R[0]**2*R[1]
>>> q = dynamicsymbols('q')
>>> R1 = R.orientnew('R1', rot_type = 'Axis', amounts = [q, R.z])
>>> from sympy.physics.vector import time_derivative
>>> time_derivative(electric_potential, R)
0
>>> time_derivative(electric_potential, R1).simplify()
2*(R1_x*cos(q(t)) - R1_y*sin(q(t)))*(3*R1_x**2*cos(2*q(t))/2 -
R1_x**2/2 - 3*R1_x*R1_y*sin(2*q(t)) - 3*R1_y**2*cos(2*q(t))/2 -
R1_y**2/2)*Derivative(q(t), t)
场算符和其他相关函数
这里我们描述了在 sympy.physics.vector 中实现的一些基本与场相关的功能。
旋度
旋度是描述三维空间中矢量微小旋转的数学算子。方向由右手法则(沿着旋转轴)确定,幅度由旋转的大小给出。
在 3D 笛卡尔系统中,三维矢量( \mathbf{F} )的旋度,记作( \nabla \times \mathbf{F} ),由以下公式给出 -
( \nabla \times \mathbf{F} = \left(\frac{\partial F_z}{\partial y} - \frac{\partial F_y}{\partial z}\right) \mathbf{\hat{i}} + \left(\frac{\partial F_x}{\partial z} - \frac{\partial F_z}{\partial x}\right) \mathbf{\hat{j}} + \left(\frac{\partial F_y}{\partial x} - \frac{\partial F_x}{\partial y}\right) \mathbf{\hat{k}} )
其中( F_x )表示矢量( \mathbf{F} )的( X )分量。
在sympy.physics.vector中计算矢量场的旋度,您可以执行以下操作:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> from sympy.physics.vector import curl
>>> field = R[0]*R[1]*R[2]*R.x
>>> curl(field, R)
R_x*R_y*R.y - R_x*R_z*R.z
散度
散度是一个矢量算子,用于衡量矢量场在给定点的源或汇的大小,以有符号标量形式表示。
散度算子在作用于矢量后始终返回一个标量。
在 3D 笛卡尔系统中,三维矢量( \mathbf{F} )的散度,记作( \nabla\cdot\mathbf{F} ),由以下公式给出 -
( \nabla\cdot\mathbf{F} = \frac{\partial U}{\partial x} + \frac{\partial V}{\partial y} + \frac{\partial W}{\partial z } )
其中( U ),( V )和( W )分别表示( \mathbf{F} )的( X ),( Y )和( Z )分量。
在sympy.physics.vector中计算矢量场的散度,您可以执行以下操作:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> from sympy.physics.vector import divergence
>>> field = R[0]*R[1]*R[2] * (R.x+R.y+R.z)
>>> divergence(field, R)
R_x*R_y + R_x*R_z + R_y*R_z
梯度
考虑在三维空间中的标量场( f(x, y, z) )。该场的梯度定义为关于( X ),( Y )和( Z )方向上( f )的三个偏导数的向量。
在 3D 笛卡尔系统中,标量场( f )的梯度,记作( \nabla f ),由以下公式给出 -
( \nabla f = \frac{\partial f}{\partial x} \mathbf{\hat{i}} + \frac{\partial f}{\partial y} \mathbf{\hat{j}} + \frac{\partial f}{\partial z} \mathbf{\hat{k}} )
在sympy.physics.vector中计算标量场的梯度,您可以执行以下操作:
>>> from sympy.physics.vector import ReferenceFrame
>>> R = ReferenceFrame('R')
>>> from sympy.physics.vector import gradient
>>> scalar_field = R[0]*R[1]*R[2]
>>> gradient(scalar_field, R)
R_y*R_z*R.x + R_x*R_z*R.y + R_x*R_y*R.z
保守与旋度场
在向量微积分中,保守场是某个标量场的梯度。保守场具有这样的性质,即其沿任意路径的线积分仅依赖于端点,并且与路径本身无关。保守矢量场也被称为‘无旋场’,因为保守场的旋度始终为零。
在物理学中,保守场代表能量守恒的物理系统中的力。
若要检查向量场在 sympy.physics.vector 中是否为保守场,请使用 sympy.physics.vector.fieldfunctions.is_conservative 函数。
>>> from sympy.physics.vector import ReferenceFrame, is_conservative
>>> R = ReferenceFrame('R')
>>> field = R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z
>>> is_conservative(field)
True
>>> curl(field, R)
0
另一方面,旋量场是指其在空间中所有点的散度均为零的向量场。
若要检查向量场在 sympy.physics.vector 中是否为旋量场,请使用 sympy.physics.vector.fieldfunctions.is_solenoidal 函数。
>>> from sympy.physics.vector import ReferenceFrame, is_solenoidal
>>> R = ReferenceFrame('R')
>>> field = R[1]*R[2]*R.x + R[0]*R[2]*R.y + R[0]*R[1]*R.z
>>> is_solenoidal(field)
True
>>> divergence(field, R)
0
标量势函数
我们之前提到,每个保守场都可以被定义为某个标量场的梯度。这个标量场也被称为与前述保守场对应的‘标量势场’。
sympy.physics.vector.fieldfunctions.scalar_potential 函数在 sympy.physics.vector 中计算给定三维空间中保守矢量场对应的标量势场 - 当然要减去积分的额外常数。
使用示例 -
>>> from sympy.physics.vector import ReferenceFrame, scalar_potential
>>> R = ReferenceFrame('R')
>>> conservative_field = 4*R[0]*R[1]*R[2]*R.x + 2*R[0]**2*R[2]*R.y + 2*R[0]**2*R[1]*R.z
>>> scalar_potential(conservative_field, R)
2*R_x**2*R_y*R_z
将非保守矢量场作为参数提供给 sympy.physics.vector.fieldfunctions.scalar_potential 会引发 ValueError。
对应于保守矢量场的标量势差,或简称‘势差’,可以定义为空间中两点处其标量势函数值的差。这在计算关于保守函数的线积分中非常有用,因为它仅依赖于路径的端点。
在 sympy.physics.vector 中,该计算执行如下。
>>> from sympy.physics.vector import ReferenceFrame, Point
>>> from sympy.physics.vector import scalar_potential_difference
>>> R = ReferenceFrame('R')
>>> O = Point('O')
>>> P = O.locatenew('P', 1*R.x + 2*R.y + 3*R.z)
>>> vectfield = 4*R[0]*R[1]*R.x + 2*R[0]**2*R.y
>>> scalar_potential_difference(vectfield, R, O, P, O)
4
如果提供的是标量表达式而不是矢量场,sympy.physics.vector.fieldfunctions.scalar_potential_difference 返回空间中两个给定点处该标量场值的差异。
物理矢量 API
原文:
docs.sympy.org/latest/modules/physics/vector/api/index.html
-
基本类
-
运动学(文档字符串)
-
打印(文档字符串)
-
基本函数(文档字符串)
-
基本场函数的文档字符串
关键类
原文:
docs.sympy.org/latest/modules/physics/vector/api/classes.html
class sympy.physics.vector.frame.CoordinateSym(name, frame, index)
与参考框架相关的坐标符号/基量标量。
理想情况下,用户不应该实例化这个类。这个类的实例必须仅通过相应的框架作为‘frame[index]’来访问。
具有相同框架和索引参数的 CoordinateSyms 是相等的(即使它们可能是分别实例化的)。
参数:
name:字符串
CoordinateSym 的显示名称
frame:ReferenceFrame
此基量标量所属的参考框架
index:0、1 或 2
由此坐标变量表示的维度的索引
示例
>>> from sympy.physics.vector import ReferenceFrame, CoordinateSym
>>> A = ReferenceFrame('A')
>>> A[1]
A_y
>>> type(A[0])
<class 'sympy.physics.vector.frame.CoordinateSym'>
>>> a_y = CoordinateSym('a_y', A, 1)
>>> a_y == A[1]
True
class sympy.physics.vector.frame.ReferenceFrame(name, indices=None, latexs=None, variables=None)
经典力学中的参考框架。
ReferenceFrame 是用于表示经典力学中参考框架的类。它在框架的 x、y 和 z 方向具有标准基向量。
它也可以相对于父框架进行旋转;这种旋转由一个方向余弦矩阵定义,将该框架的基向量与父框架的基向量相关联。它还可以具有在另一个框架中定义的角速度矢量。
ang_acc_in(otherframe)
返回参考框架的角加速度矢量。
有效地返回矢量:
N_alpha_B
其中 N 表示 B 在 N 中的角加速度,其中 B 是自身,N 是 otherframe。
参数:
otherframe:ReferenceFrame
返回角加速度的 ReferenceFrame。
示例
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_acc(N, V)
>>> A.ang_acc_in(N)
10*N.x
ang_vel_in(otherframe)
返回参考框架的角速度矢量。
有效地返回矢量:
^N omega ^B
其中 N 表示 B 在 N 中的角速度,其中 B 是自身,N 是 otherframe。
参数:
otherframe:ReferenceFrame
返回角速度的 ReferenceFrame。
示例
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_vel(N, V)
>>> A.ang_vel_in(N)
10*N.x
dcm(otherframe)
返回相对于提供的参考框架的此参考框架的方向余弦矩阵。
返回的矩阵可用于用otherframe的正交单位向量表示该框架的正交单位向量。
参数:
otherframe:ReferenceFrame
形成此框架的方向余弦矩阵相对于的参考框架。
示例
以下示例通过简单旋转将参考框架 A 相对于 N 旋转,然后计算 N 相对于 A 的方向余弦矩阵。
>>> from sympy import symbols, sin, cos
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> A.orient_axis(N, q1, N.x)
>>> N.dcm(A)
Matrix([
[1, 0, 0],
[0, cos(q1), -sin(q1)],
[0, sin(q1), cos(q1)]])
上述方向余弦矩阵的第二行表示在 A 中表示的 N.y 单位向量N.y。如下所示:
>>> Ny = 0*A.x + cos(q1)*A.y - sin(q1)*A.z
因此,在 A 中表达N.y应该返回相同的结果:
>>> N.y.express(A)
cos(q1)*A.y - sin(q1)*A.z
注释
知道返回的方向余弦矩阵的形式很重要。如果调用B.dcm(A),表示“B 相对于 A 旋转的方向余弦矩阵”。这是下面关系中显示的矩阵 ({}^B\mathbf{C}^A):
[\begin{split}\begin{bmatrix} \hat{\mathbf{b}}_1 \ \hat{\mathbf{b}}_2 \ \hat{\mathbf{b}}_3 \end{bmatrix} = {}^B\mathbf{C}^A \begin{bmatrix} \hat{\mathbf{a}}_1 \ \hat{\mathbf{a}}_2 \ \hat{\mathbf{a}}_3 \end{bmatrix}.\end{split}]
({}^B\mathbf{C}^A)是表达 B 单位向量与 A 单位向量关系的矩阵。
orient(parent, rot_type, amounts, rot_order='')
设置此参考框架相对于另一个(父)参考框架的方向。
注意
现在建议使用.orient_axis, .orient_body_fixed, .orient_space_fixed, .orient_quaternion方法来处理不同的旋转类型。
参数:
parent:参考框架。
将此参考框架旋转到的参考框架。
rot_type:字符串。
生成方向余弦矩阵的方法。支持的方法有:
'Axis':围绕单个共同轴的简单旋转。'DCM':用于直接设置方向余弦矩阵。'Body':围绕新中间轴的三次连续旋转,也称为“欧拉和泰特-布赖恩角”。'Space':围绕父框架单位向量的三次连续旋转。'Quaternion':由四个参数定义的旋转,其结果是一个无奇点的方向余弦矩阵。
amounts:
定义旋转角度或方向余弦矩阵的表达式。这些必须与
rot_type匹配。有关详细信息,请参见下面的示例。输入类型为:
'Axis':2 元组(表达式/符号/函数,矢量)。'DCM':矩阵,形状(3,3)。'Body':三元组表达式、符号或函数。'Space':三元组表达式、符号或函数。'Quaternion':四元组表达式、符号或函数。
rot_order:字符串或整数,可选。
如果适用,表示连续旋转的顺序。例如,字符串
'123'和整数123是等效的。对'Body'和'Space'类型是必需的。
警告:
用户警告
如果方向创建了一个运动学闭环。
orient_axis(parent, axis, angle)
通过绕父参考框架中固定轴旋转角度,设置此参考框架的方向。
参数:
parent:参考框架。
将此参考框架旋转到的参考框架。
axis:矢量。
固定在父框架中的矢量,围绕其旋转的框架。它不需要是单位向量,旋转遵循右手规则。
angle:可合并。
以弧度表示的旋转角度。
警告:
用户警告
如果方向创建了一个运动学闭环。
示例
为示例设置变量:
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B.orient_axis(N, N.x, q1)
orient_axis()方法生成一个方向余弦矩阵及其转置,定义了 B 相对于 N 的方向和反向。一旦调用orient,dcm()输出适当的方向余弦矩阵:
>>> B.dcm(N)
Matrix([
[1, 0, 0],
[0, cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])
>>> N.dcm(B)
Matrix([
[1, 0, 0],
[0, cos(q1), -sin(q1)],
[0, sin(q1), cos(q1)]])
下面两行表明旋转的方向可以通过对向量方向或角度取反来定义。这两行都会产生相同的结果。
>>> B.orient_axis(N, -N.x, q1)
>>> B.orient_axis(N, N.x, -q1)
orient_body_fixed(parent, angles, rotation_order)
将此参考框架相对于父参考框架通过连续的身体固定简单轴旋转右手旋转。每个后续旋转轴围绕新的中间参考框架的“身体固定”单位向量。这种旋转类型也称为绕欧拉和 Tait-Bryan 角度旋转。
该方法中计算的角速度默认以子框架的形式表示,因此最好使用 u1 * child.x + u2 * child.y + u3 * child.z 作为广义速度。
参数:
parent :参考框架
将相对于父参考框架设置此参考框架的方向。
angles :3-tuple of sympifiable
三个用于连续旋转的弧度角。
rotation_order :3 个字符字符串或 3 位整数
关于每个中间参考框架单位向量的旋转顺序。关于 X、Z'、X'' 轴的欧拉旋转可以用字符串
'XZX'、'131'或整数131来指定。有 12 个唯一的有效旋转顺序(6 个欧拉和 6 个 Tait-Bryan):zxz、xyx、yzy、zyz、xzx、yxy、xyz、yzx、zxy、xzy、zyx 和 yxz。
警告:
用户警告
如果方向创建一个运动学环路。
示例
为示例设置变量:
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1, q2, q3 = symbols('q1, q2, q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B1 = ReferenceFrame('B1')
>>> B2 = ReferenceFrame('B2')
>>> B3 = ReferenceFrame('B3')
例如,经典的欧拉角旋转可以通过以下方式完成:
>>> B.orient_body_fixed(N, (q1, q2, q3), 'XYX')
>>> B.dcm(N)
Matrix([
[ cos(q2), sin(q1)*sin(q2), -sin(q2)*cos(q1)],
[sin(q2)*sin(q3), -sin(q1)*sin(q3)*cos(q2) + cos(q1)*cos(q3), sin(q1)*cos(q3) + sin(q3)*cos(q1)*cos(q2)],
[sin(q2)*cos(q3), -sin(q1)*cos(q2)*cos(q3) - sin(q3)*cos(q1), -sin(q1)*sin(q3) + cos(q1)*cos(q2)*cos(q3)]])
这将参考框架 B 相对于参考框架 N 通过 q1 关于 N.x 的旋转,然后再次通过 q2 关于 B.y 的旋转,并最终通过 q3 关于 B.x 的旋转。这相当于三个连续的 orient_axis() 调用:
>>> B1.orient_axis(N, N.x, q1)
>>> B2.orient_axis(B1, B1.y, q2)
>>> B3.orient_axis(B2, B2.x, q3)
>>> B3.dcm(N)
Matrix([
[ cos(q2), sin(q1)*sin(q2), -sin(q2)*cos(q1)],
[sin(q2)*sin(q3), -sin(q1)*sin(q3)*cos(q2) + cos(q1)*cos(q3), sin(q1)*cos(q3) + sin(q3)*cos(q1)*cos(q2)],
[sin(q2)*cos(q3), -sin(q1)*cos(q2)*cos(q3) - sin(q3)*cos(q1), -sin(q1)*sin(q3) + cos(q1)*cos(q2)*cos(q3)]])
可接受的旋转顺序长度为 3,表示为字符串 'XYZ' 或 '123' 或整数 123。禁止连续两次绕一个轴旋转。
>>> B.orient_body_fixed(N, (q1, q2, 0), 'ZXZ')
>>> B.orient_body_fixed(N, (q1, q2, 0), '121')
>>> B.orient_body_fixed(N, (q1, q2, q3), 123)
orient_dcm(parent, dcm)
使用描述从子参考框架到父参考框架的旋转的方向余弦矩阵设置此参考框架的方向。
参数:
parent :参考框架
将相对于另一个(父级)参考框架设置此参考框架的方向。
dcm :矩阵,形状(3, 3)
指定两个参考框架之间相对旋转的方向余弦矩阵。
警告:
用户警告
如果方向创建一个运动学环路。
示例
为示例设置变量:
>>> from sympy import symbols, Matrix, sin, cos
>>> from sympy.physics.vector import ReferenceFrame
>>> q1 = symbols('q1')
>>> A = ReferenceFrame('A')
>>> B = ReferenceFrame('B')
>>> N = ReferenceFrame('N')
简单的相对于 N 关于 N.x 的旋转由以下方向余弦矩阵定义:
>>> dcm = Matrix([[1, 0, 0],
... [0, cos(q1), sin(q1)],
... [0, -sin(q1), cos(q1)]])
>>> A.orient_dcm(N, dcm)
>>> A.dcm(N)
Matrix([
[1, 0, 0],
[0, cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])
这相当于使用 orient_axis():
>>> B.orient_axis(N, N.x, q1)
>>> B.dcm(N)
Matrix([
[1, 0, 0],
[0, cos(q1), sin(q1)],
[0, -sin(q1), cos(q1)]])
orient_quaternion(parent, numbers)
通过方向余弦矩阵设置此参考框架相对于父参考框架的方向。方向余弦矩阵被定义为由角度 theta 的单位向量 (lambda_x, lambda_y, lambda_z) 绕一个轴进行的有限旋转。方向余弦矩阵由四个参数描述:
-
q0 = cos(theta/2) -
q1 = lambda_x*sin(theta/2) -
q2 = lambda_y*sin(theta/2) -
q3 = lambda_z*sin(theta/2)
更多信息请参见四元数和空间旋转在维基百科上。
参数:
parent : ReferenceFrame
将旋转相对于此参考系的参考系。
numbers : sympy 化的 4 元组
四个四元数标量数如上定义:
q0,q1,q2,q3。
警告:
UserWarning
如果方向性创建了一个运动学回路。
示例
设置示例变量:
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
设置方向:
>>> B.orient_quaternion(N, (q0, q1, q2, q3))
>>> B.dcm(N)
Matrix([
[q0**2 + q1**2 - q2**2 - q3**2, 2*q0*q3 + 2*q1*q2, -2*q0*q2 + 2*q1*q3],
[ -2*q0*q3 + 2*q1*q2, q0**2 - q1**2 + q2**2 - q3**2, 2*q0*q1 + 2*q2*q3],
[ 2*q0*q2 + 2*q1*q3, -2*q0*q1 + 2*q2*q3, q0**2 - q1**2 - q2**2 + q3**2]])
orient_space_fixed(parent, angles, rotation_order)
相对于父参考系通过右手侧旋转的三个连续空间固定简单轴旋转旋转此参考系。每个后续旋转轴都是关于父参考系的“空间固定”单位向量。
本方法中计算的角速度默认为在子参考系中表示,因此最好使用u1 * child.x + u2 * child.y + u3 * child.z作为广义速度。
参数:
parent : ReferenceFrame
将旋转相对于此参考系的参考系。
angles : sympy 化的 3 元组
用于连续旋转的三个弧度角。
rotation_order : 3 个字符字符串或 3 位整数
父参考系单位向量的旋转顺序。顺序可以由字符串
'XZX','131'或整数131指定。有 12 个唯一的有效旋转顺序。
警告:
UserWarning
如果方向性创建了一个运动学回路。
示例
设置示例变量:
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> q1, q2, q3 = symbols('q1, q2, q3')
>>> N = ReferenceFrame('N')
>>> B = ReferenceFrame('B')
>>> B1 = ReferenceFrame('B1')
>>> B2 = ReferenceFrame('B2')
>>> B3 = ReferenceFrame('B3')
>>> B.orient_space_fixed(N, (q1, q2, q3), '312')
>>> B.dcm(N)
Matrix([
[ sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1)],
[-sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3)],
[ sin(q3)*cos(q2), -sin(q2), cos(q2)*cos(q3)]])
等价于:
>>> B1.orient_axis(N, N.z, q1)
>>> B2.orient_axis(B1, N.x, q2)
>>> B3.orient_axis(B2, N.y, q3)
>>> B3.dcm(N).simplify()
Matrix([
[ sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3), sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1)],
[-sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1), cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3)],
[ sin(q3)*cos(q2), -sin(q2), cos(q2)*cos(q3)]])
值得注意的是,空间固定和体固定旋转通过旋转顺序相关联,即体固定的逆顺序将给出空间固定,反之亦然。
>>> B.orient_space_fixed(N, (q1, q2, q3), '231')
>>> B.dcm(N)
Matrix([
[cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3), -sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],
[ -sin(q2), cos(q2)*cos(q3), sin(q3)*cos(q2)],
[sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1), sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3)]])
>>> B.orient_body_fixed(N, (q3, q2, q1), '132')
>>> B.dcm(N)
Matrix([
[cos(q1)*cos(q2), sin(q1)*sin(q3) + sin(q2)*cos(q1)*cos(q3), -sin(q1)*cos(q3) + sin(q2)*sin(q3)*cos(q1)],
[ -sin(q2), cos(q2)*cos(q3), sin(q3)*cos(q2)],
[sin(q1)*cos(q2), sin(q1)*sin(q2)*cos(q3) - sin(q3)*cos(q1), sin(q1)*sin(q2)*sin(q3) + cos(q1)*cos(q3)]])
orientnew(newname, rot_type, amounts, rot_order='', variables=None, indices=None, latexs=None)
返回相对于此参考系定向的新参考系。
参见ReferenceFrame.orient(),了解如何定向参考系的详细示例。
参数:
newname : 字符串
新参考系的名称。
rot_type : 字符串
生成方向余弦矩阵的方法。支持的方法有:
'Axis': 简单绕单一公共轴旋转'DCM': 用于直接设置方向余弦矩阵'Body': 关于新中间轴的三个连续旋转,也称为“欧拉和泰特-布赖恩角”'Space': 关于父参考系单位向量的三个连续旋转'Quaternion': 由四个参数定义的旋转,其结果是无奇点的方向余弦矩阵
amounts :
定义旋转角度或方向余弦矩阵的表达式。这些必须与
rot_type匹配。有关详细信息,请参阅下面的示例。
'Axis': 2 元组(表达式/符号/函数,向量)'DCM': 矩阵,形状(3,3)'Body': 表达式、符号或函数的 3 元组'Space': 表达式、符号或函数的 3 元组'Quaternion': 表达式、符号或函数的 4 元组
rot_order : 字符串或整数,可选
如果适用,旋转顺序的顺序。例如字符串
'123'和整数123是等效的。对'Body'和'Space'是必需的。
indices : 字符串元组
使得可以通过 Python 的方括号索引符号访问参考框架的基单位向量,使用提供的三个索引字符串,并修改单元向量的打印以反映此选择。
latexs : 字符串元组
修改参考框架的基单位向量的 LaTeX 打印为提供的三个有效的 LaTeX 字符串。
例子
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame, vlatex
>>> q0, q1, q2, q3 = symbols('q0 q1 q2 q3')
>>> N = ReferenceFrame('N')
创建一个通过简单旋转相对于 N 旋转的新参考框架 A。
>>> A = N.orientnew('A', 'Axis', (q0, N.x))
创建一个通过体固定旋转相对于 N 旋转的新参考框架 B。
>>> B = N.orientnew('B', 'Body', (q1, q2, q3), '123')
创建一个通过简单旋转相对于 N 旋转的新参考框架 C,具有独特的索引和 LaTeX 打印。
>>> C = N.orientnew('C', 'Axis', (q0, N.x), indices=('1', '2', '3'),
... latexs=(r'\hat{\mathbf{c}}_1',r'\hat{\mathbf{c}}_2',
... r'\hat{\mathbf{c}}_3'))
>>> C['1']
C['1']
>>> print(vlatex(C['1']))
\hat{\mathbf{c}}_1
partial_velocity(frame, *gen_speeds)
返回该框架在给定框架中关于一个或多个提供的广义速度的部分角速度。
参数:
frame : 参考框架
定义角速度相对于的框架。
gen_speeds : 时间的函数
广义速度。
返回:
partial_velocities : 向量元组
对应于所提供广义速度的部分角速度向量。
例子
>>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> u1, u2 = dynamicsymbols('u1, u2')
>>> A.set_ang_vel(N, u1 * A.x + u2 * N.y)
>>> A.partial_velocity(N, u1)
A.x
>>> A.partial_velocity(N, u1, u2)
(A.x, N.y)
set_ang_acc(otherframe, value)
在参考框架中定义角加速度向量。
定义该参考框架的角加速度,另一种。 角加速度可以相对于多个不同的参考框架定义。 必须小心,以免创建不一致的循环。
参数:
otherframe : 参考框架
定义角加速度的参考框架
value : 向量
表示角加速度的向量
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_acc(N, V)
>>> A.ang_acc_in(N)
10*N.x
set_ang_vel(otherframe, value)
在参考框架中定义角速度向量。
定义该参考框架的角速度,另一种。 角速度可以相对于多个不同的参考框架定义。 必须小心,以免创建不一致的循环。
参数:
otherframe : 参考框架
定义角速度的参考框架
value : 向量
表示角速度的向量
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> N = ReferenceFrame('N')
>>> A = ReferenceFrame('A')
>>> V = 10 * N.x
>>> A.set_ang_vel(N, V)
>>> A.ang_vel_in(N)
10*N.x
property u
参考框架的单位二重项。
variable_map(otherframe)
返回一个表达该框架的坐标变量与其他框架变量的字典。
如果 Vector.simp 为 True,则返回映射值的简化版本。 否则,返回未简化的值。
简化表达可能需要时间。
参数:
otherframe : 参考框架
映射变量到另一个框架
例子
>>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
>>> A = ReferenceFrame('A')
>>> q = dynamicsymbols('q')
>>> B = A.orientnew('B', 'Axis', [q, A.z])
>>> A.variable_map(B)
{A_x: B_x*cos(q(t)) - B_y*sin(q(t)), A_y: B_x*sin(q(t)) + B_y*cos(q(t)), A_z: B_z}
property x
参考框架中 x 方向的基向量。
property xx
参考框架中基向量 x 和 x 的单位二重项。
property xy
参考框架中基向量 x 和 y 的单位二重项。
property xz
参考框架中基向量 x 和 z 的单位二重项。
property y
参考框架中 y 方向的基向量。
property yx
参考框架中基向量 y 和 x 的单位二重项。
property yy
参考框架中基向量 y 和 y 的单位二重项。
property yz
参考框架中基向量 y 和 z 的单位二重项。
property z
参考框架中 z 方向的基向量。
property zx
参考框架中基向量 z 和 x 的单位二重项。
property zy
与参考框架中基向量 z 和 y 的单位二重
property zz
用于参考框架中基向量 z 和 z 的单位二重
class sympy.physics.vector.vector.Vector(inlist)
用于定义向量的类。
它以及 ReferenceFrame 是在 PyDy 和 sympy.physics.vector 中描述经典力学系统的基本构件。
属性
| simp | (布尔值) 允许某些方法在其输出上使用 trigsimp |
|---|
angle_between(vec)
返回向量 'vec' 和自身之间的最小角度。
警告
Python 忽略前导负号,可能导致错误结果。-A.x.angle_between() 将被处理为 -(A.x.angle_between()),而不是 (-A.x).angle_between()。
参数
vecVector
需要角度的两个向量之间的向量。
示例
>>> from sympy.physics.vector import ReferenceFrame
>>> A = ReferenceFrame("A")
>>> v1 = A.x
>>> v2 = A.y
>>> v1.angle_between(v2)
pi/2
>>> v3 = A.x + A.y + A.z
>>> v1.angle_between(v3)
acos(sqrt(3)/3)
applyfunc(f)
对向量的每个分量应用一个函数。
cross(other)
两个向量的叉乘算子。
返回一个与自身相同参考框架表达的向量。
参数:
other:Vector
我们正在与之交叉的向量
示例
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame, cross
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> cross(N.x, N.y)
N.z
>>> A = ReferenceFrame('A')
>>> A.orient_axis(N, q1, N.x)
>>> cross(A.x, N.y)
N.z
>>> cross(N.y, A.x)
- sin(q1)*A.y - cos(q1)*A.z
diff(var, frame, var_in_dcm=True)
返回相对于所提供参考框架中变量的向量的偏导数。
参数:
var:Symbol
所取偏导数的对象。
frame:ReferenceFrame
在其中进行时间导数计算的参考框架。
var_in_dcm:布尔值
如果为 true,则差异化算法假定该变量可能存在于将框架与向量任何分量的框架相关联的方向余弦矩阵中。但如果已知该变量不存在于方向余弦矩阵中,则可以设置 false 以跳过完全重新表达为所需框架。
示例
>>> from sympy import Symbol
>>> from sympy.physics.vector import dynamicsymbols, ReferenceFrame
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> t = Symbol('t')
>>> q1 = dynamicsymbols('q1')
>>> N = ReferenceFrame('N')
>>> A = N.orientnew('A', 'Axis', [q1, N.y])
>>> A.x.diff(t, N)
- sin(q1)*q1'*N.x - cos(q1)*q1'*N.z
>>> A.x.diff(t, N).express(A).simplify()
- q1'*A.z
>>> B = ReferenceFrame('B')
>>> u1, u2 = dynamicsymbols('u1, u2')
>>> v = u1 * A.x + u2 * B.y
>>> v.diff(u2, N, var_in_dcm=False)
B.y
doit(**hints)
在向量的每个项上调用 .doit()
dot(other)
两个向量的点积。
返回一个标量,两个向量的点积
参数:
other:Vector
我们正在与之做点乘的向量
示例
>>> from sympy.physics.vector import ReferenceFrame, dot
>>> from sympy import symbols
>>> q1 = symbols('q1')
>>> N = ReferenceFrame('N')
>>> dot(N.x, N.x)
1
>>> dot(N.x, N.y)
0
>>> A = N.orientnew('A', 'Axis', [q1, N.x])
>>> dot(N.y, A.y)
cos(q1)
dt(otherframe)
返回一个在其他帧中时间导数的向量。
调用全局 time_derivative 方法
参数:
otherframe:ReferenceFrame
计算时间导数的框架
express(otherframe, variables=False)
返回等效于此向量的向量,表达为 otherframe。使用全局 express 方法。
参数:
otherframe:ReferenceFrame
描述此向量的帧
variables:布尔值
如果为 True,则此向量中的坐标符号(如果存在)将重新表达为其他帧的术语
示例
>>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> q1 = dynamicsymbols('q1')
>>> N = ReferenceFrame('N')
>>> A = N.orientnew('A', 'Axis', [q1, N.y])
>>> A.x.express(N)
cos(q1)*N.x - sin(q1)*N.z
free_dynamicsymbols(reference_frame)
返回在给定参考框架中表达的向量中的自由动态符号(时间函数 t)。
参数:
reference_frame:ReferenceFrame
要确定给定向量的自由动态符号的框架。
返回:
set
时间函数
t的集合,例如Function('f')(me.dynamicsymbols._t)。
free_symbols(reference_frame)
返回在给定参考框架中表达的向量的测量数字中的自由符号。
参数:
reference_frame:ReferenceFrame
要确定给定向量自由符号的框架。
返回:
一组 Symbol
表达参考框架的测量数中存在的符号集。
property func
返回类向量。
magnitude()
返回自身的大小(欧几里得范数)。
警告
Python 忽略了前导负号,这可能导致错误的结果。-A.x.magnitude() 会被视为 -(A.x.magnitude()),而不是 (-A.x).magnitude()。
normalize()
返回大小为 1、与自身共向的向量。
outer(other)
两个向量之间的外积。
一个增加秩的操作,从两个向量返回一个二元组
参数:
其他 : 向量
与向量进行外积。
例子
>>> from sympy.physics.vector import ReferenceFrame, outer
>>> N = ReferenceFrame('N')
>>> outer(N.x, N.x)
(N.x|N.x)
separate()
根据其定义,这个向量在不同参考框架中的组成部分。
返回将每个参考框架映射到相应组成向量的字典。
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> R1 = ReferenceFrame('R1')
>>> R2 = ReferenceFrame('R2')
>>> v = R1.x + R2.x
>>> v.separate() == {R1: R1.x, R2: R2.x}
True
simplify()
返回一个简化的向量。
subs(*args, **kwargs)
对向量进行替换。
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> from sympy import Symbol
>>> N = ReferenceFrame('N')
>>> s = Symbol('s')
>>> a = N.x * s
>>> a.subs({s: 2})
2*N.x
to_matrix(reference_frame)
返回给定框架下向量的矩阵形式。
参数:
参考框架 : 参考框架
矩阵的行对应的参考框架。
返回:
矩阵 : 不可变矩阵,形状(3,1)
提供给 1D 向量的矩阵。
例子
>>> from sympy import symbols
>>> from sympy.physics.vector import ReferenceFrame
>>> a, b, c = symbols('a, b, c')
>>> N = ReferenceFrame('N')
>>> vector = a * N.x + b * N.y + c * N.z
>>> vector.to_matrix(N)
Matrix([
[a],
[b],
[c]])
>>> beta = symbols('beta')
>>> A = N.orientnew('A', 'Axis', (beta, N.x))
>>> vector.to_matrix(A)
Matrix([
[ a],
[ b*cos(beta) + c*sin(beta)],
[-b*sin(beta) + c*cos(beta)]])
xreplace(rule)
替换向量的测量数内的对象出现。
参数:
规则 : 类似字典
表达替换规则。
返回:
向量
替换结果。
例子
>>> from sympy import symbols, pi
>>> from sympy.physics.vector import ReferenceFrame
>>> A = ReferenceFrame('A')
>>> x, y, z = symbols('x y z')
>>> ((1 + x*y) * A.x).xreplace({x: pi})
(pi*y + 1)*A.x
>>> ((1 + x*y) * A.x).xreplace({x: pi, y: 2})
(1 + 2*pi)*A.x
仅当匹配表达树中的整个节点时才进行替换:
>>> ((x*y + z) * A.x).xreplace({x*y: pi})
(z + pi)*A.x
>>> ((x*y*z) * A.x).xreplace({x*y: pi})
x*y*z*A.x
class sympy.physics.vector.dyadic.Dyadic(inlist)
一个二元组对象。
见:en.wikipedia.org/wiki/Dyadic_tensor Kane, T., Levinson, D. Dynamics Theory and Applications. 1985 McGraw-Hill
更强大地表示刚体的惯性的一种方法。虽然更复杂,但通过选择二元组的分量为体固定基向量,得到的矩阵等效于惯性张量。
applyfunc(f)
对二元组的每个分量应用函数。
cross(other)
返回二元组与向量的叉积结果:二元组 x 向量。
参数:
其他 : 向量
与之交叉的向量。
例子
>>> from sympy.physics.vector import ReferenceFrame, outer, cross
>>> N = ReferenceFrame('N')
>>> d = outer(N.x, N.x)
>>> cross(d, N.y)
(N.x|N.z)
doit(**hints)
对二元组中的每个项调用 .doit()
dot(other)
二元组和二元组或向量的内积运算符。
参数:
其他 : 二元组或向量
与二元组或向量进行内积的其他二元组或向量
例子
>>> from sympy.physics.vector import ReferenceFrame, outer
>>> N = ReferenceFrame('N')
>>> D1 = outer(N.x, N.y)
>>> D2 = outer(N.y, N.y)
>>> D1.dot(D2)
(N.x|N.y)
>>> D1.dot(N.y)
N.x
dt(frame)
对此二元组在一个框架中进行时间导数。
此函数调用全局 time_derivative 方法
参数:
框架 : 参考框架
用于进行时间导数的框架
例子
>>> from sympy.physics.vector import ReferenceFrame, outer, dynamicsymbols
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> B = N.orientnew('B', 'Axis', [q, N.z])
>>> d = outer(N.x, N.x)
>>> d.dt(B)
- q'*(N.y|N.x) - q'*(N.x|N.y)
express(frame1, frame2=None)
表达该二元组在备用框架中
第一个框架是列表达表达式,第二个框架是右边;如果二元组以 A.x|B.y 形式存在,则可以在两个不同的框架中表达它。如果没有给出第二个框架,则二元组只在一个框架中表达。
调用全局表达函数
参数:
框架 1 : 参考框架
表达二元组左侧的框架
框架 2 : 参考框架
如果提供,则表达二元组右侧的框架
例子
>>> from sympy.physics.vector import ReferenceFrame, outer, dynamicsymbols
>>> from sympy.physics.vector import init_vprinting
>>> init_vprinting(pretty_print=False)
>>> N = ReferenceFrame('N')
>>> q = dynamicsymbols('q')
>>> B = N.orientnew('B', 'Axis', [q, N.z])
>>> d = outer(N.x, N.x)
>>> d.express(B, N)
cos(q)*(B.x|N.x) - sin(q)*(B.y|N.x)
property func
返回类二元组。
simplify()
返回一个简化的二元组。
subs(*args, **kwargs)
对二元组进行替换。
例子
>>> from sympy.physics.vector import ReferenceFrame
>>> from sympy import Symbol
>>> N = ReferenceFrame('N')
>>> s = Symbol('s')
>>> a = s*(N.x|N.x)
>>> a.subs({s: 2})
2*(N.x|N.x)
to_matrix(reference_frame, second_reference_frame=None)
返回与一个或两个参考框架相关的二阶张量形式的矩阵。
参数:
reference_frame:参考框架
矩阵的行和列所对应的参考框架。如果提供了第二个参考框架,这仅对矩阵的行起作用。
second_reference_frame:参考框架,可选,默认为 None
矩阵的列所对应的参考框架。
返回:
matrix:ImmutableMatrix,形状为(3,3)
给出二维张量形式的矩阵。
示例
>>> from sympy import symbols, trigsimp
>>> from sympy.physics.vector import ReferenceFrame
>>> from sympy.physics.mechanics import inertia
>>> Ixx, Iyy, Izz, Ixy, Iyz, Ixz = symbols('Ixx, Iyy, Izz, Ixy, Iyz, Ixz')
>>> N = ReferenceFrame('N')
>>> inertia_dyadic = inertia(N, Ixx, Iyy, Izz, Ixy, Iyz, Ixz)
>>> inertia_dyadic.to_matrix(N)
Matrix([
[Ixx, Ixy, Ixz],
[Ixy, Iyy, Iyz],
[Ixz, Iyz, Izz]])
>>> beta = symbols('beta')
>>> A = N.orientnew('A', 'Axis', (beta, N.x))
>>> trigsimp(inertia_dyadic.to_matrix(A))
Matrix([
[ Ixx, Ixy*cos(beta) + Ixz*sin(beta), -Ixy*sin(beta) + Ixz*cos(beta)],
[ Ixy*cos(beta) + Ixz*sin(beta), Iyy*cos(2*beta)/2 + Iyy/2 + Iyz*sin(2*beta) - Izz*cos(2*beta)/2 + Izz/2, -Iyy*sin(2*beta)/2 + Iyz*cos(2*beta) + Izz*sin(2*beta)/2],
[-Ixy*sin(beta) + Ixz*cos(beta), -Iyy*sin(2*beta)/2 + Iyz*cos(2*beta) + Izz*sin(2*beta)/2, -Iyy*cos(2*beta)/2 + Iyy/2 - Iyz*sin(2*beta) + Izz*cos(2*beta)/2 + Izz/2]])
xreplace(rule)
替换二阶张量测量数中对象的出现。
参数:
rule:类似字典
表达一个替换规则。
返回:
二阶张量
替换的结果。
示例
>>> from sympy import symbols, pi
>>> from sympy.physics.vector import ReferenceFrame, outer
>>> N = ReferenceFrame('N')
>>> D = outer(N.x, N.x)
>>> x, y, z = symbols('x y z')
>>> ((1 + x*y) * D).xreplace({x: pi})
(pi*y + 1)*(N.x|N.x)
>>> ((1 + x*y) * D).xreplace({x: pi, y: 2})
(1 + 2*pi)*(N.x|N.x)
只有在匹配表达式树中的整个节点时才会发生替换:
>>> ((x*y + z) * D).xreplace({x*y: pi})
(z + pi)*(N.x|N.x)
>>> ((x*y*z) * D).xreplace({x*y: pi})
x*y*z*(N.x|N.x)