15,878,316 members
See more:
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.
Posted
Updated 24-Jan-23 21:04pm
v2
0x01AA 11-Dec-22 11:32am
Not read all your stuff carefully. But I think you could do that with a simple rotation matrix?
a.) Translate the point to your 'rotation origin'
b.) Rotate
c.) Translate back
I have tried doing the rotation at the sphere centre, but because there is no 'z' information, I think the field line structure is lost, and I end up with just a diagonal line.
0x01AA 12-Dec-22 11:53am
How does your rotation matrix looks like?
I've updated the post with the attempt of perform the rotation at the sphere centre, and then displacing it and rotating again to the desired location. I've added the rotation matrices as comments in the code. This method (rot around x-axis, the y-axis) is different to what I replied to you with before, but I still don't get the result I expect - i.e. the final field line doesnt show the expected rotation to the angle gamma.
0x01AA 13-Dec-22 7:34am
Do you expect something like this?
https://python3-9-code.trinket.io/python3-generated/5ciydimu/trinket_plot.png[^]
where orange is the not rotated dipol and blue is rotatet?

`x= x0*np.cos(theta) - y0*np.sin(theta)y= x0*np.sin(theta) + y0*np.cos(theta)`