Reputation: 48600
Is this the correct way to co-compute translation and rotation, or is there a better way? At the moment my code translates and then rotates, could that pose a problem?
Code
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))
Output
root@ubuntu:~$ python rotate.py
[-0.707106781186547, 12.0, 15.606601717798213]
Upvotes: 4
Views: 38722
Reputation: 121
As this is a highly viewed post I thought it would be useful to lead people to the SciPy Rotation Class which I found very useful for rotations, and would have been a good solution for the question, had it been around at the time.
Upvotes: 2
Reputation: 1162
well your matrix function is fine I got it working but for output I used this:
#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
the theory behind it if instead of performing manual changes let the matrices sort it out. Here is where you can find the literature to better understand what I did: http://www.inf.ed.ac.uk/teaching/courses/cg/lectures/cg3_2013.pdf
And yes the way you perform your matrix function defines the way you perform the order of your transformations. There are 3 major transformations: Scaling, Translation, and Rotation. More on that in the link I sent.
Though matrix function works it seems you have the x and z rotations swapped by mistake now I could now follow any of your matrix indices so I rewrote it as such:
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)))
As you can see the sequence of transforms in my return will change the output: since the last is the translation it will translate the point first then rotate in X , then rotate in Y and finally in Z. Hope this helps cheers bud.
Upvotes: 3