title: Rotation of a vector (Python)
body: <p>I am rotating a vector in 3D via two 2D rotations using the following code:</p>
  
  <p>NOTE: L is </p>
  
  <pre><code>np.array([11.231303753070549, 9.27144871768164, 18.085790226916288])
  </code></pre>
  
  <p>a predefined vector shown in blue in the plot below.</p>
  
  <pre><code>import numpy as np
  import matplotlib.pyplot as plt
  from mpl_toolkits.mplot3d import Axes3D
  
  def angle_between(p1, p2):
      ang1 = np.arctan2(*p1[::-1])
      ang2 = np.arctan2(*p2[::-1])
      return ((ang1 - ang2) % (2 * np.pi))
  
  L = np.vstack([L,np.zeros(3)])
  line_xy = [0.,1.]
  line_L = [L[0,0],L[0,1]]
  a = angle_between(line_xy, line_L)
  
  def rotation(vector,theta):    
          v1_new = (vector[0]*np.cos(theta)) - (vector[1]*np.sin(theta))
          v2_new = (vector[1]*np.cos(theta)) + (vector[0]*np.sin(theta))        
          z_trans = [v1_new,v2_new,vector[2]]
          line_yz= [0.,1.]
          theta2 = angle_between(line_yz, [z_trans[1],z_trans[2]])
          v1_new = (z_trans[0]*np.cos(theta2)) - (z_trans[1]*np.sin(theta2))
          v2_new = (z_trans[1]*np.cos(theta2)) + (z_trans[0]*np.sin(theta2))
          y_trans = np.array([z_trans[0],v1_new,v2_new])        
          return z_trans,y_trans
  
  L2,L3 = rotation(L[0,:],a)
  
  L2 = np.vstack([L2,np.zeros(3)])
  L3 = np.vstack([L3,np.zeros(3)])
  
  fig = plt.figure()
  ax = fig.add_subplot(111, projection='3d')
  #ax.scatter(x1*1000,y1*1000,z1*1000,c ='r',zorder=2)
  ax.plot(L[:,0],L[:,1],L[:,2],color='b',zorder=1)
  line = np.array([[0,0,0],[0,0,15]])
  ax.plot(line[:,0],line[:,1],line[:,2],color = 'g')
  ax.set_xlabel('X Kpc')
  ax.set_ylabel('Y Kpc')
  ax.set_zlabel('Z Kpc')
  
  ax.plot(L2[:,0],L2[:,1],L2[:,2],color='g')
  ax.plot(L3[:,0],L3[:,1],L3[:,2],color='y')
  </code></pre>
  
  <p>What I'm doing here is calculating the angle between x=0, y=1 (that's the line_xy part) and then rotating it around the z-axis using the first part of the rotation function:</p>
  
  <pre><code>v1_new = (vector[0]*np.cos(theta)) - (vector[1]*np.sin(theta))
  v2_new = (vector[1]*np.cos(theta)) + (vector[0]*np.sin(theta))        
  z_trans = [v1_new,v2_new,vector[2]]
  </code></pre>
  
  <p>then repeat the process but this time  rotating around the x axis  using the second  part of the rotation function: </p>
  
  <pre><code>line_yz= [0.,1.]
  theta2 = angle_between(line_yz, [z_trans[1],z_trans[2]])
  v1_new = (z_trans[0]*np.cos(theta2)) - (z_trans[1]*np.sin(theta2))
  v2_new = (z_trans[1]*np.cos(theta2)) + (z_trans[0]*np.sin(theta2))
  y_trans = np.array([z_trans[0],v1_new,v2_new]) 
  </code></pre>
  
  <p>Rotations are done via the standard 2D rotation equations:</p>
  
  <p>x' = x cos(theta)  - y sin(theta)
  y' = y cos(theta) + x sin(theta)</p>
  
  <p>But for some reason, after the second rotation, the line (in yellow) doesn't  line up  with the green line (the original target of rotating this vector). </p>
  
  <p><a href="https://i.stack.imgur.com/R3XGi.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/R3XGi.png" alt="enter image description here"></a></p>
  
  <p>I've tried checking the angles in both radians and degrees but it appears to only work with radians.</p>
  
  <p>When checking the angle theta2, it comes out around 35 degrees which looks plausible. </p>