# -*- coding: utf-8 -*-
"""
Geometrical functions
---------------------

References
----------
.. [W1] Wikipedia: https://de.wikipedia.org/wiki/Ellipse#Ellipsengleichung_(Parameterform)
.. [WAE] Wolfram Alpha: Ellipse. (http://mathworld.wolfram.com/Ellipse.html)

"""

import numpy as np
from typing import Union

def circle(center: Union[list, np.ndarray], radius: float = 1.0, num_points: int = 20) -> np.ndarray:
    """
    Build a circle with the given characteristics.

    Parameters
    ----------
    c : array-like
        2D Coordinates of center.
    r : float
        Radius of the circle.
    num_points : int
        Number of points to build.

    Returns
    -------
    points : numpy.ndarray
        N-by-2 array with the coordinates of the circle.

    """
    R = np.linspace(0.0, 2.0*np.pi, num_points+1)
    x = center[0] + radius*np.cos(R)
    y = center[1] + radius*np.sin(R)
    return np.array([x, y]).transpose()

def ellipse(center: Union[list, np.ndarray], phi: float, axes: Union[list, np.ndarray], num_points: int = 20) -> np.ndarray:
    """
    Build an ellipse with the given characteristics.

    Parameters
    ----------
    center : array-like
        2D Coordinates of center.
    phi : float
        Angle, in radians, of the major axis w.r.t. the X-axis
    axes : array-like
        Lengths of major and minor axes, respectively.
    num_points : int
        Number of points. Defaults to 20.

    Returns
    -------
    points : numpy.ndarray
        N-by-2 array with the coordinates of the ellipse.

    """
    R = np.linspace(0.0, 2.0*np.pi, num_points+1)
    a, b = axes
    x = center[0] + a*np.cos(R)*np.cos(phi) - b*np.sin(R)*np.sin(phi)
    y = center[1] + a*np.cos(R)*np.sin(phi) + b*np.sin(R)*np.cos(phi)
    return np.array([x, y]).transpose()

[((35, 8, 35, 49), 'numpy.linspace', 'np.linspace', ({(35, 20, 35, 23): '0.0', (35, 25, 35, 34): '2.0 * np.pi', (35, 36, 35, 48): 'num_points + 1'}, {}), '(0.0, 2.0 * np.pi, num_points + 1)', True, 'import numpy as np\n'), ((61, 8, 61, 49), 'numpy.linspace', 'np.linspace', ({(61, 20, 61, 23): '0.0', (61, 25, 61, 34): '2.0 * np.pi', (61, 36, 61, 48): 'num_points + 1'}, {}), '(0.0, 2.0 * np.pi, num_points + 1)', True, 'import numpy as np\n'), ((36, 27, 36, 36), 'numpy.cos', 'np.cos', ({(36, 34, 36, 35): 'R'}, {}), '(R)', True, 'import numpy as np\n'), ((37, 27, 37, 36), 'numpy.sin', 'np.sin', ({(37, 34, 37, 35): 'R'}, {}), '(R)', True, 'import numpy as np\n'), ((38, 11, 38, 27), 'numpy.array', 'np.array', ({(38, 20, 38, 26): '[x, y]'}, {}), '([x, y])', True, 'import numpy as np\n'), ((63, 58, 63, 69), 'numpy.sin', 'np.sin', ({(63, 65, 63, 68): 'phi'}, {}), '(phi)', True, 'import numpy as np\n'), ((64, 58, 64, 69), 'numpy.cos', 'np.cos', ({(64, 65, 64, 68): 'phi'}, {}), '(phi)', True, 'import numpy as np\n'), ((65, 11, 65, 27), 'numpy.array', 'np.array', ({(65, 20, 65, 26): '[x, y]'}, {}), '([x, y])', True, 'import numpy as np\n'), ((63, 32, 63, 43), 'numpy.cos', 'np.cos', ({(63, 39, 63, 42): 'phi'}, {}), '(phi)', True, 'import numpy as np\n'), ((63, 48, 63, 57), 'numpy.sin', 'np.sin', ({(63, 55, 63, 56): 'R'}, {}), '(R)', True, 'import numpy as np\n'), ((64, 32, 64, 43), 'numpy.sin', 'np.sin', ({(64, 39, 64, 42): 'phi'}, {}), '(phi)', True, 'import numpy as np\n'), ((64, 48, 64, 57), 'numpy.sin', 'np.sin', ({(64, 55, 64, 56): 'R'}, {}), '(R)', True, 'import numpy as np\n'), ((63, 22, 63, 31), 'numpy.cos', 'np.cos', ({(63, 29, 63, 30): 'R'}, {}), '(R)', True, 'import numpy as np\n'), ((64, 22, 64, 31), 'numpy.cos', 'np.cos', ({(64, 29, 64, 30): 'R'}, {}), '(R)', True, 'import numpy as np\n')]