def test_sph_to_cart(): """Test conversion between sphere and cartesian.""" # Simple test, expected value (11, 0, 0) r, theta, phi = 11., 0., np.pi / 2. z = r * np.cos(phi) rsin_phi = r * np.sin(phi) x = rsin_phi * np.cos(theta) y = rsin_phi * np.sin(theta) coord = _sph_to_cart(np.array([[r, theta, phi]]))[0] assert_allclose(coord, (x, y, z), atol=1e-7) assert_allclose(coord, (r, 0, 0), atol=1e-7) rng = np.random.RandomState(0) # round-trip test coords = rng.randn(10, 3) assert_allclose(_sph_to_cart(_cart_to_sph(coords)), coords, atol=1e-5) # equivalence tests to old versions for coord in coords: sph = _cart_to_sph(coord[np.newaxis]) cart = _sph_to_cart(sph) sph_old = np.array(_cartesian_to_sphere(*coord)) cart_old = _sphere_to_cartesian(*sph_old) sph_old[1] = np.pi / 2. - sph_old[1] # new convention assert_allclose(sph[0], sph_old[[2, 0, 1]], atol=1e-7) assert_allclose(cart[0], cart_old, atol=1e-7) assert_allclose(cart[0], coord, atol=1e-7)
def _make_radial_coord_system(points, origin): """Compute a radial coordinate system at the given points. For each point X, a set of three unit vectors is computed that point along the axes of a radial coordinate system. The first axis of the coordinate system is in the direction of the line between X and the origin point. The second and third axes are perpendicular to the first axis. Parameters ---------- points : ndarray, shape (n_points, 3) For each point, the XYZ carthesian coordinates. origin : (x, y, z) A tuple (or other array-like) containing the XYZ carthesian coordinates of the point of origin. This can for example be the center of a sphere fitted through the points. Returns ------- radial : ndarray, shape (n_points, 3) For each point X, a unit vector pointing in the radial direction, i.e., the direction of the line between X and the origin point. This is the first axis of the coordinate system. tan1 : ndarray, shape (n_points, 3) For each point, a unit vector perpendicular to both ``radial`` and ``tan2``. This is the second axis of the coordinate system. tan2 : ndarray, shape (n_points, 3) For each point, a unit vector perpendicular to both ``radial`` and ``tan1``. This is the third axis of the coordinate system. """ radial = (points - origin) radial /= np.linalg.norm(radial, axis=1)[:, np.newaxis] theta = _cart_to_sph(radial)[:, 1] # Compute tangential directions tan1 = np.vstack((-np.sin(theta), np.cos(theta), np.zeros(len(points)))).T tan2 = np.cross(radial, tan1) return radial, tan1, tan2