subroutine rot_3d(axis, x1in, y1in, z1in, angle, x2out, y2out, z2out, degrees, convert)
integer, intent(IN) :: axis ! axis of rotation 1=x, 2=y, 3=z
real(ESMF_KIND_R8) , intent(IN) :: x1in, y1in, z1in
real(ESMF_KIND_R8) , intent(INOUT) :: angle ! angle to rotate in radians
real(ESMF_KIND_R8) , intent(OUT) :: x2out, y2out, z2out
integer, intent(IN), optional :: degrees ! if present convert angle
! from degrees to radians
integer, intent(IN), optional :: convert ! if present convert input point
! from spherical to cartesian, rotate,
! and convert back
real(ESMF_KIND_R8) :: c, s
real(ESMF_KIND_R8) :: x1,y1,z1, x2,y2,z2
if ( present(convert) ) then
call spherical_to_cartesian(x1in, y1in, z1in, x1, y1, z1)
else
x1=x1in
y1=y1in
z1=z1in
endif
if ( present(degrees) ) then
angle = angle*torad
endif
c = COS(angle)
s = SIN(angle)
SELECT CASE(axis)
CASE(1)
x2 = x1
y2 = c*y1 + s*z1
z2 = -s*y1 + c*z1
CASE(2)
x2 = c*x1 - s*z1
y2 = y1
z2 = s*x1 + c*z1
CASE(3)
x2 = c*x1 + s*y1
y2 = -s*x1 + c*y1
z2 = z1
CASE DEFAULT
write(*,*) "Invalid axis: must be 1 for X, 2 for Y, 3 for Z."
END SELECT
if ( present(convert) ) then
call cartesian_to_spherical(x2, y2, z2, x2out, y2out, z2out)
else
x2out=x2
y2out=y2
z2out=z2
endif
end subroutine rot_3d