我正在使用sympy
进行一些符号矢量计算,但是我不能以适当的方式简化矢量类的参数。考虑以下代码:
from sympy.physics.mechanics import ReferenceFrame, dot, cross
from sympy import symbols, sin, cos, simplify
alpha, theta, l = symbols('alpha theta l')
def Rodrigues(v, k, angle):
return cos(angle) * v + cross(k, v) * sin(angle) + k * dot(k, v) * (1- cos(angle))
N = ReferenceFrame('N')
P0 = -l * N.y
P2 = Rodrigues(
Rodrigues(P0, -N.z, alpha),
Rodrigues(N.x, -N.z, alpha),
theta)
返回:
尝试simplify(P2)
时收到错误消息:
AttributeError:“函数”对象没有属性“ x”
我认为这是因为simplify
需要一个sympy
表达式对象。尝试dir(P2)
时,有一个simplify
方法返回:
<bound method Vector.simplify of - l*sin(alpha)*cos(theta)*N.x - l*cos(alpha)*cos(theta)*N.y + (-l*sin(alpha)**2 - l*cos(alpha)**2)*sin(theta)*N.z>
我不知道这是什么!尝试P2.args
我得到:
[(Matrix([
[ -l*sin(alpha)*cos(theta)],
[ -l*cos(alpha)*cos(theta)],
[(-l*sin(alpha)**2 - l*cos(alpha)**2)*sin(theta)]]), N)]
这是带有嵌套3x1 sympy
矩阵的2D元组的1D列表!我不知道谁的选择是使向量类变得如此晦涩难懂,但是现在我可以使用simplify(P2.args[0][0][2])
简化最后一个元素并将函数更改为:
def Rodrigues(v, k, angle):
tmpVec = cos(angle) * v + cross(k, v) * sin(angle) + k * dot(k, v) * (1- cos(angle))
tmpFrame = tmpVec.args[0][1]
return simplify(tmpVec.args[0][0][0]) * tmpFrame.x + simplify(tmpVec.args[0][0][1]) * tmpFrame.y + simplify(tmpVec.args[0][0][2]) * tmpFrame.z
在我看来这是一个非常糟糕的解决方案。
我想知道您是否可以帮助我知道是否还有更多的Python方式可以做到这一点。例如,默认情况下强制sympy
简化所有表达式。还是我以错误的方式使用了vector.simplify
方法?感谢您的提前支持。
P.S。 Rodrigues旋转公式
答案 0 :(得分:1)
您需要调用print(P2.simplify)
之类的方法来代替print(P2.simplify())
。之后,您将获得- l*sin(alpha)*cos(theta)*N.x - l*cos(alpha)*cos(theta)*N.y - l*sin(theta)*N.z
作为输出,与您的def Rodrigues
的最新版本相同。
答案 1 :(得分:0)