有关坐标系的详细信息#

现在我们来看看如何在中初始化新的坐标系 sympy.vector ,根据现有系统以用户定义的方式进行转换。

定位新系统#

我们已经知道 origin A的性质 CoordSys3D 对应于 Point 表示其原点参考点的实例。

考虑坐标系 \(N\) . 假设我们想定义一个新系统 \(M\) ,其原产地位于 \(\mathbf{{3\hat{{i}} + 4\hat{{j}} + 5\hat{{k}}}}\)\(N\) 的起源。换句话说,坐标 \(M\) 从N的角度来看 \((3, 4, 5)\) . 此外,这也意味着 \(N\) 关于 \(M\) 将是 \((-3, -4, -5)\) .

这可以通过编程实现,如下所示-

>>> from sympy.vector import CoordSys3D
>>> N = CoordSys3D('N')
>>> M = N.locate_new('M', 3*N.i + 4*N.j + 5*N.k)
>>> M.position_wrt(N)
3*N.i + 4*N.j + 5*N.k
>>> N.origin.express_coordinates(M)
(-3, -4, -5)

值得注意的是 \(M\) 的方向与的方向相同 \(N\) . 这意味着旋转矩阵 :math: \(N\) with respect to \(M\) ,反之亦然,等于3x3维的单位矩阵。这个 locate_new 方法初始化 CoordSys3D 这只会在空间中转换,而不是相对于“父”系统重新定位。

定位新系统#

类似于“定位”新系统, sympy.vector 还允许初始化新的 CoordSys3D 以用户定义的方式相对于现有系统定向的实例。

假设你有一个坐标系 \(A\) .

>>> from sympy.vector import CoordSys3D
>>> A = CoordSys3D('A')

要初始化新的坐标系 \(B\) ,相对于 \(A\) 的Z轴角度 \(\theta\) .

>>> from sympy import Symbol
>>> theta = Symbol('theta')

方位如下图所示:

image/svg+xml A B θ θ azbz ax bx ay by

有两种方法可以做到这一点。

直接使用CoordSys3D方法#

因此,这是最简单、最干净的方法。

>>> B = A.orient_new_axis('B', theta, A.k)

这将初始化 \(B\) 提供有关 \(A\) .

CoordSys3D 在其API中提供以下直接定向方法-

  1. orient_new_axis

  2. orient_new_body

  3. orient_new_space

  4. orient_new_quaternion

请看 CoordSys3D 类API在这个模块的文档中给出,以详细了解它们的功能和所需的参数。

使用Orienter(s)和orient_新方法#

首先必须初始化 AxisOrienter 例如存储旋转信息。

>>> from sympy.vector import AxisOrienter
>>> axis_orienter = AxisOrienter(theta, A.k)

然后使用 orient_new 方法,以获得 \(B\) .

>>> B = A.orient_new('B', axis_orienter)

orient_new 还可以使用多个 Orienter 实例,在iterable中提供。旋转/方向按顺序应用于新系统 Orienter 实例出现在iterable中。

>>> from sympy.vector import BodyOrienter
>>> from sympy.abc import a, b, c
>>> body_orienter = BodyOrienter(a, b, c, 'XYZ')
>>> C = A.orient_new('C', (axis_orienter, body_orienter))

The sympy.vector API provides the following four Orienter classes for orientation purposes:

  1. AxisOrienter

  2. BodyOrienter

  3. SpaceOrienter

  4. QuaternionOrienter

请参阅本模块中的各个类的更多信息。

在上述每个示例中,新坐标系的原点与“父”坐标系的原点重合。

>>> B.position_wrt(A)
0

要计算任何坐标系相对于另一坐标系的旋转矩阵,请使用 rotation_matrix 方法。

>>> B = A.orient_new_axis('B', a, A.k)
>>> B.rotation_matrix(A)
Matrix([
[ cos(a), sin(a), 0],
[-sin(a), cos(a), 0],
[      0,      0, 1]])
>>> B.rotation_matrix(B)
Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])

定位和定位新系统#

如果您想初始化一个新系统,它不仅以预定义的方式定向,而且还相对于父系统进行了转换,那么该怎么办?

每个 orient_new_<method of orientation> 方法,以及 orient_new 方法,支持a location 关键字参数。

如果A Vector 作为此的值提供 kwarg ,新系统的原点将自动定义为位于相对于父坐标系的位置矢量处。

因此,定向方法也可以作为支持新系统定向+定位的方法。

>>> C = A.orient_new_axis('C', a, A.k, location=2*A.j)
>>> C.position_wrt(A)
2*A.j
>>> from sympy.vector import express
>>> express(A.position_wrt(C), C)
(-2*sin(a))*C.i + (-2*cos(a))*C.j

更多关于 express 一点作用。

改造新体制#

创建用户定义系统的最一般的方法是使用 transformation 参数在 CoordSys3D . 在这里我们可以定义任何变换方程。如果我们对不同于笛卡尔坐标系的一些典型曲线坐标系感兴趣,我们也可以使用一些预定义的曲线坐标系。也可以通过设置适当的变换方程来平移或旋转系统。

>>> from sympy.vector import CoordSys3D
>>> from sympy import sin, cos
>>> A = CoordSys3D('A', transformation='spherical')
>>> B = CoordSys3D('A', transformation=lambda x,y,z: (x*sin(y), x*cos(y), z))

CoordSys3D 也是专用方法, create_new 其工作原理类似于 locate_neworient_new_axis 等。

>>> from sympy.vector import CoordSys3D
>>> A = CoordSys3D('A')
>>> B = A.create_new('B', transformation='spherical')

不同坐标系下的量的表示#

向量和并矢#

如前所述,同一个向量在不同的坐标系中得到不同的表达式。一般来说,标量表达式和并矢张量也是如此。

sympy.vector 支持在不同坐标系中使用 express 功能。

For purposes of this section, assume the following initializations:

>>> from sympy.vector import CoordSys3D, express
>>> from sympy.abc import a, b, c
>>> N = CoordSys3D('N')
>>> M = N.orient_new_axis('M', a, N.k)

Vector 实例可以在用户定义的系统中使用 express .

>>> v1 = N.i + N.j + N.k
>>> express(v1, M)
(sin(a) + cos(a))*M.i + (-sin(a) + cos(a))*M.j + M.k
>>> v2 = N.i + M.j
>>> express(v2, N)
(1 - sin(a))*N.i + (cos(a))*N.j

除了 Vector 实例, express 也支持标量的重新表达式(通用SymPy ExprDyadic 物体。

express 也接受第二个坐标系以重新表达 Dyadic 实例。

>>> d = 2*(M.i | N.j) + 3* (M.j | N.k)
>>> express(d, M)
(2*sin(a))*(M.i|M.i) + (2*cos(a))*(M.i|M.j) + 3*(M.j|M.k)
>>> express(d, M, N)
2*(M.i|N.j) + 3*(M.j|N.k)

坐标变量#

坐标系原点的位置不影响 BaseVector 实例。但是,它确实影响了 BaseScalar 实例在不同的系统中表示。

BaseScalar 实例,是坐标“符号”,表示在中的向量/标量字段定义中使用的变量 sympy.vector .

例如,考虑标量字段 \(\mathbf{{{{T}}_{{N}}(x, y, z) = x + y + z}}\) 在系统中定义 \(N\) . 因此,在一个有坐标的点上 \((a, b, c)\) ,字段的值将为 \(a + b + c\) . 现在考虑系统 \(R\) ,其原产地位于 \((1, 2, 3)\) 关于 \(N\) (方向不变)。有坐标的点 \((a, b, c)\) 在里面 \(R\) 有坐标 \((a + 1, b + 2, c + 3)\) 在里面 \(N\) . 因此,表达式 \(\mathbf{{{{T}}_{{N}}}}\) 在里面 \(R\) 变成 \(\mathbf{{{{T}}_{{R}}}}(x, y, z) = x + y + z + 6\) .

如果在向量/标量/并元表达式中存在坐标变量,也可以通过设置 variables 的关键字参数 expressTrue .

上面提到的示例,以编程方式完成,如下所示-

>>> R = N.locate_new('R', N.i + 2*N.j + 3*N.k)
>>> T_N = N.x + N.y + N.z
>>> express(T_N, R, variables=True)
R.x + R.y + R.z + 6

其他依赖表达式的方法#

这个 to_matrix 方法 Vectorexpress_coordinates 方法 Point 还根据提供的坐标系返回不同的结果。

>>> P = R.origin.locate_new('P', a*R.i + b*R.j + c*R.k)
>>> P.express_coordinates(N)
(a + 1, b + 2, c + 3)
>>> P.express_coordinates(R)
(a, b, c)
>>> v = N.i + N.j + N.k
>>> v.to_matrix(M)
Matrix([
[ sin(a) + cos(a)],
[-sin(a) + cos(a)],
[               1]])
>>> v.to_matrix(N)
Matrix([
[1],
[1],
[1]])