Converting from spherical coordinates to cartesian around arbitrary vector N
Categories:
Converting Spherical to Cartesian Coordinates Around an Arbitrary Vector

Learn the mathematical principles and practical steps to transform spherical coordinates (radius, polar, azimuthal angles) into Cartesian coordinates, specifically when the polar axis is aligned with an arbitrary 3D vector N.
Converting between coordinate systems is a fundamental task in many fields, including computer graphics, physics simulations, and robotics. While the standard conversion from spherical to Cartesian coordinates assumes the polar axis aligns with the Z-axis, real-world applications often require this conversion around an arbitrary vector. This article will guide you through the mathematical derivation and practical implementation of such a transformation, enabling you to accurately position points in 3D space relative to any given orientation.
Understanding Spherical Coordinates
Standard spherical coordinates are defined by three parameters: the radial distance r
(or ρ
), the polar angle θ
(theta), and the azimuthal angle φ
(phi). The radial distance r
is the distance from the origin to the point. The polar angle θ
is the angle between the positive Z-axis and the line segment from the origin to the point, ranging from 0 to π radians (0 to 180 degrees). The azimuthal angle φ
is the angle between the positive X-axis and the projection of the line segment onto the XY-plane, ranging from 0 to 2π radians (0 to 360 degrees).
The standard conversion formulas to Cartesian coordinates (x, y, z) are:
x = r * sin(θ) * cos(φ)
y = r * sin(θ) * sin(φ)
z = r * cos(θ)
However, when the 'polar axis' is not the Z-axis but an arbitrary vector N, these formulas no longer directly apply. We need a method to rotate our coordinate system such that N becomes the effective Z-axis, perform the standard conversion, and then rotate back.
graph TD A[Input: r, θ, φ, Vector N] --> B{Normalize N} B --> C{Construct Rotation Matrix} C --> D[Standard Spherical to Cartesian] D --> E{Apply Inverse Rotation} E --> F[Output: Cartesian (x, y, z)]
High-level process for converting spherical coordinates around an arbitrary vector N.
The Transformation Process
The core idea is to align our coordinate system with the arbitrary vector N. This involves creating an orthonormal basis where N is one of the axes (typically the Z-axis). Once this new basis is established, we can perform the standard spherical-to-Cartesian conversion within this rotated frame and then transform the resulting Cartesian coordinates back to the original global frame.
Let N be the arbitrary vector around which the spherical coordinates are defined. We'll assume N is a unit vector (if not, normalize it first). We need to construct a rotation matrix that transforms the standard Z-axis to N. This matrix will also define the new X and Y axes relative to N.
- Normalize N: Ensure N is a unit vector.
N_unit = N / ||N||
. - Find a Perpendicular Vector: Choose an arbitrary non-parallel vector, say
V_arbitrary = (0, 0, 1)
(if N is not(0,0,1)
or(0,0,-1)
), or(1, 0, 0)
otherwise. ComputeU = N_unit x V_arbitrary
. NormalizeU
. - Find the Third Orthogonal Vector: Compute
W = N_unit x U
. NormalizeW
. - Construct the Basis: The vectors
U
,W
, andN_unit
now form an orthonormal basis.U
can be considered the new X-axis,W
the new Y-axis, andN_unit
the new Z-axis. - Standard Conversion in New Basis: Calculate the Cartesian coordinates
(x', y', z')
using the standard formulas:x' = r * sin(θ) * cos(φ)
y' = r * sin(θ) * sin(φ)
z' = r * cos(θ)
- Transform to Global Coordinates: The final Cartesian coordinates
(x, y, z)
in the global frame are obtained by combining the new basis vectors with(x', y', z')
:P = x' * U + y' * W + z' * N_unit
This method effectively rotates the standard spherical coordinate system so its Z-axis aligns with N, calculates the point, and then rotates it back to the original global coordinate system.
V_arbitrary
in step 2, ensure it's not collinear with N_unit
. A common robust approach is to check if abs(N_unit.x) < 0.9
(or y
or z
) and pick (1,0,0)
, (0,1,0)
, or (0,0,1)
accordingly to guarantee non-collinearity. For example, if N_unit.x
is close to 1 or -1, (1,0,0)
would be a poor choice for V_arbitrary
.Mathematical Derivation and Implementation
Let's formalize the rotation. We want to find a rotation matrix R
that maps the standard basis vectors (e_x, e_y, e_z)
to our new basis (U, W, N_unit)
. Specifically, if e_z
maps to N_unit
, e_x
maps to U
, and e_y
maps to W
, then the rotation matrix R
will have U
, W
, and N_unit
as its columns:
R = [ U | W | N_unit ]
However, this matrix R
transforms points from the new coordinate system to the global coordinate system. If we calculate P_local = (x', y', z')
in the new system, then P_global = R * P_local
. This is exactly what we need.
Let's consider an example implementation in a programming language like Python or C++.
import numpy as np
def spherical_to_cartesian_around_vector(r, theta, phi, N):
"""
Converts spherical coordinates (r, theta, phi) to Cartesian coordinates
where the polar axis is aligned with the arbitrary vector N.
Args:
r (float): Radial distance.
theta (float): Polar angle (angle from N), in radians.
phi (float): Azimuthal angle (around N), in radians.
N (np.array): The arbitrary 3D vector defining the polar axis.
Returns:
np.array: The Cartesian coordinates (x, y, z).
"""
N_unit = N / np.linalg.norm(N)
# Find a vector perpendicular to N_unit
# Robustly choose an arbitrary vector not collinear with N_unit
if np.abs(N_unit[0]) < 0.9:
V_arbitrary = np.array([1.0, 0.0, 0.0])
elif np.abs(N_unit[1]) < 0.9:
V_arbitrary = np.array([0.0, 1.0, 0.0])
else:
V_arbitrary = np.array([0.0, 0.0, 1.0])
# Construct orthonormal basis (U, W, N_unit)
U = np.cross(N_unit, V_arbitrary)
U = U / np.linalg.norm(U)
W = np.cross(N_unit, U)
# W is already orthogonal and unit length if N_unit and U are.
# Standard spherical to Cartesian in the new basis
x_prime = r * np.sin(theta) * np.cos(phi)
y_prime = r * np.sin(theta) * np.sin(phi)
z_prime = r * np.cos(theta)
# Transform to global Cartesian coordinates
# P_global = x_prime * U + y_prime * W + z_prime * N_unit
# Note: The basis vectors U, W, N_unit form the columns of the rotation matrix
# that transforms from the new basis to the global basis.
# So, P_global = [U | W | N_unit] @ [x_prime, y_prime, z_prime].T
P_global = x_prime * U + y_prime * W + z_prime * N_unit
return P_global
# Example Usage:
r_val = 1.0
theta_val = np.pi / 2 # 90 degrees from N
phi_val = np.pi / 4 # 45 degrees around N
N_vector = np.array([1.0, 1.0, 0.0]) # Arbitrary vector (e.g., 45 deg in XY plane)
cartesian_coords = spherical_to_cartesian_around_vector(r_val, theta_val, phi_val, N_vector)
print(f"Spherical (r={r_val}, theta={np.degrees(theta_val)}°, phi={np.degrees(phi_val)}°) around N={N_vector} -> Cartesian: {cartesian_coords}")
# Test with N = (0,0,1) (standard case)
N_standard = np.array([0.0, 0.0, 1.0])
cartesian_standard = spherical_to_cartesian_around_vector(r_val, theta_val, phi_val, N_standard)
print(f"Spherical (r={r_val}, theta={np.degrees(theta_val)}°, phi={np.degrees(phi_val)}°) around N={N_standard} -> Cartesian: {cartesian_standard}")
# Expected for standard: x = 1*sin(90)*cos(45) = 0.707, y = 1*sin(90)*sin(45) = 0.707, z = 1*cos(90) = 0
# Output should be close to [0.707, 0.707, 0.0]
Python implementation for converting spherical coordinates around an arbitrary vector.
U
and W
is not unique. Any two orthonormal vectors perpendicular to N_unit
and to each other will work. The np.cross
operations ensure this orthogonality. The specific orientation of U
and W
defines the 'zero' for the azimuthal angle φ
relative to N_unit
.This method provides a robust way to handle spherical coordinate conversions in scenarios where the polar axis is not fixed to a global coordinate axis. It's crucial for applications requiring flexible object placement or camera orientations in 3D environments.