Python:变换矩阵

4

这种同时计算平移和旋转的方式正确吗?还有更好的方法吗?目前我的代码是先进行平移再进行旋转,这样会有问题吗?

代码

from math import cos, sin, radians

def trig(angle):
  r = radians(angle)
  return cos(r), sin(r)

def matrix(rotation=(0,0,0), translation=(0,0,0)):
  xC, xS = trig(rotation[0])
  yC, yS = trig(rotation[1])
  zC, zS = trig(rotation[2])
  dX = translation[0]
  dY = translation[1]
  dZ = translation[2]
  return [[yC*xC, -zC*xS+zS*yS*xC, zS*xS+zC*yS*xC, dX],
    [yC*xS, zC*xC+zS*yS*xS, -zS*xC+zC*yS*xS, dY],
    [-yS, zS*yC, zC*yC, dZ],
    [0, 0, 0, 1]]

def transform(point=(0,0,0), vector=(0,0,0)):
  p = [0,0,0]
  for r in range(3):
    p[r] += vector[r][3]
    for c in range(3):
      p[r] += point[c] * vector[r][c]
  return p

if __name__ == '__main__':
  point = (7, 12, 8)
  rotation = (0, -45, 0)
  translation = (0, 0, 5)
  matrix = matrix(rotation, translation)
  print (transform(point, matrix))

输出

root@ubuntu:~$ python rotate.py 
[-0.707106781186547, 12.0, 15.606601717798213]
2个回答

3

好的,你的矩阵函数没问题,我已经让它正常工作了,但是为了输出,我使用了这个:

#def transform(point, vector):
#  p = [0,0,0]
#  for r in range(0,3):
#    p[r] += vector[r][3]
#    print p
#    for c in range(3):
#        p[r] += point[c] * vector[r][c]
#  return p

def transform(point, TransformArray):
  p = np.array([0,0,0,1])
  for i in range (0,len(point)-1):
      p[i] = point[i]
  p=np.dot(TransformArray,np.transpose(p))
  for i in range (0,len(point)-1):
      point[i]=p[i]
  return point

如果不是手动更改,而是让矩阵进行排序的话,它背后的理论是什么。在这里,您可以找到更好地理解我所做的事情的文献: http://www.inf.ed.ac.uk/teaching/courses/cg/lectures/cg3_2013.pdf

是的,您执行矩阵函数的方式定义了您执行变换顺序的方式。有三个主要的变换: 缩放、平移和旋转。有关此问题,请参阅我发送的链接。

虽然矩阵函数起作用,但似乎您错误地交换了x和z的旋转,现在我可以跟随您的任何矩阵索引之一,所以我重写了它:

def matrix(rotation, translation):
  xC, xS = trig(rotation[0])
  yC, yS = trig(rotation[1])
  zC, zS = trig(rotation[2])
  dX = translation[0]
  dY = translation[1]
  dZ = translation[2]
  Translate_matrix = np.array([[1, 0, 0, dX],
                               [0, 1, 0, dY],
                               [0, 0, 1, dZ],
                               [0, 0, 0, 1]])
  Rotate_X_matrix = np.array([[1, 0, 0, 0],
                              [0, xC, -xS, 0],
                              [0, xS, xC, 0],
                              [0, 0, 0, 1]])
  Rotate_Y_matrix = np.array([[yC, 0, yS, 0],
                              [0, 1, 0, 0],
                              [-yS, 0, yC, 0],
                              [0, 0, 0, 1]])
  Rotate_Z_matrix = np.array([[zC, -zS, 0, 0],
                              [zS, zC, 0, 0],
                              [0, 0, 1, 0],
                              [0, 0, 0, 1]])
  return np.dot(Rotate_Z_matrix,np.dot(Rotate_Y_matrix,np.dot(Rotate_X_matrix,Translate_matrix)))

正如您所看到的,我的返回序列将改变输出:因为最后一个是翻译,它将首先翻译点,然后在X轴旋转,然后在Y轴旋转,最后在Z轴旋转。

希望这可以帮助您,祝您好运。


2

由于这是一篇非常受欢迎的帖子,我认为将人们引导到我发现非常有用的SciPy Rotation类对于旋转问题是一个很好的解决方案,如果当时有这个类库,它将是一个不错的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接