o
    8VaF                     @   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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 ddlmZ ddlmZ ddlmZ ddlmZmZ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 )aS  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.geometry.point 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)is_sequence)Tuple)	nsimplifysimplify)GeometryError)sqrt)im)Matrix)Float)global_parameters)Add)uniq)
filldedent	func_nameUndecidable   )GeometryEntityc                   @   sf  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dLd.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+eZ,d-S )M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.geometry 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|s=ttd	t
|t|dkrR| dd rRtjf| d }t| }| dt|}t|d	k rjttd
t||krd	|t||}|dkr~n|dkrt||dkrt| nttdt||d  rtdtdd |D rtdtdd |D std|d | tjf|t|   }|r|dd |tD }t|d	krd|d< t|i |S t|dkrd|d< t|i |S tj| g|R  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warnzf
                        on_morph value should be 'error',
                        'warn' or 'ignore'.z&Nonzero coordinates cannot be removed.c                 s   s    | ]
}|j o
t|V  qd S N)	is_numberr   .0a r#   6/usr/lib/python3/dist-packages/sympy/geometry/point.py	<genexpr>       z Point.__new__.<locals>.<genexpr>z(Imaginary coordinates are not permitted.c                 s   s    | ]}t |tV  qd S r   )
isinstancer   r    r#   r#   r$   r%          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$   r8   j   s\   

 
zPoint.__new__c                 C   s   t dgt|  }t || S )z7Returns the distance between this point and the origin.r   )r   r.   distance)selforiginr#   r#   r$   __abs__   s   zPoint.__abs__c                 C   sZ   zt | t |dd\}}W n ty   td|w dd t||D }t |ddS )aG  Add other to self by incrementing self's coordinates by
        those of other.

        Notes
        =====

        >>> from sympy.geometry.point 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>       z!Point.__add__.<locals>.<listcomp>)r   _normalize_dimensionr/   r	   r0   zip)r?   othersor<   r#   r#   r$   __add__   s   zPoint.__add__c                 C   s
   || j v S r   r:   r?   itemr#   r#   r$   __contains__      
zPoint.__contains__c                    (   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#   rC   r!   xdivisorr#   r$   rF          z%Point.__truediv__.<locals>.<listcomp>FrB   r   r:   r   )r?   rW   r<   r#   rV   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   r.   r:   r?   rJ   r#   r#   r$   __eq__   s   zPoint.__eq__c                 C   s
   | j | S r   rN   )r?   keyr#   r#   r$   __getitem__   rR   zPoint.__getitem__c                 C   
   t | jS r   )hashr:   r?   r#   r#   r$   __hash__   rR   zPoint.__hash__c                 C   s
   | j  S r   )r:   __iter__ra   r#   r#   r$   rc      rR   zPoint.__iter__c                 C   r_   r   )r.   r:   ra   r#   r#   r$   __len__   rR   zPoint.__len__c                    rS   )a{  Multiply point's coordinates by a factor.

        Notes
        =====

        >>> from sympy.geometry.point 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#   rC   rT   factorr#   r$   rF     rX   z!Point.__mul__.<locals>.<listcomp>FrB   rY   )r?   rf   r<   r#   re   r$   __mul__   s   zPoint.__mul__c                 C   s
   |  |S )z)Multiply a factor by point's coordinates.)rg   )r?   rf   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      g | ]}| qS r#   r#   rT   r#   r#   r$   rF         z!Point.__neg__.<locals>.<listcomp>FrB   r:   r   )r?   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   ri   r#   r#   rT   r#   r#   r$   rF   #  rj   z!Point.__sub__.<locals>.<listcomp>r#   r[   r#   r#   r$   __sub__   s   zPoint.__sub__c                    sz   t | dd d   du rtdd |D  t fdd|D r(t|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%   0  s    z-Point._normalize_dimension.<locals>.<genexpr>c                 3   s    | ]}|j  kV  qd S r   ro   rq   r   r#   r$   r%   1  r(   r   r   c                    s   g | ]
}t |fi  qS r#   r   rq   )r;   r#   r$   rF   5  rG   z.Point._normalize_dimension.<locals>.<listcomp>)getattrr-   maxr5   list)r9   pointsr;   r#   )r   r;   r$   rH   %  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      g | ]}t |qS r#   rt   rq   r#   r#   r$   rF   D      z%Point.affine_rank.<locals>.<listcomp>c                       g | ]}|  qS r#   r#   rq   r@   r#   r$   rF   F  r{   r   Nc                 S      g | ]}|j qS r#   rN   rq   r#   r#   r$   rF   H  rj   c                 S   s   | j rt| ddk S | jS )Nr   g-q=)r   absnis_zero)rU   r#   r#   r$   <lambda>J  s   z#Point.affine_rank.<locals>.<lambda>)Z
iszerofunc)r.   r   rH   r   rank)r:   rx   mr#   r}   r$   affine_rank7  s   	zPoint.affine_rankc                 C   s   t | dt| S )z$Number of components this point has.rn   )ru   r.   ra   r#   r#   r$   rp   M  s   zPoint.ambient_dimensionc                 G   sP   t |dkrdS | jdd |D  }|d jdkrd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   rz   r#   rt   rq   r#   r#   r$   rF   y  r{   z&Point.are_coplanar.<locals>.<listcomp>r   r   )r.   rH   rp   rw   r   r   r   )r9   rx   r#   r#   r$   are_coplanarR  s   $zPoint.are_coplanarc                 C   s   t |tsz	t|| jd}W n ty   tdt| w t |tr;t| t|\}}ttdd t	||D  S t
|dd}|du rMtdt| || S )a  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.geometry 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)

        rs   z'not recognized as a GeometricEntity: %sc                 s   s     | ]\}}|| d  V  qdS r   Nr#   rD   r#   r#   r$   r%         z!Point.distance.<locals>.<genexpr>r>   Nz,distance between Point and %s is not defined)r'   r   r   rp   r/   typerH   r
   r   rI   ru   )r?   rJ   rK   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 r   r#   rD   r#   r#   r$   r%     s    zPoint.dot.<locals>.<genexpr>)r   r   r   rI   )r?   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   )equalsrD   r#   r#   r$   r%     r&   zPoint.equals.<locals>.<genexpr>)r'   r   r.   r5   rI   r[   r#   r#   r$   r     s   zPoint.equalsNc                    s$    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i  qS r#   )evalfrT   optionsprecr#   r$   rF     s    zPoint.evalf.<locals>.<listcomp>r   Frk   )r?   r   r   r<   r#   r   r$   r     s   zPoint.evalfc                 C   s^   t |ts	t|}t |tr*| |kr| gS t| |\}}|| kr(||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 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   rH   intersection)r?   rJ   Z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   rz   r#   rt   rq   r#   r#   r$   rF   +  r{   z&Point.is_collinear.<locals>.<listcomp>r   )r   rH   rw   r   r   )r?   r:   rx   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 |vrBd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   rz   r#   rt   rq   r#   r#   r$   rF   V  r{   z&Point.is_concyclic.<locals>.<listcomp>r   Fr   c                    r|   r#   r#   )r!   r   r}   r#   r$   rF   [  r{   c                 S   s    g | ]}t |||g qS r#   )rw   r   rq   r#   r#   r$   rF   a  s     T)r   rH   rw   r   r   r   rrefr.   )r?   r:   rx   Zmatr   Zpivotsr#   r}   r$   is_concyclic/  s   
&zPoint.is_concyclicc                 C   s   | j }|du 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   )r?   r   r#   r#   r$   
is_nonzerog  s   zPoint.is_nonzeroc           
      C   s   t | t |\}}|jdkr3|j|j\}}\}}|| ||  d}|du r3t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   NzDcan't determine if %s is a scalar multiple of
                    %s)	r   rH   rp   r:   r   r   r   r   r   )
r?   r   rK   rL   Zx1Zy1Zx2Zy2rvr   r#   r#   r$   is_scalar_multiplep  s   
zPoint.is_scalar_multiplec                 C   s6   dd | j D }t|rdS tdd |D rd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   r~   r#   )r   rT   r#   r#   r$   rF     rj   z!Point.is_zero.<locals>.<listcomp>Fc                 s   s    | ]}|d u V  qd S r   r#   rT   r#   r#   r$   r%         z Point.is_zero.<locals>.<genexpr>NT)r:   r4   )r?   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   r1   ra   r#   r#   r$   length     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.geometry 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HalfrD   r#   r#   r$   rF     s   " z"Point.midpoint.<locals>.<listcomp>)r   rH   rI   r?   r   rK   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   FrB   )r   r.   ra   r#   r#   r$   r@     s   zPoint.originc                 C   sp   | j }| d jrtdg|d dg  S | d jr&tddg|d dg  S t| d  | d g|d dg  S )a~  Returns a non-zero point that is orthogonal to the
        line containing `self` and the origin.

        Examples
        ========

        >>> from sympy.geometry 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   )rp   r   r   )r?   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.geometry 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   rH   r   r2   r   )r"   rE   r#   r#   r$   project  s   "zPoint.projectc                 C   s,   t | t |\}}tdd t||D  S )a;  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.geometry import Point
        >>> p1, p2 = Point(1, 1), Point(4, 5)
        >>> p1.taxicab_distance(p2)
        7

        c                 s   s     | ]\}}t || V  qd S r   r   rD   r#   r#   r$   r%   !  r   z)Point.taxicab_distance.<locals>.<genexpr>)r   rH   r   rI   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 )aF  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.geometry 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   s0    | ]\}}t || t |t |  V  qd S r   r   rD   r#   r#   r$   r%   O  s   . z*Point.canberra_distance.<locals>.<genexpr>)r   rH   r   r2   r   rI   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   ra   r#   r#   r$   unitQ  s   z
Point.unitr   )-__name__
__module____qualname____doc__Zis_Pointr8   rA   rM   rQ   rZ   r\   r^   rb   rc   rd   rg   rh   rl   rm   classmethodrH   staticmethodr   propertyrp   r   r>   r   r   r   r   r   r   r   r   r   r   r   r@   r   r   r   r   r   r   r#   r#   r#   r$   r   '   sf    @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 )r6   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.geometry 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d|d< t |i |}tj| g|R  S )Nr   r   r   r   r8   r9   r+   r:   r;   r#   r#   r$   r8        zPoint2D.__new__c                 C      || kS r   r#   rO   r#   r#   r$   rQ        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.

        )rU   yra   r#   r#   r$   bounds  s   zPoint2D.boundsNc                 C   s   ddl m}m}m} ||}||}| }|dur"||dd}||8 }|j\}	}
|||	 ||
  ||	 ||
  }|dur@||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)

        r   )cossinr   Nr   rs   )Zsympyr   r   r   r:   )r?   Zangleptr   r   r   crK   r   rU   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   rs   )r   	translater:   scalerU   r   )r?   rU   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shaper2   r:   r   r   tolist)r?   matrixrU   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   rU   r   )r?   rU   r   r#   r#   r$   r     s   zPoint2D.translatec                 C      | j S )z
        Returns the two coordinates of the Point.

        Examples
        ========

        >>> from sympy import Point2D
        >>> p = Point2D(0, 1)
        >>> p.coordinates
        (0, 1)
        rN   ra   r#   r#   r$   coordinates  r   zPoint2D.coordinatesc                 C   
   | j d S )z
        Returns the X coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point2D
        >>> p = Point2D(0, 1)
        >>> p.x
        0
        r   rN   ra   r#   r#   r$   rU        
z	Point2D.xc                 C   r   )z
        Returns the Y coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point2D
        >>> p = Point2D(0, 1)
        >>> p.y
        1
        r   rN   ra   r#   r#   r$   r      r   z	Point2D.yr   )r   r   N)r   r   )r   r   r   r   rn   r8   rQ   r   r   r   r   r   r   r   rU   r   r#   r#   r#   r$   r6   Y  s"    1


"


r6   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 )$r7   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,   Fr   c                O   r   )Nr,   r   r   r   r#   r#   r$   r8   ^  r   zPoint3D.__new__c                 C   r   r   r#   rO   r#   r#   r$   rQ   d  r   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   )rx   r#   r#   r$   are_collinearg  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#   rq   r#   r#   r$   r%     r   z+Point3D.direction_cosine.<locals>.<genexpr>)direction_ratior
   r   rU   r   z)r?   pointr"   rE   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]
        )rU   r   r   )r?   r   r#   r#   r$   r     s   "zPoint3D.direction_ratioc                 C   s<   t |tst|dd}t |tr| |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,   rs   )r'   r   r   r7   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)

        )r7   r   r:   r   rU   r   r   )r?   rU   r   r   r   r#   r#   r$   r     s    zPoint3D.scalec                 C   sd   |j r|jdkstdddlm} | j\}}}||}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   )	Transposer   r   Nr,   )	r   r   r2   Zsympy.matrices.expressionsr   r:   r7   r   r   )r?   r   r   rU   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)

        )r7   rU   r   r   )r?   rU   r   r   r#   r#   r$   r     s   zPoint3D.translatec                 C   r   )z
        Returns the three coordinates of the Point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p = Point3D(0, 1, 2)
        >>> p.coordinates
        (0, 1, 2)
        rN   ra   r#   r#   r$   r   &  r   zPoint3D.coordinatesc                 C   r   )z
        Returns the X coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p = Point3D(0, 1, 3)
        >>> p.x
        0
        r   rN   ra   r#   r#   r$   rU   5  r   z	Point3D.xc                 C   r   )z
        Returns the Y coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p = Point3D(0, 1, 2)
        >>> p.y
        1
        r   rN   ra   r#   r#   r$   r   D  r   z	Point3D.yc                 C   r   )z
        Returns the Z coordinate of the Point.

        Examples
        ========

        >>> from sympy import Point3D
        >>> p = Point3D(0, 1, 1)
        >>> p.z
        1
        r   rN   ra   r#   r#   r$   r   S  r   z	Point3D.z)r   r   r   N)r   r   r   )r   r   r   r   rn   r8   rQ   r   r   r   r   r   r   r   r   r   r   rU   r   r   r#   r#   r#   r$   r7   /  s*    ,
#
&



r7   )&r   r3   Z
sympy.corer   r   r   Zsympy.core.compatibilityr   Zsympy.core.containersr   Zsympy.simplifyr   r   Zsympy.geometry.exceptionsr	   Z(sympy.functions.elementary.miscellaneousr
   Z$sympy.functions.elementary.complexesr   Zsympy.matricesr   Zsympy.core.numbersr   Zsympy.core.parametersr   Zsympy.core.addr   Zsympy.utilities.iterablesr   Zsympy.utilities.miscr   r   r   Zentityr   r   r6   r7   r#   r#   r#   r$   <module>   s4          8 W