#pragma TextEncoding = "UTF-8"
#pragma rtGlobals=3
#pragma version = 1.1
#pragma IgorVersion = 6.1
#pragma ModuleName = PearlPolarCoordinates

// author: matthias.muntwiler@psi.ch
// Copyright (c) 2011-13 Paul Scherrer Institut
// $Id$

function cart2polar(xx, yy, zz, radius, theta, phi)
	// converts a 3-vector from Cartesian to polar coordinates
	variable xx, yy, zz
	variable &radius, &theta, &phi // angles in degrees
	
	radius = sqrt(xx^2 + yy^2 + zz^2)
	
	if (radius > 0)
		theta = acos(zz / radius) * 180 / pi
	else
		theta = 0
	endif
		
	if (xx > 0)
		phi = atan(yy / xx) * 180 / pi
	elseif (xx < 0)
		phi = atan(yy / xx) * 180 / pi + 180
	else
		if (yy > 0)
			phi = 90
		else
			phi = 270
		endif
	endif
end

function cart2polar_wave(in, out)
	// converts a wave of 3-vectors from Cartesian to polar coordinates
	wave in // wave with dimensions (3, N), N >= 1, (x, y, z)
	wave out // wave same dimensions as in, (radius, theta, phi)
		// angles in degrees
	
	out[0][] = sqrt(in[0][q]^2 + in[1][q]^2 + in[2][q]^2)
	out[1][] = acos(in[2][q] / out[0][q]) * 180 / pi
	out[2][] = atan(in[1][q] / in[0][q]) * 180 / pi + 180 * (in[0][q] < 0)
	out[2][] = numtype(out[2][q]) == 0 ? out[2][q] : 90 + 180 * (in[1][q] < 0)
end

function polar2cart(radius, theta, phi, xx, yy, zz)
	// converts a 3-vector from Cartesian to polar coordinates
	variable radius, theta, phi // angles in degrees
	variable &xx, &yy, &zz
	
	xx = radius * sin(theta * pi / 180) * cos(phi * pi / 180)
	yy = radius * sin(theta * pi / 180) * sin(phi * pi / 180)
	zz = radius * cos(theta * pi / 180)
end

function polar2cart_wave(in, out)
	// converts a wave of 3-vectors from polar to Cartesian coordinates
	wave in // wave with dimensions (3, N), N >= 1, (radius, theta, phi)
		// angles in degrees
	wave out // wave same dimensions as in, (x, y, z)
	
	out[0][] = in[0][q] * sin(in[1][q] * pi / 180) * cos(in[2][q] * pi / 180)
	out[1][] = in[0][q] * sin(in[1][q] * pi / 180) * sin(in[2][q] * pi / 180)
	out[2][] = in[0][q] * cos(in[1][q] * pi / 180)
end

function polar_distance(polar1, azim1, polar2, azim2)
	// returns the angle between two spherical coordinates
	variable polar1, azim1
		// angles in degrees
	variable polar2, azim2
		// angles in degrees
	
	variable xx1, yy1, zz1
	variable xx2, yy2, zz2
	
	polar2cart(1, polar1, azim1, xx1, yy1, zz1)
	polar2cart(1, polar2, azim2, xx2, yy2, zz2)
	
	variable vv
	vv = (xx1 * xx2 + yy1 * yy2 + zz1 * zz2) / sqrt(xx1^2 + yy1^2 + zz1^2) / sqrt(xx2^2 + yy2^2 + zz2^2)
	return acos(vv) * 180 / pi
end
