U
    ZÊ¹j,�  ã                   @   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 ¡r¤tjf|  d¡ }t|Ž }|  dt|ƒ¡}t|ƒd	k rÔttd
ƒƒ‚t|ƒ|k�r8d 	|t|ƒ|¡}|dkrþn:|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 ƒƒ�sŠtdƒ‚|d |… tjf|t|ƒ   }|�rÊ| dd„ | t¡D ƒ¡}t|ƒd	k�rêd|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(   úS/var/www/html/bwave/python/venv/lib/python3.8/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*   �   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   r2   Údistance)ÚselfÚoriginr(   r(   r)   Ú__abs__µ   s    zPoint.__abs__c                 C   s`   z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_dimensionr3   r   r4   Úzip)rC   ÚotherÚsÚor@   r(   r(   r)   Ú__add__º   s    zPoint.__add__c                 C   s
   || j kS r+   ©r>   ©rC   Ú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(   rG   ©r&   Úx©Údivisorr(   r)   rJ   ç   s     z%Point.__truediv__.<locals>.<listcomp>FrF   ©r   r>   r   )rC   rX   r@   r(   rW   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   r2   r>   ©rC   rM   r(   r(   r)   Ú__eq__ê   s    zPoint.__eq__c                 C   s
   | j | S r+   rQ   )rC   Úkeyr(   r(   r)   Ú__getitem__ï   s    zPoint.__getitem__c                 C   s
   t | jƒS r+   )Úhashr>   ©rC   r(   r(   r)   Ú__hash__ò   s    zPoint.__hash__c                 C   s
   | j  ¡ S r+   )r>   Ú__iter__r`   r(   r(   r)   rb   õ   s    zPoint.__iter__c                 C   s
   t | jƒS r+   )r2   r>   r`   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(   rG   rU   ©Úfactorr(   r)   rJ     s     z!Point.__mul__.<locals>.<listcomp>FrF   rY   )rC   re   r@   r(   rd   r)   Ú__mul__û   s    zPoint.__mul__c                 C   s
   |   |¡S )z)Multiply a factor by point's coordinates.)rf   )rC   re   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(   rU   r(   r(   r)   rJ      s     z!Point.__neg__.<locals>.<listcomp>FrF   )r>   r   )rC   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(   rU   r(   r(   r)   rJ   &  s     z!Point.__sub__.<locals>.<listcomp>r(   r[   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 r+   ©Úambient_dimension©r&   Úir(   r(   r)   r*   3  s     z-Point._normalize_dimension.<locals>.<genexpr>c                 3   s   | ]}|j ˆ kV  qd S r+   rk   rm   ©r   r(   r)   r*   4  s     r   r!   c                    s   g | ]}t |fˆ Ž‘qS r(   ©r   rm   )r?   r(   r)   rJ   8  s     z.Point._normalize_dimension.<locals>.<listcomp>)Úgetattrr1   Úmaxr9   Úlist)r=   Úpointsr?   r(   )r   r?   r)   rK   (  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(   rp   rm   r(   r(   r)   rJ   G  s     z%Point.affine_rank.<locals>.<listcomp>c                    s   g | ]}|ˆ  ‘qS r(   r(   rm   ©rD   r(   r)   rJ   I  s     r   Nc                 S   s   g | ]
}|j ‘qS r(   rQ   rm   r(   r(   r)   rJ   K  s     c                 S   s   | j rt|  d¡ƒdk S | jS )Nr   gê-�™—q=)r#   ÚabsÚnr$   )rV   r(   r(   r)   Ú<lambda>M  s    z#Point.affine_rank.<locals>.<lambda>)Z
iszerofunc)r2   r   rK   r   Úrank)r>   rt   Úmr(   rv   r)   Úaffine_rank:  s    	zPoint.affine_rankc                 C   s   t | dt| ƒƒS )z$Number of components this point has.rj   )rq   r2   r`   r(   r(   r)   rl   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(   rp   rm   r(   r(   r)   rJ   |  s     z&Point.are_coplanar.<locals>.<listcomp>r   r   )r2   rK   rl   rs   r   r   r|   )r=   rt   r(   r(   r)   Úare_coplanarU  s    $zPoint.are_coplanarc                 C   s¨   t |tƒsBz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r t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)

        ro   z'not recognized as a GeometricEntity: %sc                 s   s   | ]\}}|| d  V  qdS ©r   Nr(   rH   r(   r(   r)   r*   ±  s     z!Point.distance.<locals>.<genexpr>rB   Nz,distance between Point and %s is not defined)r,   r   r   rl   r3   ÚtyperK   r   r   rL   rq   )rC   rM   rN   ÚprB   r(   r(   r)   rB   ƒ  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 r+   r(   rH   r(   r(   r)   r*   »  s     zPoint.dot.<locals>.<genexpr>)r   r   r   rL   )rC   r€   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 r+   )ÚequalsrH   r(   r(   r)   r*   Â  s     zPoint.equals.<locals>.<genexpr>)r,   r   r2   r9   rL   r[   r(   r(   r)   r‚   ½  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 )rx   )ZevalfrU   ©ZdpsÚoptionsr(   r)   rJ   á  s     z%Point._eval_evalf.<locals>.<listcomp>r   F)r   r>   r   )rC   Úprecr…   r@   r(   r„   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   rK   Úintersection)rC   rM   Úp1Zp2r(   r(   r)   rˆ   ä  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(   rp   rm   r(   r(   r)   rJ   /  s     z&Point.is_collinear.<locals>.<listcomp>r   )r   rK   rs   r   r|   )rC   r>   rt   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r„d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(   rp   rm   r(   r(   r)   rJ   Z  s     z&Point.is_concyclic.<locals>.<listcomp>r   Fr   c                    s   g | ]}|ˆ  ‘qS r(   r(   )r&   r€   rv   r(   r)   rJ   _  s     c                 S   s    g | ]}t |ƒ| |¡g ‘qS r(   )rs   r�   rm   r(   r(   r)   rJ   e  s     T)r   rK   rs   r   r|   r   Úrrefr2   )rC   r>   rt   Zmatr‹   Zpivotsr(   rv   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$   )rC   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   rK   rl   r>   r‚   r   r   r   rz   )
rC   r€   rN   rO   Úx1Úy1Zx2Úy2Úrvr{   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�   rU   r(   r(   r)   rJ   ‹  s     z!Point.is_zero.<locals>.<listcomp>Fc                 s   s   | ]}|d kV  qd S r+   r(   rU   r(   r(   r)   r*   Ž  s     z Point.is_zero.<locals>.<genexpr>NT)r>   r8   )rC   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   r5   r`   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HalfrH   r(   r(   r)   rJ   ½  s     z"Point.midpoint.<locals>.<listcomp>)r   rK   rL   ©rC   r€   rN   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   FrF   )r   r2   r`   r(   r(   r)   rD   ¿  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   )rl   r$   r   )rC   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
        ú"Cannot project to the zero vector.)r   rK   r$   r6   r�   )r'   rI   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 r+   ©rw   rH   r(   r(   r)   r*   %  s     z)Point.taxicab_distance.<locals>.<genexpr>)r   rK   r   rL   r”   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

        r—   c                 s   s.   | ]&\}}t || ƒt |ƒt |ƒ  V  qd S r+   r™   rH   r(   r(   r)   r*   S  s     z*Point.canberra_distance.<locals>.<genexpr>)r   rK   r$   r6   r   rL   r”   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 originr™   r`   r(   r(   r)   ÚunitU  s    z
Point.unitN)rƒ   ),Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zis_Pointr<   rE   rP   rT   rZ   r\   r^   ra   rb   rc   rf   rg   rh   ri   ÚclassmethodrK   Ústaticmethodr|   Úpropertyrl   r}   rB   r�   r‚   r‡   rˆ   rŠ   rŒ   r�   r’   r$   r“   r•   rD   r–   r˜   rš   r›   rœ   r(   r(   r(   r)   r   *   sb   @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 )r:   a±  A point in a 2-dimensional Euclidean space.

    Parameters
    ==========

    coords
        A 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 r+   r(   rR   r(   r(   r)   rT   —  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.

        )rV   Úyr`   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   ro   )r   r   r   r>   )rC   ZangleÚptÚcrN   r‘   rV   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   ro   )r   Ú	translater>   ÚscalerV   r§   )rC   rV   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
        )r0   r0   zmatrix must be a 3x3 matrixr   r0   r   Nr   )Ú	is_MatrixÚshaper6   r>   r   r   Útolist)rC   ÚmatrixrV   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   rV   r§   )rC   rV   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)
        rQ   r`   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   rQ   r`   r(   r(   r)   rV     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   rQ   r`   r(   r(   r)   r§   "  s    z	Point2D.y)N)r   r   N)r   r   )r�   rž   rŸ   r    rj   r<   rT   r£   r¨   r«   r­   r²   r¬   r³   rV   r§   r(   r(   r(   r)   r:   \  s    2

 



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„ 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 )$r;   a>  A point in a 3-dimensional Euclidean space.

    Parameters
    ==========

    coords
        A 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)

    r0   Fr¤   c                O   s&   |sd|d< t ||Ž}tj| f|žŽ S )Nr0   r   r¥   r¦   r(   r(   r)   r<   a  s    
zPoint3D.__new__c                 C   s   || kS r+   r(   rR   r(   r(   r)   rT   g  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   rŠ   )rt   r(   r(   r)   Úare_collinearj  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~   r(   rm   r(   r(   r)   r*   ¥  s     z+Point3D.direction_cosine.<locals>.<genexpr>)Údirection_ratior   r   rV   r§   Úz)rC   Úpointr'   rI   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]
        )rV   r§   r¶   )rC   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)]

        r0   ro   )r,   r   r   r;   rˆ   r[   r(   r(   r)   rˆ   Á  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)

        )r;   r¬   r>   r­   rV   r§   r¶   )rC   rV   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 )zéReturn 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   Nr0   )r®   r¯   r6   r>   r   r;   r   r°   )rC   r±   rV   r§   r¶   r{   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)

        )r;   rV   r§   r¶   )rC   rV   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)
        rQ   r`   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   rQ   r`   r(   r(   r)   rV   7  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   rQ   r`   r(   r(   r)   r§   F  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   rQ   r`   r(   r(   r)   r¶   U  s    z	Point3D.z)r   r   r   N)r   r   r   )r�   rž   rŸ   r    rj   r<   rT   r¢   r´   r¸   rµ   rˆ   r­   r²   r¬   r£   r³   rV   r§   r¶   r(   r(   r(   r)   r;   1  s(   -
#&




r;   ),r    r7   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   r:   r;   r(   r(   r(   r)   Ú<module>   s6         8 V