I would like to rotate an array about the axis that is normal to a given location on the surface of a sphere, but unsure how to go about it.
As an example, the below code creates a series of points (a dipole field line), shifts it away from the centre of a sphere and rotates to some angle in the xy plane. At this location, I would like to rotate the field line to any angle around the axis that is normal to the sphere surface.
import numpy as np
import matplotlib.pyplot as plt
field=np.linspace(-np.pi/2,np.pi/2,100)
circle=np.linspace(0,2*np.pi,100)
theta=60*np.pi/180
r_shift=0.9
r=1.5*np.sin(field+np.pi/2)**2
x0=r*np.cos(field)+r_shift
y0=r*np.sin(field)
# rotate around y-axis
x=x0*np.cos(theta)
y=y0
fig,ax=plt.subplots()
ax.set_box_aspect(1)
ax.plot(np.cos(circle),np.sin(circle),color='k')
ax.plot(x,y)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
plt.show()
I think it could be done with Euler angles or Rodriguez' formula, but I'm not familiar enough to implement this.
Here is an attempt to perform the required rotation at the sphere centre, and then displace and rotate to the desired location, however the resulting field line does not seem to retain any rotation around angle gamma.
<pre>import numpy as np
import matplotlib.pyplot as plt
field=np.linspace(-np.pi/2,np.pi/2,100)
circle=np.linspace(0,2*np.pi,100)
theta=60*np.pi/180
gamma=45*np.pi/180
r_shift=0.9
r=1.5*np.sin(field+np.pi/2)**2
x0=r*np.cos(field)
y0=r*np.sin(field)
# rotate around x-axis to angle gamma
# [1 0 0 ]
# [0 cos(gamma) -sin(gamma)]
# [0 sin(gamma) cos(gamma)]
y=y0*np.cos(gamma)
# displace in x to r_shift
x=x0+r_shift
# rotate around y-axis to angle theta
# [cos(theta) 0 sin(theta)]
# [0 1 0]
# [sin(theta) 0 cos(theta)]
x=x*np.cos(theta)
fig,ax=plt.subplots()
ax.set_box_aspect(1)
ax.plot(np.cos(circle),np.sin(circle),color='k')
ax.plot(x0,y0)
ax.plot(x,y)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
plt.show()
What I have tried:
Performing the rotating at (0,0) but it doesn't seem to translate and rotate correctly to where the above code displays the field line.