Rotate a 3d object in python

I have done this 3D plot of 2 cubes. But now I want it to rotate, so How can I rotate the cube that is inside? I want to rotate horizontally up to 90º degrees!

enter image description here

And this is the code:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from itertools import product, combinations
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect("auto")
ax.set_autoscale_on(True)


#dibujar cubo
r = [-10, 10]
 for s, e in combinations(np.array(list(product(r,r,r))), 2):
    if np.sum(np.abs(s-e)) == r[1]-r[0]:
        ax.plot3D(*zip(s,e), color="b")


#dibujar punto
#ax.scatter([0],[0],[0],color="g",s=100)

d = [-2, 2]
for s, e in combinations(np.array(list(product(d,d,d))), 2):
    if np.sum(np.abs(s-e)) == d[1]-d[0]:
        ax.plot3D(*zip(s,e), color="g")

plt.show()

Upvotes: 4

Views: 20536

Answers (1)

Greg
Greg

Reputation: 12234

As you are plotting each vertex individually I think you will need to apply a rotation to each vertex. 3D rotations can be confusing, there are numerous ways to define such a rotation, and depending on how you want to rotate it will depend on which you will choose.

You state you want to rotate it horizontally, in such a 3d picture it is unclear what is meant by this so please forgive me if I'm wrong in assuming you want to rotate it say about the z axis by an angle theta.

To rotate a vector p which has length 3, we keep the third component constant and apply a rotation to the other two. This is best understood by matrix multiplication but I'll leave the explanation to the Wolfram pages:

p_rotated_x = p_x * sin(theta) - p_y * sin(theta)
p_rotated_y = p_x * sin(theta) + p_y * cos(theta)
p_rotate_z = p_z

This is the rotated components after applying the R_z rotation matrix in the link above.Applying this to your code after importing some trig functions

from numpy import sin, cos
theta = np.radians(30)
for s, e in combinations(np.array(list(product(d,d,d))), 2):
    if np.sum(np.abs(s-e)) == d[1]-d[0]:
        s_rotated = [s[0] * cos(theta) - s[1] * sin(theta), 
                     s[0] * sin(theta) + s[1] * cos(theta),
                     s[2]]
        e_rotated = [e[0] * cos(theta) - e[1] * sin(theta), 
                     e[0] * sin(theta) + e[1] * cos(theta),
                     e[2]]      
        ax.plot3D(*zip(s_rotated,e_rotated), color="g")

plt.show()

This gives:

enter image description here Note the angle is specified in degrees by the trig function need it to be in radians (hence the conversion).

This is quite a simple rotation, and the implementation is somewhat simplistic. This could be improved upon I admit but the basic idea is there. If you want to rotate it a more complex method I recommend reading about Euler angles which is one (for me at least) intuitive way to understand 3d rotations.

Upvotes: 10

Related Questions