B
    dd                 @   s  d Z ddlZddlmZmZmZ ddl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 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m Z  ddl!m"Z"m#Z#m$Z$ ddl%m&Z& ddl'm(Z( G dd de&Z)G dd de)Z*G dd de)Z+dS )aD  Geometrical Points.

Contains
========
Point
Point2D
Point3D

When methods of Point require 1 or more points as arguments, they
can be passed as a sequence of coordinates or Points:

>>> from sympy import Point
>>> Point(1, 1).is_collinear((2, 2), (3, 4))
False
>>> Point(1, 1).is_collinear(Point(2, 2), Point(3, 4))
False

    N)SsympifyExpr)Add)Tuple)Float)global_parameters)	nsimplifysimplify)GeometryError)sqrt)im)cossin)Matrix)	Transpose)uniqis_sequence)
filldedent	func_nameUndecidable   )GeometryEntity)prec_to_dpsc               @   sb  e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zedd  Zed!d" Zed#d$ Zed%d& Zd'd( Zd)d* Zd+d, ZdMd.d/Zd0d1 Zd2d3 Zd4d5 Z ed6d7 Z!d8d9 Z"ed:d; Z#ed<d= Z$d>d? Z%ed@dA Z&edBdC Z'edDdE Z(dFdG Z)dHdI Z*edJdK Z+dLS )NPointa  A point in a n-dimensional Euclidean space.

    Parameters
    ==========

    coords : sequence of n-coordinate values. In the special
        case where n=2 or 3, a Point2D or Point3D will be created
        as appropriate.
    evaluate : if `True` (default), all floats are turn into
        exact types.
    dim : number of coordinates the point should have.  If coordinates
        are unspecified, they are padded with zeros.
    on_morph : indicates what should happen when the number of
        coordinates of a point need to be changed by adding or
        removing zeros.  Possible values are `'warn'`, `'error'`, or
        `ignore` (default).  No warning or error is given when `*args`
        is empty and `dim` is given. An error is always raised when
        trying to remove nonzero coordinates.


    Attributes
    ==========

    length
    origin: A `Point` representing the origin of the
        appropriately-dimensioned space.

    Raises
    ======

    TypeError : When instantiating with anything but a Point or sequence
    ValueError : when instantiating with a sequence with length < 2 or
        when trying to reduce dimensions if keyword `on_morph='error'` is
        set.

    See Also
    ========

    sympy.geometry.line.Segment : Connects two Points

    Examples
    ========

    >>> from sympy import Point
    >>> from sympy.abc import x
    >>> Point(1, 2, 3)
    Point3D(1, 2, 3)
    >>> Point([1, 2])
    Point2D(1, 2)
    >>> Point(0, x)
    Point2D(0, x)
    >>> Point(dim=4)
    Point(0, 0, 0, 0)

    Floats are automatically converted to Rational unless the
    evaluate flag is False:

    >>> Point(0.5, 0.25)
    Point2D(1/2, 1/4)
    >>> Point(0.5, 0.25, evaluate=False)
    Point2D(0.5, 0.25)

    Tc             O   s  | dtj}| dd}t|dkr.|d n|}t|tr\d}t|| dt|kr\|S t|szttd	t
|t|dkr| dd rtjf| d }t| }| dt|}t|d	k rttd
t||kr8d	|t||}|dkrn:|dkrt|n&|dkr,tj|d	d nttdt||d  rRtdtdd |D rntdtdd |D std|d | tjf|t|   }|r|dd |tD }t|d	krd|d< t||S t|dkr
d|d< t||S tj| f| S )Nevaluateon_morphignorer   r   Fdimz<
                Expecting sequence of coordinates, not `{}`   z[
                Point requires 2 or more coordinates or
                keyword `dim` > 1.z2Dimension of {} needs to be changed from {} to {}.errorwarn)
stacklevelzf
                        on_morph value should be 'error',
                        'warn' or 'ignore'.z&Nonzero coordinates cannot be removed.c             s   s"   | ]}|j ot|jd kV  qdS )FN)	is_numberr   is_zero).0a r'   a/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/sympy/geometry/point.py	<genexpr>   s    z Point.__new__.<locals>.<genexpr>z(Imaginary coordinates are not permitted.c             s   s   | ]}t |tV  qd S )N)
isinstancer   )r%   r&   r'   r'   r(   r)      s    z,Coordinates must be valid SymPy expressions.c             S   s   i | ]}t t|d d|qS )T)Zrational)r
   r	   )r%   fr'   r'   r(   
<dictcomp>   s   z!Point.__new__.<locals>.<dictcomp>T_nocheck   )getr   r   lenr*   r   r   	TypeErrorr   formatr   r   Zeror   
ValueErrorwarningsr!   anyallZxreplaceZatomsr   Point2DPoint3Dr   __new__)clsargskwargsr   r   coordsr   messager'   r'   r(   r:   m   s\    



 


zPoint.__new__c             C   s   t dgt|  }t || S )z7Returns the distance between this point and the origin.r   )r   r0   distance)selforiginr'   r'   r(   __abs__   s    zPoint.__abs__c             C   s`   yt | t |dd\}}W n" tk
r>   td|Y nX dd t||D }t |ddS )a8  Add other to self by incrementing self's coordinates by
        those of other.

        Notes
        =====

        >>> from sympy import Point

        When sequences of coordinates are passed to Point methods, they
        are converted to a Point internally. This __add__ method does
        not do that so if floating point values are used, a floating
        point result (in terms of SymPy Floats) will be returned.

        >>> Point(1, 2) + (.1, .2)
        Point2D(1.1, 2.2)

        If this is not desired, the `translate` method can be used or
        another Point can be added:

        >>> Point(1, 2).translate(.1, .2)
        Point2D(11/10, 11/5)
        >>> Point(1, 2) + Point(.1, .2)
        Point2D(11/10, 11/5)

        See Also
        ========

        sympy.geometry.point.Point.translate

        F)r   z+Don't know how to add {} and a Point objectc             S   s   g | ]\}}t || qS r'   )r
   )r%   r&   br'   r'   r(   
<listcomp>   s    z!Point.__add__.<locals>.<listcomp>)r   _normalize_dimensionr1   r   r2   zip)rA   othersor>   r'   r'   r(   __add__   s    zPoint.__add__c             C   s
   || j kS )N)r<   )rA   itemr'   r'   r(   __contains__   s    zPoint.__contains__c                s(   t    fdd| jD }t|ddS )z'Divide point's coordinates by a factor.c                s   g | ]}t |  qS r'   )r
   )r%   x)divisorr'   r(   rE      s    z%Point.__truediv__.<locals>.<listcomp>F)r   )r   r<   r   )rA   rO   r>   r'   )rO   r(   __truediv__   s    zPoint.__truediv__c             C   s.   t |trt| jt|jkr"dS | j|jkS )NF)r*   r   r0   r<   )rA   rH   r'   r'   r(   __eq__   s    zPoint.__eq__c             C   s
   | j | S )N)r<   )rA   keyr'   r'   r(   __getitem__   s    zPoint.__getitem__c             C   s
   t | jS )N)hashr<   )rA   r'   r'   r(   __hash__   s    zPoint.__hash__c             C   s
   | j  S )N)r<   __iter__)rA   r'   r'   r(   rV      s    zPoint.__iter__c             C   s
   t | jS )N)r0   r<   )rA   r'   r'   r(   __len__   s    zPoint.__len__c                s(   t    fdd| jD }t|ddS )al  Multiply point's coordinates by a factor.

        Notes
        =====

        >>> from sympy import Point

        When multiplying a Point by a floating point number,
        the coordinates of the Point will be changed to Floats:

        >>> Point(1, 2)*0.1
        Point2D(0.1, 0.2)

        If this is not desired, the `scale` method can be used or
        else only multiply or divide by integers:

        >>> Point(1, 2).scale(1.1, 1.1)
        Point2D(11/10, 11/5)
        >>> Point(1, 2)*11/10
        Point2D(11/10, 11/5)

        See Also
        ========

        sympy.geometry.point.Point.scale
        c                s   g | ]}t |  qS r'   )r
   )r%   rN   )factorr'   r(   rE     s    z!Point.__mul__.<locals>.<listcomp>F)r   )r   r<   r   )rA   rX   r>   r'   )rX   r(   __mul__   s    zPoint.__mul__c             C   s
   |  |S )z)Multiply a factor by point's coordinates.)rY   )rA   rX   r'   r'   r(   __rmul__  s    zPoint.__rmul__c             C   s   dd | j D }t|ddS )zNegate the point.c             S   s   g | ]
}| qS r'   r'   )r%   rN   r'   r'   r(   rE      s    z!Point.__neg__.<locals>.<listcomp>F)r   )r<   r   )rA   r>   r'   r'   r(   __neg__  s    zPoint.__neg__c             C   s   | dd |D  S )zPSubtract two points, or subtract a factor from this point's
        coordinates.c             S   s   g | ]
}| qS r'   r'   )r%   rN   r'   r'   r(   rE   &  s    z!Point.__sub__.<locals>.<listcomp>r'   )rA   rH   r'   r'   r(   __sub__#  s    zPoint.__sub__c                sz   t | dd d   dkr2tdd |D  t fdd|D rPt|S  d< ddd< fd	d
|D S )z~Ensure that points have the same dimension.
        By default `on_morph='warn'` is passed to the
        `Point` constructor._ambient_dimensionNr   c             s   s   | ]}|j V  qd S )N)ambient_dimension)r%   ir'   r'   r(   r)   3  s    z-Point._normalize_dimension.<locals>.<genexpr>c             3   s   | ]}|j  kV  qd S )N)r^   )r%   r_   )r   r'   r(   r)   4  s    r   r!   c                s   g | ]}t |f qS r'   )r   )r%   r_   )r=   r'   r(   rE   8  s    z.Point._normalize_dimension.<locals>.<listcomp>)getattrr/   maxr7   list)r;   pointsr=   r'   )r   r=   r(   rF   (  s    zPoint._normalize_dimensionc                 sh   t | dkrdS tjdd | D  }|d   fdd|dd D }tdd |D }|jd	d
 dS )ag  The affine rank of a set of points is the dimension
        of the smallest affine space containing all the points.
        For example, if the points lie on a line (and are not all
        the same) their affine rank is 1.  If the points lie on a plane
        but not a line, their affine rank is 2.  By convention, the empty
        set has affine rank -1.r   c             S   s   g | ]}t |qS r'   )r   )r%   r_   r'   r'   r(   rE   G  s    z%Point.affine_rank.<locals>.<listcomp>c                s   g | ]}|  qS r'   r'   )r%   r_   )rB   r'   r(   rE   I  s    r   Nc             S   s   g | ]
}|j qS r'   )r<   )r%   r_   r'   r'   r(   rE   K  s    c             S   s   | j rt| ddk S | jS )Nr   g-q=)r#   absnr$   )rN   r'   r'   r(   <lambda>M  s    z#Point.affine_rank.<locals>.<lambda>)Z
iszerofunc)r0   r   rF   r   rank)r<   rc   mr'   )rB   r(   affine_rank:  s    	zPoint.affine_rankc             C   s   t | dt| S )z$Number of components this point has.r]   )r`   r0   )rA   r'   r'   r(   r^   P  s    zPoint.ambient_dimensionc             G   sP   t |dkrdS | jdd |D  }|d jdkr6dS tt|}tj| dkS )a  Return True if there exists a plane in which all the points
        lie.  A trivial True value is returned if `len(points) < 3` or
        all Points are 2-dimensional.

        Parameters
        ==========

        A set of points

        Raises
        ======

        ValueError : if less than 3 unique points are given

        Returns
        =======

        boolean

        Examples
        ========

        >>> from sympy import Point3D
        >>> p1 = Point3D(1, 2, 2)
        >>> p2 = Point3D(2, 7, 2)
        >>> p3 = Point3D(0, 0, 2)
        >>> p4 = Point3D(1, 1, 2)
        >>> Point3D.are_coplanar(p1, p2, p3, p4)
        True
        >>> p5 = Point3D(0, 1, 3)
        >>> Point3D.are_coplanar(p1, p2, p3, p5)
        False

        r   Tc             S   s   g | ]}t |qS r'   )r   )r%   r_   r'   r'   r(   rE   |  s    z&Point.are_coplanar.<locals>.<listcomp>r   r   )r0   rF   r^   rb   r   r   rj   )r;   rc   r'   r'   r(   are_coplanarU  s    $zPoint.are_coplanarc             C   s   t |tsByt|| jd}W n$ tk
r@   tdt| Y nX t |tr|t| t|\}}ttdd t	||D  S t
|dd}|dkrtdt| || S )az  The Euclidean distance between self and another GeometricEntity.

        Returns
        =======

        distance : number or symbolic expression.

        Raises
        ======

        TypeError : if other is not recognized as a GeometricEntity or is a
                    GeometricEntity for which distance is not defined.

        See Also
        ========

        sympy.geometry.line.Segment.length
        sympy.geometry.point.Point.taxicab_distance

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(1, 1), Point(4, 5)
        >>> l = Line((3, 1), (2, 2))
        >>> p1.distance(p2)
        5
        >>> p1.distance(l)
        sqrt(2)

        The computed distance may be symbolic, too:

        >>> from sympy.abc import x, y
        >>> p3 = Point(x, y)
        >>> p3.distance((0, 0))
        sqrt(x**2 + y**2)

        )r   z'not recognized as a GeometricEntity: %sc             s   s   | ]\}}|| d  V  qdS )r   Nr'   )r%   r&   rD   r'   r'   r(   r)     s    z!Point.distance.<locals>.<genexpr>r@   Nz,distance between Point and %s is not defined)r*   r   r   r^   r1   typerF   r   r   rG   r`   )rA   rH   rI   pr@   r'   r'   r(   r@     s    '

zPoint.distancec             C   s(   t |st|}tdd t| |D  S )z.Return dot product of self with another Point.c             s   s   | ]\}}|| V  qd S )Nr'   )r%   r&   rD   r'   r'   r(   r)     s    zPoint.dot.<locals>.<genexpr>)r   r   r   rG   )rA   rm   r'   r'   r(   dot  s    z	Point.dotc             C   s6   t |trt| t|krdS tdd t| |D S )z8Returns whether the coordinates of self and other agree.Fc             s   s   | ]\}}| |V  qd S )N)equals)r%   r&   rD   r'   r'   r(   r)     s    zPoint.equals.<locals>.<genexpr>)r*   r   r0   r7   rG   )rA   rH   r'   r'   r(   ro     s    zPoint.equals   c                s,   t |  fdd| jD }t|ddiS )aF  Evaluate the coordinates of the point.

        This method will, where possible, create and return a new Point
        where the coordinates are evaluated as floating point numbers to
        the precision indicated (default=15).

        Parameters
        ==========

        prec : int

        Returns
        =======

        point : Point

        Examples
        ========

        >>> from sympy import Point, Rational
        >>> p1 = Point(Rational(1, 2), Rational(3, 2))
        >>> p1
        Point2D(1/2, 3/2)
        >>> p1.evalf()
        Point2D(0.5, 1.5)

        c                s    g | ]}|j f d  iqS )rf   )Zevalf)r%   rN   )dpsoptionsr'   r(   rE     s    z%Point._eval_evalf.<locals>.<listcomp>r   F)r   r<   r   )rA   precrr   r>   r'   )rq   rr   r(   _eval_evalf  s    zPoint._eval_evalfc             C   s^   t |tst|}t |trT| |kr*| gS t| |\}}|| krP||krP| gS g S || S )a|  The intersection between this point and another GeometryEntity.

        Parameters
        ==========

        other : GeometryEntity or sequence of coordinates

        Returns
        =======

        intersection : list of Points

        Notes
        =====

        The return value will either be an empty list if there is no
        intersection, otherwise it will contain this point.

        Examples
        ========

        >>> from sympy import Point
        >>> p1, p2, p3 = Point(0, 0), Point(1, 1), Point(0, 0)
        >>> p1.intersection(p2)
        []
        >>> p1.intersection(p3)
        [Point2D(0, 0)]

        )r*   r   r   rF   intersection)rA   rH   p1p2r'   r'   r(   ru     s    

zPoint.intersectionc             G   s8   | f| }t jdd |D  }tt|}t j| dkS )a  Returns `True` if there exists a line
        that contains `self` and `points`.  Returns `False` otherwise.
        A trivially True value is returned if no points are given.

        Parameters
        ==========

        args : sequence of Points

        Returns
        =======

        is_collinear : boolean

        See Also
        ========

        sympy.geometry.line.Line

        Examples
        ========

        >>> from sympy import Point
        >>> from sympy.abc import x
        >>> p1, p2 = Point(0, 0), Point(1, 1)
        >>> p3, p4, p5 = Point(2, 2), Point(x, x), Point(1, 2)
        >>> Point.is_collinear(p1, p2, p3, p4)
        True
        >>> Point.is_collinear(p1, p2, p3, p5)
        False

        c             S   s   g | ]}t |qS r'   )r   )r%   r_   r'   r'   r(   rE   /  s    z&Point.is_collinear.<locals>.<listcomp>r   )r   rF   rb   r   rj   )rA   r<   rc   r'   r'   r(   is_collinear  s    !
zPoint.is_collinearc                s   | f| }t jdd |D  }tt|}t j| dks<dS |d   fdd|D }tdd |D }| \}}t |krdS dS )	a  Do `self` and the given sequence of points lie in a circle?

        Returns True if the set of points are concyclic and
        False otherwise. A trivial value of True is returned
        if there are fewer than 2 other points.

        Parameters
        ==========

        args : sequence of Points

        Returns
        =======

        is_concyclic : boolean


        Examples
        ========

        >>> from sympy import Point

        Define 4 points that are on the unit circle:

        >>> p1, p2, p3, p4 = Point(1, 0), (0, 1), (-1, 0), (0, -1)

        >>> p1.is_concyclic() == p1.is_concyclic(p2, p3, p4) == True
        True

        Define a point not on that circle:

        >>> p = Point(1, 1)

        >>> p.is_concyclic(p1, p2, p3)
        False

        c             S   s   g | ]}t |qS r'   )r   )r%   r_   r'   r'   r(   rE   Z  s    z&Point.is_concyclic.<locals>.<listcomp>r   Fr   c                s   g | ]}|  qS r'   r'   )r%   rm   )rB   r'   r(   rE   _  s    c             S   s    g | ]}t |||g qS r'   )rb   rn   )r%   r_   r'   r'   r(   rE   e  s    T)r   rF   rb   r   rj   r   rrefr0   )rA   r<   rc   matry   Zpivotsr'   )rB   r(   is_concyclic3  s    &
zPoint.is_concyclicc             C   s   | j }|dkrdS | S )zrTrue if any coordinate is nonzero, False if every coordinate is zero,
        and None if it cannot be determined.N)r$   )rA   r$   r'   r'   r(   
is_nonzerok  s    zPoint.is_nonzeroc       
      C   s   t | t |\}}|jdkrf|j|j \}}\}}|| ||  d}|dkrfttd||f t|j|jg}	|	 dk S )z{Returns whether each coordinate of `self` is a scalar
        multiple of the corresponding coordinate in point p.
        r   r   NzECannot determine if %s is a scalar multiple of
                    %s)	r   rF   r^   r<   ro   r   r   r   rh   )
rA   rm   rI   rJ   x1y1Zx2y2rvri   r'   r'   r(   is_scalar_multiplet  s    
zPoint.is_scalar_multiplec             C   s6   dd | j D }t|rdS tdd |D r2dS dS )zsTrue if every coordinate is zero, False if any coordinate is not zero,
        and None if it cannot be determined.c             S   s   g | ]
}|j qS r'   )r|   )r%   rN   r'   r'   r(   rE     s    z!Point.is_zero.<locals>.<listcomp>Fc             s   s   | ]}|d kV  qd S )Nr'   )r%   rN   r'   r'   r(   r)     s    z Point.is_zero.<locals>.<genexpr>NT)r<   r6   )rA   Znonzeror'   r'   r(   r$     s    zPoint.is_zeroc             C   s   t jS )z
        Treating a Point as a Line, this returns 0 for the length of a Point.

        Examples
        ========

        >>> from sympy import Point
        >>> p = Point(0, 1)
        >>> p.length
        0
        )r   r3   )rA   r'   r'   r(   length  s    zPoint.lengthc             C   s,   t | t |\}}t dd t||D S )a  The midpoint between self and point p.

        Parameters
        ==========

        p : Point

        Returns
        =======

        midpoint : Point

        See Also
        ========

        sympy.geometry.line.Segment.midpoint

        Examples
        ========

        >>> from sympy import Point
        >>> p1, p2 = Point(1, 1), Point(13, 5)
        >>> p1.midpoint(p2)
        Point2D(7, 3)

        c             S   s"   g | ]\}}t || tj qS r'   )r
   r   ZHalf)r%   r&   rD   r'   r'   r(   rE     s    z"Point.midpoint.<locals>.<listcomp>)r   rF   rG   )rA   rm   rI   r'   r'   r(   midpoint  s    zPoint.midpointc             C   s   t dgt|  ddS )zOA point of all zeros of the same ambient dimension
        as the current pointr   F)r   )r   r0   )rA   r'   r'   r(   rB     s    zPoint.originc             C   sp   | j }| d jr(tdg|d dg  S | d jrLtddg|d dg  S t| d  | d g|d dg  S )au  Returns a non-zero point that is orthogonal to the
        line containing `self` and the origin.

        Examples
        ========

        >>> from sympy import Line, Point
        >>> a = Point(1, 2, 3)
        >>> a.orthogonal_direction
        Point3D(-2, 1, 0)
        >>> b = _
        >>> Line(b, b.origin).is_perpendicular(Line(a, a.origin))
        True
        r   r   r   )r^   r$   r   )rA   r   r'   r'   r(   orthogonal_direction  s    

zPoint.orthogonal_directionc             C   s>   t t | t |\} }|jr&td|| |||  S )a  Project the point `a` onto the line between the origin
        and point `b` along the normal direction.

        Parameters
        ==========

        a : Point
        b : Point

        Returns
        =======

        p : Point

        See Also
        ========

        sympy.geometry.line.LinearEntity.projection

        Examples
        ========

        >>> from sympy import Line, Point
        >>> a = Point(1, 2)
        >>> b = Point(2, 5)
        >>> z = a.origin
        >>> p = Point.project(a, b)
        >>> Line(p, a).is_perpendicular(Line(p, b))
        True
        >>> Point.is_collinear(z, p, b)
        True
        z"Cannot project to the zero vector.)r   rF   r$   r4   rn   )r&   rD   r'   r'   r(   project  s    "zPoint.projectc             C   s,   t | t |\}}tdd t||D  S )a2  The Taxicab Distance from self to point p.

        Returns the sum of the horizontal and vertical distances to point p.

        Parameters
        ==========

        p : Point

        Returns
        =======

        taxicab_distance : The sum of the horizontal
        and vertical distances to point p.

        See Also
        ========

        sympy.geometry.point.Point.distance

        Examples
        ========

        >>> from sympy import Point
        >>> p1, p2 = Point(1, 1), Point(4, 5)
        >>> p1.taxicab_distance(p2)
        7

        c             s   s   | ]\}}t || V  qd S )N)re   )r%   r&   rD   r'   r'   r(   r)   %  s    z)Point.taxicab_distance.<locals>.<genexpr>)r   rF   r   rG   )rA   rm   rI   r'   r'   r(   taxicab_distance  s    zPoint.taxicab_distancec             C   s@   t | t |\}}| jr(|jr(tdtdd t||D  S )a=  The Canberra Distance from self to point p.

        Returns the weighted sum of horizontal and vertical distances to
        point p.

        Parameters
        ==========

        p : Point

        Returns
        =======

        canberra_distance : The weighted sum of horizontal and vertical
        distances to point p. The weight used is the sum of absolute values
        of the coordinates.

        Examples
        ========

        >>> from sympy import Point
        >>> p1, p2 = Point(1, 1), Point(3, 3)
        >>> p1.canberra_distance(p2)
        1
        >>> p1, p2 = Point(0, 0), Point(3, 3)
        >>> p1.canberra_distance(p2)
        2

        Raises
        ======

        ValueError when both vectors are zero.

        See Also
        ========

        sympy.geometry.point.Point.distance

        z"Cannot project to the zero vector.c             s   s.   | ]&\}}t || t |t |  V  qd S )N)re   )r%   r&   rD   r'   r'   r(   r)   S  s    z*Point.canberra_distance.<locals>.<genexpr>)r   rF   r$   r4   r   rG   )rA   rm   rI   r'   r'   r(   canberra_distance'  s    )zPoint.canberra_distancec             C   s   | t |  S )zdReturn the Point that is in the same direction as `self`
        and a distance of 1 from the origin)re   )rA   r'   r'   r(   unitU  s    z
Point.unitN)rp   ),__name__
__module____qualname____doc__Zis_Pointr:   rC   rK   rM   rP   rQ   rS   rU   rV   rW   rY   rZ   r[   r\   classmethodrF   staticmethodrj   propertyr^   rk   r@   rn   ro   rt   ru   rx   r{   r|   r   r$   r   r   rB   r   r   r   r   r   r'   r'   r'   r(   r   *   sL   ?H'.4
 )&8	'!.r   c               @   s   e Zd ZdZdZddddZdd Zed	d
 ZdddZ	dddZ
dd ZdddZedd Zedd Zedd ZdS )r8   a  A point in a 2-dimensional Euclidean space.

    Parameters
    ==========

    coords : sequence of 2 coordinate values.

    Attributes
    ==========

    x
    y
    length

    Raises
    ======

    TypeError
        When trying to add or subtract points with different dimensions.
        When trying to create a point with more than two dimensions.
        When `intersection` is called with object other than a Point.

    See Also
    ========

    sympy.geometry.line.Segment : Connects two Points

    Examples
    ========

    >>> from sympy import Point2D
    >>> from sympy.abc import x
    >>> Point2D(1, 2)
    Point2D(1, 2)
    >>> Point2D([1, 2])
    Point2D(1, 2)
    >>> Point2D(0, x)
    Point2D(0, x)

    Floats are automatically converted to Rational unless the
    evaluate flag is False:

    >>> Point2D(0.5, 0.25)
    Point2D(1/2, 1/4)
    >>> Point2D(0.5, 0.25, evaluate=False)
    Point2D(0.5, 0.25)

    r   F)r-   c            O   s&   |sd|d< t ||}tj| f| S )Nr   r   )r   r   r:   )r;   r-   r<   r=   r'   r'   r(   r:     s    
zPoint2D.__new__c             C   s   || kS )Nr'   )rA   rL   r'   r'   r(   rM     s    zPoint2D.__contains__c             C   s   | j | j| j | jfS )zwReturn a tuple (xmin, ymin, xmax, ymax) representing the bounding
        rectangle for the geometric figure.

        )rN   y)rA   r'   r'   r(   bounds  s    zPoint2D.boundsNc             C   sp   t |}t|}| }|dk	r0t|dd}||8 }|j\}}t|| ||  || ||  }|dk	rl||7 }|S )a[  Rotate ``angle`` radians counterclockwise about Point ``pt``.

        See Also
        ========

        translate, scale

        Examples
        ========

        >>> from sympy import Point2D, pi
        >>> t = Point2D(1, 0)
        >>> t.rotate(pi/2)
        Point2D(0, 1)
        >>> t.rotate(pi/2, (2, 0))
        Point2D(2, -1)

        Nr   )r   )r   r   r   r<   )rA   ZangleptcrI   r   rN   r   r'   r'   r(   rotate  s    
"zPoint2D.rotater   c             C   sD   |r.t |dd}| j| j ||j|j S t | j| | j| S )a  Scale the coordinates of the Point by multiplying by
        ``x`` and ``y`` after subtracting ``pt`` -- default is (0, 0) --
        and then adding ``pt`` back again (i.e. ``pt`` is the point of
        reference for the scaling).

        See Also
        ========

        rotate, translate

        Examples
        ========

        >>> from sympy import Point2D
        >>> t = Point2D(1, 1)
        >>> t.scale(2)
        Point2D(2, 1)
        >>> t.scale(2, 2)
        Point2D(2, 2)

        r   )r   )r   	translater<   scalerN   r   )rA   rN   r   r   r'   r'   r(   r     s    zPoint2D.scalec             C   sL   |j r|jdkstd| j\}}ttdd||dg|  d dd  S )a  Return the point after applying the transformation described
        by the 3x3 Matrix, ``matrix``.

        See Also
        ========
        sympy.geometry.point.Point2D.rotate
        sympy.geometry.point.Point2D.scale
        sympy.geometry.point.Point2D.translate
        )r.   r.   zmatrix must be a 3x3 matrixr   r.   r   Nr   )	is_Matrixshaper4   r<   r   r   tolist)rA   matrixrN   r   r'   r'   r(   	transform  s    

zPoint2D.transformr   c             C   s   t | j| | j| S )a  Shift the Point by adding x and y to the coordinates of the Point.

        See Also
        ========

        sympy.geometry.point.Point2D.rotate, scale

        Examples
        ========

        >>> from sympy import Point2D
        >>> t = Point2D(0, 1)
        >>> t.translate(2)
        Point2D(2, 1)
        >>> t.translate(2, 2)
        Point2D(2, 3)
        >>> t + Point2D(2, 2)
        Point2D(2, 3)

        )r   rN   r   )rA   rN   r   r'   r'   r(   r     s    zPoint2D.translatec             C   s   | j S )z
        Returns the two coordinates of the Point.

        Examples
        ========

        >>> from sympy import Point2D
        >>> p = Point2D(0, 1)
        >>> p.coordinates
        (0, 1)
        )r<   )rA   r'   r'   r(   coordinates  s    zPoint2D.coordinatesc             C   s
   | j d S )z
        Returns the X coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point2D
        >>> p = Point2D(0, 1)
        >>> p.x
        0
        r   )r<   )rA   r'   r'   r(   rN     s    z	Point2D.xc             C   s
   | j d S )z
        Returns the Y coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point2D
        >>> p = Point2D(0, 1)
        >>> p.y
        1
        r   )r<   )rA   r'   r'   r(   r   !  s    z	Point2D.y)N)r   r   N)r   r   )r   r   r   r   r]   r:   rM   r   r   r   r   r   r   r   rN   r   r'   r'   r'   r(   r8   \  s   0	
 

r8   c               @   s   e Zd ZdZdZddddZdd Zed	d
 Zdd Z	dd Z
dd Zd"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dS )$r9   a6  A point in a 3-dimensional Euclidean space.

    Parameters
    ==========

    coords : sequence of 3 coordinate values.

    Attributes
    ==========

    x
    y
    z
    length

    Raises
    ======

    TypeError
        When trying to add or subtract points with different dimensions.
        When `intersection` is called with object other than a Point.

    Examples
    ========

    >>> from sympy import Point3D
    >>> from sympy.abc import x
    >>> Point3D(1, 2, 3)
    Point3D(1, 2, 3)
    >>> Point3D([1, 2, 3])
    Point3D(1, 2, 3)
    >>> Point3D(0, x, 3)
    Point3D(0, x, 3)

    Floats are automatically converted to Rational unless the
    evaluate flag is False:

    >>> Point3D(0.5, 0.25, 2)
    Point3D(1/2, 1/4, 2)
    >>> Point3D(0.5, 0.25, 3, evaluate=False)
    Point3D(0.5, 0.25, 3)

    r.   F)r-   c            O   s&   |sd|d< t ||}tj| f| S )Nr.   r   )r   r   r:   )r;   r-   r<   r=   r'   r'   r(   r:   _  s    
zPoint3D.__new__c             C   s   || kS )Nr'   )rA   rL   r'   r'   r(   rM   e  s    zPoint3D.__contains__c              G   s
   t j|  S )a  Is a sequence of points collinear?

        Test whether or not a set of points are collinear. Returns True if
        the set of points are collinear, or False otherwise.

        Parameters
        ==========

        points : sequence of Point

        Returns
        =======

        are_collinear : boolean

        See Also
        ========

        sympy.geometry.line.Line3D

        Examples
        ========

        >>> from sympy import Point3D
        >>> from sympy.abc import x
        >>> p1, p2 = Point3D(0, 0, 0), Point3D(1, 1, 1)
        >>> p3, p4, p5 = Point3D(2, 2, 2), Point3D(x, x, x), Point3D(1, 2, 6)
        >>> Point3D.are_collinear(p1, p2, p3, p4)
        True
        >>> Point3D.are_collinear(p1, p2, p3, p5)
        False
        )r   rx   )rc   r'   r'   r(   are_collinearh  s    "zPoint3D.are_collinearc             C   sN   |  |}ttdd |D  }|j| j | |j| j | |j| j | gS )ap  
        Gives the direction cosine between 2 points

        Parameters
        ==========

        p : Point3D

        Returns
        =======

        list

        Examples
        ========

        >>> from sympy import Point3D
        >>> p1 = Point3D(1, 2, 3)
        >>> p1.direction_cosine(Point3D(2, 3, 5))
        [sqrt(6)/6, sqrt(6)/6, sqrt(6)/3]
        c             s   s   | ]}|d  V  qdS )r   Nr'   )r%   r_   r'   r'   r(   r)     s    z+Point3D.direction_cosine.<locals>.<genexpr>)direction_ratior   r   rN   r   z)rA   pointr&   rD   r'   r'   r(   direction_cosine  s    
zPoint3D.direction_cosinec             C   s"   |j | j  |j| j |j| j gS )aV  
        Gives the direction ratio between 2 points

        Parameters
        ==========

        p : Point3D

        Returns
        =======

        list

        Examples
        ========

        >>> from sympy import Point3D
        >>> p1 = Point3D(1, 2, 3)
        >>> p1.direction_ratio(Point3D(2, 3, 5))
        [1, 1, 2]
        )rN   r   r   )rA   r   r'   r'   r(   r     s    zPoint3D.direction_ratioc             C   s<   t |tst|dd}t |tr2| |kr.| gS g S || S )a  The intersection between this point and another GeometryEntity.

        Parameters
        ==========

        other : GeometryEntity or sequence of coordinates

        Returns
        =======

        intersection : list of Points

        Notes
        =====

        The return value will either be an empty list if there is no
        intersection, otherwise it will contain this point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(1, 1, 1), Point3D(0, 0, 0)
        >>> p1.intersection(p2)
        []
        >>> p1.intersection(p3)
        [Point3D(0, 0, 0)]

        r.   )r   )r*   r   r   r9   ru   )rA   rH   r'   r'   r(   ru     s    

zPoint3D.intersectionr   Nc             C   sJ   |r,t |}| j| j |||j|j S t | j| | j| | j| S )a  Scale the coordinates of the Point by multiplying by
        ``x`` and ``y`` after subtracting ``pt`` -- default is (0, 0) --
        and then adding ``pt`` back again (i.e. ``pt`` is the point of
        reference for the scaling).

        See Also
        ========

        translate

        Examples
        ========

        >>> from sympy import Point3D
        >>> t = Point3D(1, 1, 1)
        >>> t.scale(2)
        Point3D(2, 1, 1)
        >>> t.scale(2, 2)
        Point3D(2, 2, 1)

        )r9   r   r<   r   rN   r   r   )rA   rN   r   r   r   r'   r'   r(   r     s     zPoint3D.scalec             C   sX   |j r|jdkstd| j\}}}t|}ttdd|||dg|  d dd  S )zReturn the point after applying the transformation described
        by the 4x4 Matrix, ``matrix``.

        See Also
        ========
        sympy.geometry.point.Point3D.scale
        sympy.geometry.point.Point3D.translate
        )   r   zmatrix must be a 4x4 matrixr   r   r   Nr.   )r   r   r4   r<   r   r9   r   r   )rA   r   rN   r   r   ri   r'   r'   r(   r      s
    	zPoint3D.transformr   c             C   s   t | j| | j| | j| S )a  Shift the Point by adding x and y to the coordinates of the Point.

        See Also
        ========

        scale

        Examples
        ========

        >>> from sympy import Point3D
        >>> t = Point3D(0, 1, 1)
        >>> t.translate(2)
        Point3D(2, 1, 1)
        >>> t.translate(2, 2)
        Point3D(2, 3, 1)
        >>> t + Point3D(2, 2, 2)
        Point3D(2, 3, 3)

        )r9   rN   r   r   )rA   rN   r   r   r'   r'   r(   r     s    zPoint3D.translatec             C   s   | j S )z
        Returns the three coordinates of the Point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p = Point3D(0, 1, 2)
        >>> p.coordinates
        (0, 1, 2)
        )r<   )rA   r'   r'   r(   r   &  s    zPoint3D.coordinatesc             C   s
   | j d S )z
        Returns the X coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p = Point3D(0, 1, 3)
        >>> p.x
        0
        r   )r<   )rA   r'   r'   r(   rN   5  s    z	Point3D.xc             C   s
   | j d S )z
        Returns the Y coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p = Point3D(0, 1, 2)
        >>> p.y
        1
        r   )r<   )rA   r'   r'   r(   r   D  s    z	Point3D.yc             C   s
   | j d S )z
        Returns the Z coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p = Point3D(0, 1, 1)
        >>> p.z
        1
        r   )r<   )rA   r'   r'   r(   r   S  s    z	Point3D.z)r   r   r   N)r   r   r   )r   r   r   r   r]   r:   rM   r   r   r   r   ru   r   r   r   r   r   rN   r   r   r'   r'   r'   r(   r9   0  s   +$&

r9   ),r   r5   Z
sympy.corer   r   r   Zsympy.core.addr   Zsympy.core.containersr   Zsympy.core.numbersr   Zsympy.core.parametersr   Zsympy.simplifyr	   r
   Zsympy.geometry.exceptionsr   Z(sympy.functions.elementary.miscellaneousr   Z$sympy.functions.elementary.complexesr   Z(sympy.functions.elementary.trigonometricr   r   Zsympy.matricesr   Zsympy.matrices.expressionsr   Zsympy.utilities.iterablesr   r   Zsympy.utilities.miscr   r   r   entityr   Zmpmath.libmp.libmpfr   r   r8   r9   r'   r'   r'   r(   <module>   s6         8 U