I have coordinates (x,y,z) of the center of spheres stored in a numpy array. I want be able to rotate the spheres with respect to the z-axis but am getting weird results. My code does the rotation but it seems to also be moving it up and right. Maybe this is an intended result from the rotation, but I don't think it is. Here is my code:
theta = math.pi/6
ct = math.cos(theta)
st = math.sin(theta)
z = np.array([[ct, -st, 0], [st, ct, 0], [0, 0, 1]])
self.atoms = np.array([[90,100, 1], [140,100, 1]])
self.atoms = self.atoms.dot(z)
Here is what the image looked like before the rotation:
and here is what it looks like after:
You have to translate the entire system so that the center of the rotation is the center of the system.
The equations used for rotation that you use work only if rotating around the origin.
For the translation you can also multiply with a matrix having the direction of translation as the last row.
Anyway, the entire transformation is P' = inv(T) * R * T * P
(where P
is each point of the figure and P'
is where it will be in the final result, see example) For the inverse of the translation matrix simply negate the sign of the translation components.
Edit (worked out example -- you might have to transpose everything -- switch rows with columns):
You start with the points placed at:
atoms =
90 140
100 100
1 1
which is presented in
Then you apply a rotation with matrix
R =
0.86603 -0.50000 0.00000
0.50000 0.86603 0.00000
0.00000 0.00000 1.00000
and get a result of
R * atoms =
27.9423 71.2436
131.6025 156.6025
1.0000 1.0000
which translates into (as you observed, the red points are the new ones)
The problem is that by doing R * atoms
we rotate around the origin. In the following figure, the angle between the two blue lines is exactly pi/6
Now, we'd like to obtain the blue circles in:
To do this we need several steps:
Build a translation matrix to convert the points such that the center of the rotation is the center of the axes:
T =
1 0 -115
0 1 -100
0 0 1
(the -115
and -100
are the negatives of the center of the atoms)
Translate the points such that the two centers overlap (and we get the red atoms)
T * atoms =
-25 25
0 0
1 1
(observe that our new two points are symmetrical around the origin)
Rotate the new points (and we get the green circles)
R * T * atoms
-21.6506 21.6506
-12.5000 12.5000
1.0000 1.0000
Finally, translate everything back
inv(T) * R * T * atoms =
93.3494 136.6506
87.5000 112.5000
1.0000 1.0000
Final remarks:
The output that you've obtained is explicable due to the fact that my origin is in the lower corner/middle of the figure while yours is in the upper corner.
Because of this you might have to also reverse the order of the multiplications: point * translation * rotation * translation
. Check what works properly.
I cheated a little and did the transformation on both points at the same time. Luckily, the results are the same as if doing the transformation on each point in turn.
Every 2D/3D transform can be written in term of matrices. We use 3x3
matrices for 2D and 4x4
for 3D for this. Basically, we work with Homogenous coordinates
Finally, see Transformation matrix for more examples and details.