矩阵在Python中围绕一个点旋转一组向量

矩阵在Python中围绕一个点旋转一组向量,python,matrix,rotational-matrices,Python,Matrix,Rotational Matrices,我整个上午都在努力想办法解决这个问题,最终不得不求助于这样的方法 我正在尝试旋转一组具有3D位置和旋转的“对象”(实际上是为另一个程序编写的,但我正在编写一个快速Python工具来解析数据,以我想要的方式旋转数据并将其吐出) 在我的课程中,有两门课: class Object: def __init__(self, mod, px, py, pz, rx, ry, rz): self.mod = mod self.pos = [px, py, pz]

我整个上午都在努力想办法解决这个问题,最终不得不求助于这样的方法

我正在尝试旋转一组具有3D位置和旋转的“对象”(实际上是为另一个程序编写的,但我正在编写一个快速Python工具来解析数据,以我想要的方式旋转数据并将其吐出)

在我的课程中,有两门课:

class Object:

    def __init__(self, mod, px, py, pz, rx, ry, rz):
        self.mod = mod
        self.pos = [px, py, pz]
        self.rot = [rx, ry, rz]


    def rotate(self, axisx, axisy, axisz, rotx, roty, rotz):
        """rotates object around axis"""

        ?
这是我的“对象”类(好吧,我现在意识到它的命名有多么糟糕!)。忽略“mod”,它非常简单,只存在于空间中,具有位置和旋转(度)

我不知道在旋转部分写什么。我得到了一些矩阵,但只是数学形式,我从来没有为它们编写过代码,我想知道是否有任何库可以提供帮助

我的另一个类是这些对象的简单组。唯一的另一个属性是平均位置,它实际上是我要围绕每个对象旋转的轴:

class ObjectMap:

    def __init__(self, objs):
        self.objs = objs

        tpx = 0.0
        tpy = 0.0
        tpz = 0.0

        for obj in objs:
            tpx += obj.pos[0]
            tpy += obj.pos[1]
            tpz += obj.pos[2]

        # calculate average position for this object map
        # somewhere in the middle of all the objects
        self.apx = tpx / len(objs)
        self.apy = tpy / len(objs)
        self.apz = tpz / len(objs)



    def rotate(self, rotx, roty, rotz):
        """rotate the entire object map around the averaged position in the centre"""

        for o in self.objs:
            o.rotate(self.apx, self.apy, self.apz, rotx, roty, rotz)

正如你所看到的,这个类有一个旋转函数,它简单地贯穿其中包含的所有对象,并将它们围绕“平均位置”轴旋转,因为它是一个平均值,应该在中间某个地方。 我制作了一个快速动画,以更好地解释我在这里所追求的:

其中球面形状是我的“对象”,中间的形状是它们围绕的轴(Objax映射类的APX、APY、APZ坐标)。

我试着开始工作,但就是不起作用,所以我放弃了这个想法。我正在使用Python3,安装了numpy,因为我认为它会有所帮助。我也在互联网上尝试了很多代码,但都不起作用(或者是在老的python版本中,或者只是安装失败)


我希望有人能为我指出正确的方向,让这些旋转运转起来。即使只是一个链接到Python中的矩阵示例或一个有用的库也会很棒

编辑:我的原始答案完全避免了俯仰、侧倾和偏航。基于对问题的澄清,这段代码似乎使用了需要使用俯仰、横摇和偏航的数据结构和/或API,因此我现在将尝试解决这一需求

有几种方法可以指定三维笛卡尔坐标系中的旋转:

  • 欧拉角(3个数值参数)
  • 轴和角度(4个数字参数)
  • 旋转矩阵(9个数值参数)
  • 四元数(4个数值参数)
偏航、俯仰和横摇是欧拉角 (至少根据我所知道的这三个术语的任何适用定义)。 但是 说有24种可能的方法来解释三个欧拉角的序列, 每一种解释都有不同的结果 对于至少一些角度序列,每个其他的。 如何将“偏航、俯仰和滚转”转换为一个 transformations.py中24个可能的“轴序列”。 事实上,除非您确切了解现有数据/软件的使用情况 与的接口将偏航、俯仰和滚动应用于要移动的对象 旋转,我认为你不能真正说出“偏航、俯仰和滚动”在这个应用程序中的含义,你也不可能猜到transformations.py中使用的正确“轴序列”。 我怀疑这可能是你没能获得成功的主要原因 transformations.py为您工作

除了这些模棱两可之外,我还不清楚这些参数是什么
axisx
axisy
axisz
表示
旋转(self、axisx、axisy、axisz、rotx、roty、rotz)
。 通常,偏航、俯仰和滚转指绕三个轴的旋转 旋转的物体,一般来说,一个人应该定义 这些轴是什么以及应用旋转的顺序 在进行任何旋转之前,请不要更改这些定义。 因此,每次必须指定轴时,都指定轴是没有意义的 再做一次旋转;软件应该已经知道具体是哪个了 要使用的轴,即使它们是实体轴而不是世界轴。 (我现在假设每个参数
axisx
axisy
,和
axisz
它本身就是一个轴,而这三个参数在某种程度上并不相同 用于指定我在初始答案中假设的单个轴。)

当俯仰、横滚和偏航通常应用时,会增加混乱 对于体轴,您应该旋转整个对象集合, 这似乎意味着你应该围绕世界轴旋转,而不是 单个身体轴

实际上,一旦你弄清楚什么是偏航、俯仰和侧倾 在您的应用程序中真正的含义是什么?您的应用程序的参数是什么
rotate
函数的意思是,我要做的第一件事 任何旋转都是为了将其转换为非旋转的表示 任何类型的欧拉角。旋转矩阵看起来是个不错的选择。 如果您知道代表您定义的正确“轴序列” 在transformations.py,
euler_矩阵中的偏航、俯仰和滚转
为你们计算那个矩阵

您可以通过执行对象的矩阵乘法来进一步旋转对象 新的旋转矩阵和现有旋转矩阵; 结果是第三个矩阵。 如果在世界坐标系中是旋转,则新矩阵在乘法中位于左侧,如果在身体坐标系中是旋转,则位于右侧

使用新的旋转矩阵重新定向对象后, 如果确实需要将对象的结果方向存储为 某个地方的一系列欧拉角(横摇、俯仰和偏航),
transformations.py中来自矩阵的euler\u
承诺会告诉您这些是什么 角度是(但再一次,你必须知道你的“侧倾、俯仰和偏航”是如何变化的) 以及transformations.py如何将该定义表示为轴序列)

线下是材料f
    def rotate(self, axisx, axisy, axisz, angle)
    def rotate(self, angle)
    def __init__(self, mod, px, py, pz):
        self.mod = mod
        self.position = [px, py, pz]
    def __init__(self, mod, px, py, pz, vector1x, vector1y, vector1z, vector2x, vector2y, vector2z):
        self.mod = mod
        self.position = [px, py, pz]
        self.feature1 = [px + vector1x, py + vector1y, pz + vector1z]
        self.feature2 = [px + vector2x, py + vector2y, pz + vector2z]
    def rotate(self, axisx, axisy, axisz, angle):
        rotate self.position around [axisx, axisy, axisz] by angle radians
        rotate self.feature1 around [axisx, axisy, axisz] by angle radians
        rotate self.feature2 around [axisx, axisy, axisz] by angle radians
    rotation = define_rotation(axisx, axisy, axisz, angle)
    self.feature1 = [px + vector1x, py + vector1y, pz + vector1z]
    self.feature1 = p.add(vector1)