B
    [y#                 @   s   d Z ddlmZmZ ddlmZ ddlmZmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZmZ dd	lmZ dd
lmZ G dd deZdS )zCCurves in 2-dimensional Euclidean space.

Contains
========
Curve

    )divisionprint_function)sqrt)sympifydiff)is_sequence)Tuple)_symbol)GeometryEntityGeometrySet)Point)	integratec               @   s   e Zd ZdZdd Zdd Zd ddZed	d
 Zedd Z	edd Z
edd Zedd Zedd Zd!ddZd"ddZd#ddZd$ddZdS )%CurveaU  A curve in space.

    A curve is defined by parametric functions for the coordinates, a
    parameter and the lower and upper bounds for the parameter value.

    Parameters
    ==========

    function : list of functions
    limits : 3-tuple
        Function parameter and lower and upper bounds.

    Attributes
    ==========

    functions
    parameter
    limits

    Raises
    ======

    ValueError
        When `functions` are specified incorrectly.
        When `limits` are specified incorrectly.

    See Also
    ========

    sympy.core.function.Function
    sympy.polys.polyfuncs.interpolate

    Examples
    ========

    >>> from sympy import sin, cos, Symbol, interpolate
    >>> from sympy.abc import t, a
    >>> from sympy.geometry import Curve
    >>> C = Curve((sin(t), cos(t)), (t, 0, 2))
    >>> C.functions
    (sin(t), cos(t))
    >>> C.limits
    (t, 0, 2)
    >>> C.parameter
    t
    >>> C = Curve((t, interpolate([1, 4, 9, 16], t)), (t, 0, 1)); C
    Curve((t, t**2), (t, 0, 1))
    >>> C.subs(t, 4)
    Point2D(4, 16)
    >>> C.arbitrary_point(a)
    Point2D(a, a**2)
    c             C   sf   t |}t|rt|dkr,tdt| t|r@t|dkrPtdt| t| t| t| S )N   z3Function argument should be (x(t), y(t)) but got %s   z3Limit argument should be (t, tmin, tmax) but got %s)r   r   len
ValueErrorstrr
   __new__r   )clsZfunctionlimitsZfun r   3lib/python3.7/site-packages/sympy/geometry/curve.pyr   K   s    zCurve.__new__c                s(   | j kr$t fdd| jD  S d S )Nc                s   g | ]}|  qS r   )subs).0f)newoldr   r   
<listcomp>X   s    z$Curve._eval_subs.<locals>.<listcomp>)	parameterr   	functions)selfr   r   r   )r   r   r   
_eval_subsV   s    
zCurve._eval_substc                sr   |dkrt | j S t|| jdd| j j jkrXjdd | jD krXtdj t  fdd| jD  S )	a  
        A parameterized point on the curve.

        Parameters
        ==========

        parameter : str or Symbol, optional
            Default value is 't';
            the Curve's parameter is selected with None or self.parameter
            otherwise the provided symbol is used.

        Returns
        =======

        arbitrary_point : Point

        Raises
        ======

        ValueError
            When `parameter` already appears in the functions.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Symbol
        >>> from sympy.abc import s
        >>> from sympy.geometry import Curve
        >>> C = Curve([2*s, s**2], (s, 0, 2))
        >>> C.arbitrary_point()
        Point2D(2*t, t**2)
        >>> C.arbitrary_point(C.parameter)
        Point2D(2*s, s**2)
        >>> C.arbitrary_point(None)
        Point2D(2*s, s**2)
        >>> C.arbitrary_point(Symbol('a'))
        Point2D(2*a, a**2)

        NT)realc             s   s   | ]}|j V  qd S )N)name)r   r   r   r   r   	<genexpr>   s    z(Curve.arbitrary_point.<locals>.<genexpr>zFSymbol %s already appears in object and cannot be used as a parameter.c                s   g | ]}|  qS r   )r   )r   w)r#   tnewr   r   r      s    z)Curve.arbitrary_point.<locals>.<listcomp>)r   r    r	   r   r%   free_symbolsr   )r!   r   r   )r#   r(   r   arbitrary_pointZ   s    -

zCurve.arbitrary_pointc             C   s@   t  }x&| j| jdd  D ]}||jO }qW || jh}|S )as  
        Return a set of symbols other than the bound symbols used to
        parametrically define the Curve.

        Examples
        ========

        >>> from sympy.abc import t, a
        >>> from sympy.geometry import Curve
        >>> Curve((t, t**2), (t, 0, 2)).free_symbols
        set()
        >>> Curve((t, t**2), (t, a, 2)).free_symbols
        {a}
           N)setr    r   r)   
differencer   )r!   Zfreear   r   r   r)      s
    zCurve.free_symbolsc             C   s   t | jd S )Nr   )r   args)r!   r   r   r   ambient_dimension   s    zCurve.ambient_dimensionc             C   s
   | j d S )a  The functions specifying the curve.

        Returns
        =======

        functions : list of parameterized coordinate functions.

        See Also
        ========

        parameter

        Examples
        ========

        >>> from sympy.abc import t
        >>> from sympy.geometry import Curve
        >>> C = Curve((t, t**2), (t, 0, 2))
        >>> C.functions
        (t, t**2)

        r   )r/   )r!   r   r   r   r       s    zCurve.functionsc             C   s
   | j d S )a  The limits for the curve.

        Returns
        =======

        limits : tuple
            Contains parameter and lower and upper limits.

        See Also
        ========

        plot_interval

        Examples
        ========

        >>> from sympy.abc import t
        >>> from sympy.geometry import Curve
        >>> C = Curve([t, t**3], (t, -2, 2))
        >>> C.limits
        (t, -2, 2)

        r+   )r/   )r!   r   r   r   r      s    zCurve.limitsc             C   s   | j d d S )ab  The curve function variable.

        Returns
        =======

        parameter : SymPy symbol

        See Also
        ========

        functions

        Examples
        ========

        >>> from sympy.abc import t
        >>> from sympy.geometry import Curve
        >>> C = Curve([t, t**2], (t, 0, 2))
        >>> C.parameter
        t

        r+   r   )r/   )r!   r   r   r   r      s    zCurve.parameterc                s(   t t fdd jD }t| jS )zThe curve length.

        Examples
        ========

        >>> from sympy.geometry.curve import Curve
        >>> from sympy import cos, sin
        >>> from sympy.abc import t
        >>> Curve((t, t), (t, 0, 1)).length
        sqrt(2)
        c             3   s"   | ]}t | jd  d V  qdS )r   r   N)r   r   )r   func)r!   r   r   r&     s    zCurve.length.<locals>.<genexpr>)r   sumr    r   r   )r!   Z	integrandr   )r!   r   length   s    zCurve.lengthc             C   s(   t || jdd}|gt| jdd  S )a  The plot interval for the default geometric plot of the curve.

        Parameters
        ==========

        parameter : str or Symbol, optional
            Default value is 't';
            otherwise the provided symbol is used.

        Returns
        =======

        plot_interval : list (plot interval)
            [parameter, lower_bound, upper_bound]

        See Also
        ========

        limits : Returns limits of the parameter interval

        Examples
        ========

        >>> from sympy import Curve, sin
        >>> from sympy.abc import x, t, s
        >>> Curve((x, sin(x)), (x, 1, 2)).plot_interval()
        [t, 1, 2]
        >>> Curve((x, sin(x)), (x, 1, 2)).plot_interval(s)
        [s, 1, 2]

        T)r$   r+   N)r	   r   listr   )r!   r   r#   r   r   r   plot_interval  s     zCurve.plot_intervalr   Nc             C   s   ddl m}m} |r$t|dd }n
tdd}| j|j }t|j}|d |dd|}|||9 }| 	|dddf 
 d | j}|dk	r| }|j|j S |S )aj  Rotate ``angle`` radians counterclockwise about Point ``pt``.

        The default pt is the origin, Point(0, 0).

        Examples
        ========

        >>> from sympy.geometry.curve import Curve
        >>> from sympy.abc import x
        >>> from sympy import pi
        >>> Curve((x, x), (x, 0, 1)).rotate(pi/2)
        Curve((-x, x), (x, 0, 1))
        r   )Matrix	rot_axis3r   )dimr+   r   N)Zsympy.matricesr6   r7   r   	translater/   r4   r    appendr1   tolistr   )r!   Zangleptr6   r7   rvr   r   r   r   rotate.  s    


"zCurve.rotater+   c             C   sR   |r.t |dd}| j| j ||j|j S | j\}}| || || f| jS )a9  Override GeometryEntity.scale since Curve is not made up of Points.

        Examples
        ========

        >>> from sympy.geometry.curve import Curve
        >>> from sympy import pi
        >>> from sympy.abc import x
        >>> Curve((x, x), (x, 0, 1)).scale(2)
        Curve((2*x, x), (x, 0, 1))
        r   )r8   )r   r9   r/   scaler    r1   r   )r!   xyr<   fxfyr   r   r   r?   L  s
    
zCurve.scalec             C   s$   | j \}}| || || f| jS )a!  Translate the Curve by (x, y).

        Examples
        ========

        >>> from sympy.geometry.curve import Curve
        >>> from sympy import pi
        >>> from sympy.abc import x
        >>> Curve((x, x), (x, 0, 1)).translate(1, 2)
        Curve((x + 1, x + 2), (x, 0, 1))
        )r    r1   r   )r!   r@   rA   rB   rC   r   r   r   r9   ^  s    
zCurve.translate)r#   )r#   )r   N)r+   r+   N)r   r   )__name__
__module____qualname____doc__r   r"   r*   propertyr)   r0   r    r   r   r3   r5   r>   r?   r9   r   r   r   r   r      s   4
8
#

r   N)rG   Z
__future__r   r   Zsympyr   Z
sympy.corer   r   Zsympy.core.compatibilityr   Zsympy.core.containersr   Zsympy.core.symbolr	   Zsympy.geometry.entityr
   r   Zsympy.geometry.pointr   Zsympy.integralsr   r   r   r   r   r   <module>   s   