Source code for colour.algebra.coordinates.transformations

"""
Coordinates System Transformations
==================================

Define the objects to apply transformations on coordinates systems.

The following transformations are available:

-   :func:`colour.algebra.cartesian_to_spherical`: Cartesian to spherical
    transformation.
-   :func:`colour.algebra.spherical_to_cartesian`: Spherical to cartesian
    transformation.
-   :func:`colour.algebra.cartesian_to_polar`: Cartesian to polar
    transformation.
-   :func:`colour.algebra.polar_to_cartesian`: Polar to cartesian
    transformation.
-   :func:`colour.algebra.cartesian_to_cylindrical`: Cartesian to cylindrical
    transformation.
-   :func:`colour.algebra.cylindrical_to_cartesian`: Cylindrical to cartesian
    transformation.

References
----------
-   :cite:`Wikipedia2005a` : Wikipedia. (2005). ISO 31-11. Retrieved July 31,
    2016, from https://en.wikipedia.org/wiki/ISO_31-11
-   :cite:`Wikipedia2006` : Wikipedia. (2006). List of common coordinate
    transformations. Retrieved July 18, 2014, from
    http://en.wikipedia.org/wiki/List_of_common_coordinate_transformations
"""

from __future__ import annotations

import numpy as np

from colour.algebra import sdiv, sdiv_mode
from colour.hints import ArrayLike, NDArrayFloat
from colour.utilities import as_float_array, tsplit, tstack

__author__ = "Colour Developers"
__copyright__ = "Copyright 2013 Colour Developers"
__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
__maintainer__ = "Colour Developers"
__email__ = "colour-developers@colour-science.org"
__status__ = "Production"

__all__ = [
    "cartesian_to_spherical",
    "spherical_to_cartesian",
    "cartesian_to_polar",
    "polar_to_cartesian",
    "cartesian_to_cylindrical",
    "cylindrical_to_cartesian",
]


[docs] def cartesian_to_spherical(a: ArrayLike) -> NDArrayFloat: """ Transform given cartesian coordinates array :math:`xyz` to spherical coordinates array :math:`\\rho\\theta\\phi` (radial distance, inclination or elevation and azimuth). Parameters ---------- a Cartesian coordinates array :math:`xyz` to transform. Returns ------- :class:`numpy.ndarray` Spherical coordinates array :math:`\\rho\\theta\\phi`, :math:`\\rho` is in range [0, +inf], :math:`\\theta` is in range [0, pi] radians, i.e., [0, 180] degrees, and :math:`\\phi` is in range [-pi, pi] radians, i.e., [-180, 180] degrees. References ---------- :cite:`Wikipedia2006`, :cite:`Wikipedia2005a` Examples -------- >>> a = np.array([3, 1, 6]) >>> cartesian_to_spherical(a) # doctest: +ELLIPSIS array([ 6.7823299..., 0.4850497..., 0.3217505...]) """ x, y, z = tsplit(a) rho = np.linalg.norm(a, axis=-1) with sdiv_mode(): theta = np.arccos(sdiv(z, rho)) phi = np.arctan2(y, x) rtp = tstack([rho, theta, phi]) return rtp
[docs] def spherical_to_cartesian(a: ArrayLike) -> NDArrayFloat: """ Transform given spherical coordinates array :math:`\\rho\\theta\\phi` (radial distance, inclination or elevation and azimuth) to cartesian coordinates array :math:`xyz`. Parameters ---------- a Spherical coordinates array :math:`\\rho\\theta\\phi` to transform, :math:`\\rho` is in range [0, +inf], :math:`\\theta` is in range [0, pi] radians, i.e., [0, 180] degrees, and :math:`\\phi` is in range [-pi, pi] radians, i.e., [-180, 180] degrees. Returns ------- :class:`numpy.ndarray` Cartesian coordinates array :math:`xyz`. References ---------- :cite:`Wikipedia2006`, :cite:`Wikipedia2005a` Examples -------- >>> a = np.array([6.78232998, 0.48504979, 0.32175055]) >>> spherical_to_cartesian(a) # doctest: +ELLIPSIS array([ 3.0000000..., 0.9999999..., 5.9999999...]) """ rho, theta, phi = tsplit(a) x = rho * np.sin(theta) * np.cos(phi) y = rho * np.sin(theta) * np.sin(phi) z = rho * np.cos(theta) xyz = tstack([x, y, z]) return xyz
[docs] def cartesian_to_polar(a: ArrayLike) -> NDArrayFloat: """ Transform given cartesian coordinates array :math:`xy` to polar coordinates array :math:`\\rho\\phi` (radial coordinate, angular coordinate). Parameters ---------- a Cartesian coordinates array :math:`xy` to transform. Returns ------- :class:`numpy.ndarray` Polar coordinates array :math:`\\rho\\phi`, :math:`\\rho` is in range [0, +inf], :math:`\\phi` is in range [-pi, pi] radians, i.e., [-180, 180] degrees. References ---------- :cite:`Wikipedia2006`, :cite:`Wikipedia2005a` Examples -------- >>> a = np.array([3, 1]) >>> cartesian_to_polar(a) # doctest: +ELLIPSIS array([ 3.1622776..., 0.3217505...]) """ x, y = tsplit(a) rho = np.hypot(x, y) phi = np.arctan2(y, x) return tstack([rho, phi])
[docs] def polar_to_cartesian(a: ArrayLike) -> NDArrayFloat: """ Transform given polar coordinates array :math:`\\rho\\phi` (radial coordinate, angular coordinate) to cartesian coordinates array :math:`xy`. Parameters ---------- a Polar coordinates array :math:`\\rho\\phi` to transform, :math:`\\rho` is in range [0, +inf], :math:`\\phi` is in range [-pi, pi] radians i.e., [-180, 180] degrees. Returns ------- :class:`numpy.ndarray` Cartesian coordinates array :math:`xy`. References ---------- :cite:`Wikipedia2006`, :cite:`Wikipedia2005a` Examples -------- >>> a = np.array([3.16227766, 0.32175055]) >>> polar_to_cartesian(a) # doctest: +ELLIPSIS array([ 3. , 0.9999999...]) """ rho, phi = tsplit(a) x = rho * np.cos(phi) y = rho * np.sin(phi) return tstack([x, y])
[docs] def cartesian_to_cylindrical(a: ArrayLike) -> NDArrayFloat: """ Transform given cartesian coordinates array :math:`xyz` to cylindrical coordinates array :math:`\\rho\\phi z` (radial distance, azimuth and height). Parameters ---------- a Cartesian coordinates array :math:`xyz` to transform. Returns ------- :class:`numpy.ndarray` Cylindrical coordinates array :math:`\\rho\\phi z`, :math:`\\rho` is in range [0, +inf], :math:`\\phi` is in range [-pi, pi] radians i.e., [-180, 180] degrees, :math:`z` is in range [0, +inf]. References ---------- :cite:`Wikipedia2006`, :cite:`Wikipedia2005a` Examples -------- >>> a = np.array([3, 1, 6]) >>> cartesian_to_cylindrical(a) # doctest: +ELLIPSIS array([ 3.1622776..., 0.3217505..., 6. ]) """ a = as_float_array(a) rho, phi = tsplit(cartesian_to_polar(a[..., 0:2])) return tstack([rho, phi, a[..., -1]])
[docs] def cylindrical_to_cartesian(a: ArrayLike) -> NDArrayFloat: """ Transform given cylindrical coordinates array :math:`\\rho\\phi z` (radial distance, azimuth and height) to cartesian coordinates array :math:`xyz`. Parameters ---------- a Cylindrical coordinates array :math:`\\rho\\phi z` to transform, :math:`\\rho` is in range [0, +inf], :math:`\\phi` is in range [-pi, pi] radians i.e., [-180, 180] degrees, :math:`z` is in range [0, +inf]. Returns ------- :class:`numpy.ndarray` Cartesian coordinates array :math:`xyz`. References ---------- :cite:`Wikipedia2006`, :cite:`Wikipedia2005a` Examples -------- >>> a = np.array([3.16227766, 0.32175055, 6.00000000]) >>> cylindrical_to_cartesian(a) # doctest: +ELLIPSIS array([ 3. , 0.9999999..., 6. ]) """ a = as_float_array(a) x, y = tsplit(polar_to_cartesian(a[..., 0:2])) return tstack([x, y, a[..., -1]])