Click here to Skip to main content
15,878,316 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
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
Comments
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
paradesic 12-Dec-22 4:40am    
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?
paradesic 13-Dec-22 6:13am    
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?

This had been done by:
x= x0*np.cos(theta) - y0*np.sin(theta)
y= x0*np.sin(theta) + y0*np.cos(theta)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900