o
    8VaL'                     @   s   d 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

    )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 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 )&CurveaN  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.

    Examples
    ========

    >>> from sympy import sin, cos, 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)

    See Also
    ========

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

    c                 C   sf   t |}t|rt|dkrtdt| t|r t|dkr(t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   )clsfunctionlimitsZfun r   6/usr/lib/python3/dist-packages/sympy/geometry/curve.pyr   J   s   zCurve.__new__c                 C   s   |  | j|S N)subs	parameter)selffr   r   r   __call__U   s   zCurve.__call__c                    s(   | j krt fdd| jD  S d S )Nc                    s   g | ]}|  qS r   r   .0r   newoldr   r   
<listcomp>Z       z$Curve._eval_subs.<locals>.<listcomp>)r   r
   	functions)r   r#   r"   r   r!   r   
_eval_subsX   s   
zCurve._eval_substc                    sr   |du r	t | j S t|| jdd| j j jkr,jdd | jD v r,t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
        =======

        Point :
            Returns a point in parametric form.

        Raises
        ======

        ValueError
            When `parameter` already appears in the functions.

        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)

        See Also
        ========

        sympy.geometry.point.Point

        NTrealc                 s   s    | ]}|j V  qd S r   )namer   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(   Ztnewr   r   r$      r%   z)Curve.arbitrary_point.<locals>.<listcomp>)r
   r&   r   r   r+   free_symbolsr   )r   r   r   r.   r   arbitrary_point\   s   -
zCurve.arbitrary_pointc                 C   s<   t  }| j| jdd  D ]}||jO }q|| jh}|S )a  Return a set of symbols other than the bound symbols used to
        parametrically define the Curve.

        Returns
        =======

        set :
            Set of all non-parameterized symbols.

        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   freear   r   r   r/      s
   zCurve.free_symbolsc                 C   s   t | jd S )aD  The dimension of the curve.

        Returns
        =======

        int :
            the dimension of curve.

        Examples
        ========

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

        r   )r   argsr   r   r   r   ambient_dimension   s   zCurve.ambient_dimensionc                 C   
   | j d S )a  The functions specifying the curve.

        Returns
        =======

        functions :
            list of parameterized coordinate functions.

        Examples
        ========

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

        See Also
        ========

        parameter

        r   r6   r7   r   r   r   r&         
zCurve.functionsc                 C   r9   )a  The limits for the curve.

        Returns
        =======

        limits : tuple
            Contains parameter and lower and upper limits.

        Examples
        ========

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

        See Also
        ========

        plot_interval

        r1   r:   r7   r   r   r   r      r;   zCurve.limitsc                 C   s   | j d d S )av  The curve function variable.

        Returns
        =======

        Symbol :
            returns a bound symbol.

        Examples
        ========

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

        See Also
        ========

        functions

        r1   r   r:   r7   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.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    funcr7   r   r   r,   %  s   " zCurve.length.<locals>.<genexpr>)r   sumr&   r   r   )r   Z	integrandr   r7   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
        =======

        List :
            the plot interval as below:
                [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Curve, sin
        >>> from sympy.abc import x, 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]

        See Also
        ========

        limits : Returns limits of the parameter interval

        Tr)   r1   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}| }|j|j S )a*  This function is used to rotate a curve along given point ``pt`` at given angle(in radian).

        Parameters
        ==========

        angle :
            the angle at which the curve will be rotated(in radian) in counterclockwise direction.
            default value of angle is 0.

        pt : Point
            the point along which the curve will be rotated.
            If no point given, the curve will be rotated around origin.

        Returns
        =======

        Curve :
            returns a curve rotated at given angle along given point.

        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   Zdimr1   r   N)Zsympy.matricesrA   rB   r
   	translater6   r?   r&   appendr<   tolistr   )r   ZangleptrA   rB   Zrvr   r   r   r   rotateL  s   


"zCurve.rotater1   c                 C   sR   |rt |dd}| j| j ||j|j S | j\}}| || || f| jS )am  Override GeometryEntity.scale since Curve is not made up of Points.

        Returns
        =======

        Curve :
            returns scaled curve.

        Examples
        ========

        >>> from sympy.geometry.curve import Curve
        >>> from sympy.abc import x
        >>> Curve((x, x), (x, 0, 1)).scale(2)
        Curve((2*x, x), (x, 0, 1))

        r   rC   )r
   rD   r6   scaler&   r<   r   )r   xyrG   fxfyr   r   r   rI   x  s
   
zCurve.scalec                 C   s$   | j \}}| || || f| jS )a[  Translate the Curve by (x, y).

        Returns
        =======

        Curve :
            returns a translated curve.

        Examples
        ========

        >>> from sympy.geometry.curve import Curve
        >>> from sympy.abc import x
        >>> Curve((x, x), (x, 0, 1)).translate(1, 2)
        Curve((x + 1, x + 2), (x, 0, 1))

        )r&   r<   r   )r   rJ   rK   rL   rM   r   r   r   rD     s   
zCurve.translate)r(   )r   N)r1   r1   N)r   r   )__name__
__module____qualname____doc__r   r   r'   r0   propertyr/   r8   r&   r   r   r>   r@   rH   rI   rD   r   r   r   r   r      s,    6
8







$
,r   N)rQ   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    