
    Ed                     B   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e&          Z) G d de)          Z* G 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                      e Zd ZdZdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zed             Zed             Zed             Zed             Zd Zd Zd Zd)dZd Zd Zd Z ed             Z!d Z"ed             Z#ed              Z$d! Z%ed"             Z&ed#             Z'ed$             Z(d% Z)d& Z*ed'             Z+d(S )*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           	         |                     dt          j                  }|                     dd          }t          |          dk    r|d         n|}t	          |t
                    r8d}t          |          |                     dt          |                    k    r|S t          |          s<t          t          d	                    t          |                                        t          |          dk    r9|                     dd           r#t          j        f|                     d          z  }t          | }|                     dt          |                    }t          |          d	k     rt          t          d
                    t          |          |k    ryd	                    |t          |          |          }|dk    rnN|dk    rt          |          |dk    rt          j        |d	           nt          t          d                    t#          ||d                    rt          d          t#          d |D                       rt          d          t%          d |D                       st          d          |d |         t          j        f|t          |          z
  z  z   }|r7|                    d |                    t*                    D                       }t          |          d	k    rd|d<   t-          |i |S t          |          dk    rd|d<   t/          |i |S t1          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warn)
stacklevelzf
                        on_morph value should be 'error',
                        'warn' or 'ignore'.z&Nonzero coordinates cannot be removed.c              3   P   K   | ]!}|j         ot          |          j        d u V  "dS )FN)	is_numberr   is_zero.0as     4lib/python3.11/site-packages/sympy/geometry/point.py	<genexpr>z Point.__new__.<locals>.<genexpr>   s6      FF!q{5r!uu}5FFFFFF    z(Imaginary coordinates are not permitted.c              3   @   K   | ]}t          |t                    V  d S N)
isinstancer   r)   s     r,   r-   z Point.__new__.<locals>.<genexpr>   s,      771:a&&777777r.   z,Coordinates must be valid SymPy expressions.c           	      L    i | ]!}|t          t          |d                     "S )T)rational)r   r
   )r*   fs     r,   
<dictcomp>z!Point.__new__.<locals>.<dictcomp>   s?     &/ &/ &/ 8Ia$77788&/ &/ &/r.   T_nocheck   )getr	   r   lenr1   r   r   	TypeErrorr   formatr   r   Zeror   
ValueErrorwarningsr$   anyallxreplaceatomsr   Point2DPoint3Dr   __new__)clsargskwargsr   r   coordsr!   messages           r,   rE   zPoint.__new__m   s   ::j*;*DEE::j(33  IIN4a fe$$ 	 H6{{fjjF<<< 6"" 	DJ (?(.y/@/@(A(AC C D D D
 v;;! 	1

5$ 7 7 	1fYvzz%000FjjF,,v;;? 	(Z )& ' ' ( ( ( v;;# 	1()/FS)I)I 8# 	1W$ 1 )))V# 1g!44444  -/ "0 "0 1 1 1 vcdd| 	GEFFFFFvFFFFF 	IGHHH7777777 	LJKKK 	3V+< ==  	0__ &/ &/ ,,u--&/ &/ &/ 0 0F
 v;;! 	.!%F:F-f---[[A 	.!%F:F-f--- %c3F3333r.   c                 x    t          dgt          |           z            }t                               ||           S )z7Returns the distance between this point and the origin.r   )r   r9   distance)selforigins     r,   __abs__zPoint.__abs__   s/    s3t99}%%~~fd+++r.   c                    	 t                               | t          |d                    \  }}n0# t          $ r# t          d                    |                    w xY wd t          ||          D             }t          |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                 8    g | ]\  }}t          ||z             S  r   r*   r+   bs      r,   
<listcomp>z!Point.__add__.<locals>.<listcomp>   s&    888da(1q5//888r.   )r   _normalize_dimensionr:   r   r;   zip)rM   othersorI   s        r,   __add__zPoint.__add__   s    >	]--dE%%4P4P4PQQDAqq 	] 	] 	] M T TUZ [ [\\\	] 98c!Qii888Ve,,,,s	   -0 -Ac                     || j         v S r0   rG   rM   items     r,   __contains__zPoint.__contains__   s    ty  r.   c                 j    t                    fd| j        D             }t          |d          S )z'Divide point's coordinates by a factor.c                 4    g | ]}t          |z            S rS   rT   )r*   xdivisors     r,   rW   z%Point.__truediv__.<locals>.<listcomp>   s%    999!(1W9%%999r.   FrQ   r   rG   r   )rM   rf   rI   s    ` r,   __truediv__zPoint.__truediv__   s>    '""9999ty999Ve,,,,r.   c                     t          |t                    r*t          | j                  t          |j                  k    rdS | j        |j        k    S )NF)r1   r   r9   rG   rM   rZ   s     r,   __eq__zPoint.__eq__   sD    %'' 	3ty>>S__+L 	5yEJ&&r.   c                     | j         |         S r0   r_   )rM   keys     r,   __getitem__zPoint.__getitem__   s    y~r.   c                 *    t          | j                  S r0   )hashrG   rM   s    r,   __hash__zPoint.__hash__   s    DIr.   c                 4    | j                                         S r0   )rG   __iter__rq   s    r,   rt   zPoint.__iter__   s    y!!###r.   c                 *    t          | j                  S r0   )r9   rG   rq   s    r,   __len__zPoint.__len__   s    49~~r.   c                 j    t                    fd| j        D             }t          |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                 4    g | ]}t          |z            S rS   rT   )r*   re   factors     r,   rW   z!Point.__mul__.<locals>.<listcomp>  s%    888(1V8$$888r.   FrQ   rg   )rM   ry   rI   s    ` r,   __mul__zPoint.__mul__   s>    6 8888di888Ve,,,,r.   c                 ,    |                      |          S )z)Multiply a factor by point's coordinates.)rz   )rM   ry   s     r,   __rmul__zPoint.__rmul__  s    ||F###r.   c                 F    d | j         D             }t          |d          S )zNegate the point.c                     g | ]}| S rS   rS   r*   re   s     r,   rW   z!Point.__neg__.<locals>.<listcomp>   s    (((1"(((r.   FrQ   )rG   r   )rM   rI   s     r,   __neg__zPoint.__neg__  s*    ((di(((Ve,,,,r.   c                      | d |D             z   S )zPSubtract two points, or subtract a factor from this point's
        coordinates.c                     g | ]}| S rS   rS   r   s     r,   rW   z!Point.__sub__.<locals>.<listcomp>&  s    )))ar)))r.   rS   rj   s     r,   __sub__zPoint.__sub__#  s     ))5)))))r.   c                 6   t          | dd                              d          t          d |D                       t          fd|D                       rt	          |          S d<                       dd          d<   f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              3   $   K   | ]}|j         V  d S r0   ambient_dimensionr*   is     r,   r-   z-Point._normalize_dimension.<locals>.<genexpr>3  s%      ::aa)::::::r.   c              3   .   K   | ]}|j         k    V  d S r0   r   )r*   r   r!   s     r,   r-   z-Point._normalize_dimension.<locals>.<genexpr>4  s+      ::aq"c)::::::r.   r   r$   c                 *    g | ]}t          |fi S rS   r   )r*   r   rH   s     r,   rW   z.Point._normalize_dimension.<locals>.<listcomp>8  s)    333qa""6""333r.   )getattrr8   maxr@   list)rF   pointsrH   r!   s     `@r,   rX   zPoint._normalize_dimension(  s     c/66jj$$ 	;::6:::::C::::6::::: 	 <<u#ZZ
F;;z3333F3333r.   c                      t          |           dk    rdS t          j        d | D              }|d         fd|dd         D             }t          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                 ,    g | ]}t          |          S rS   r   r   s     r,   rW   z%Point.affine_rank.<locals>.<listcomp>G  s    -E-E-E1eAhh-E-E-Er.   c                     g | ]}|z
  S rS   rS   )r*   r   rN   s     r,   rW   z%Point.affine_rank.<locals>.<listcomp>I  s    111!f*111r.   r   Nc                     g | ]	}|j         
S rS   r_   r   s     r,   rW   z%Point.affine_rank.<locals>.<listcomp>K  s    +++qAF+++r.   c                 j    | j         r&t          |                     d                    dk     n| j        S )Nr"   g-q=)r'   absnr(   )re   s    r,   <lambda>z#Point.affine_rank.<locals>.<lambda>M  s-    #$;=CAKK%AI r.   )
iszerofunc)r9   r   rX   r   rank)rG   r   mrN   s      @r,   affine_rankzPoint.affine_rank:  s     t99> 	2 +-E-E-E-E-EF1111fQRRj111++F+++,,vv $> $>v ? ? 	?r.   c                 >    t          | dt          |                     S )z$Number of components this point has.r   )r   r9   rq   s    r,   r   zPoint.ambient_dimensionP  s     t13t99===r.   c                     t          |          dk    rdS  | j        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                 ,    g | ]}t          |          S rS   r   r   s     r,   rW   z&Point.are_coplanar.<locals>.<listcomp>|  s    +E+E+EE!HH+E+E+Er.   r   r"   )r9   rX   r   r   r   r   r   )rF   r   s     r,   are_coplanarzPoint.are_coplanarU  sz    H v;;! 	4))+E+Ef+E+E+EF!9&!+ 	4d6ll## &)Q..r.   c           	         t          |t                    sE	 t          || j                  }n-# t          $ r  t	          dt          |          z            w xY wt          |t                    rYt                              | t          |                    \  }}t          t          d t          ||          D                        S t          |dd          }|t	          dt          |          z             ||           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              3   ,   K   | ]\  }}||z
  d z  V  dS r"   NrS   rU   s      r,   r-   z!Point.distance.<locals>.<genexpr>  s.      ??TQq1uqj??????r.   rL   Nz,distance between Point and %s is not defined)r1   r   r   r   r:   typerX   r   r   rY   r   )rM   rZ   r[   prL   s        r,   rL   zPoint.distance  s   N %00 	YYe)?@@@ Y Y Y IDQVKK WXXXYeU## 	B--dE%LLAADAq??SAYY???@AAA5*d33 	ZJTRW[[XYYYx~~s	   . *Ac                     t          |          st          |          }t          d t          | |          D              S )z.Return dot product of self with another Point.c              3   &   K   | ]\  }}||z  V  d S r0   rS   rU   s      r,   r-   zPoint.dot.<locals>.<genexpr>  s*      22TQQqS222222r.   )r   r   r   rY   )rM   r   s     r,   dotz	Point.dot  s=    1~~ 	aA22Sq\\22233r.   c                     t          |t                    r t          |           t          |          k    rdS t          d t	          | |          D                       S )z8Returns whether the coordinates of self and other agree.Fc              3   F   K   | ]\  }}|                     |          V  d S r0   )equalsrU   s      r,   r-   zPoint.equals.<locals>.<genexpr>  s0      <<41a188A;;<<<<<<r.   )r1   r   r9   r@   rY   rj   s     r,   r   zPoint.equals  sZ     %'' 	3t99E

+B 	5<<3tU+;+;<<<<<<r.      c                 d    t          |          f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                 .    g | ]} |j         dd iS )r   rS   )evalf)r*   re   dpsoptionss     r,   rW   z%Point._eval_evalf.<locals>.<listcomp>  s0    ???'!'++C+7++???r.   r   F)r   rG   r   )rM   precr   rI   r   s     ` @r,   _eval_evalfzPoint._eval_evalf  sD    8 $?????TY???f-u---r.   c                    t          |t                    st          |          }t          |t                    r8| |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)]

        )r1   r   r   rX   intersection)rM   rZ   p1p2s       r,   r   zPoint.intersection  s    < %00 	!%LLEeU## 	u} v//e<<FBTz bBh vI!!$'''r.   c                     | f|z   }t          j        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                 ,    g | ]}t          |          S rS   r   r   s     r,   rW   z&Point.is_collinear.<locals>.<listcomp>/      -G-G-G1eAhh-G-G-Gr.   r   )r   rX   r   r   r   )rM   rG   r   s      r,   is_collinearzPoint.is_collinear  sR    B 4+-G-G-G-G-GHd6ll## &)Q..r.   c                 V   | f|z   }t          j        d |D              }t          t          |                    }t          j        | dk    sdS |d         fd|D             }t          d |D                       }|                                \  }}t                    |v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                 ,    g | ]}t          |          S rS   r   r   s     r,   rW   z&Point.is_concyclic.<locals>.<listcomp>Z  r   r.   r"   Fr   c                     g | ]}|z
  S rS   rS   )r*   r   rN   s     r,   rW   z&Point.is_concyclic.<locals>.<listcomp>_  s    ---!f*---r.   c                 Z    g | ](}t          |          |                    |          gz   )S rS   )r   r   r   s     r,   rW   z&Point.is_concyclic.<locals>.<listcomp>e  s/    ;;;qd1ggq
*;;;r.   T)r   rX   r   r   r   r   rrefr9   )rM   rG   r   matr   pivotsrN   s         @r,   is_concycliczPoint.is_concyclic3  s    L 4+-G-G-G-G-GHd6ll## &)Q. 	5----f--- ;;F;;;<<xxzzfv;;f$ 	4ur.   c                     | j         }|dS | S )zrTrue if any coordinate is nonzero, False if every coordinate is zero,
        and None if it cannot be determined.N)r(   )rM   r(   s     r,   
is_nonzerozPoint.is_nonzerok  s      , 	4{r.   c                    t                               | t          |                    \  }}|j        dk    rW|j        |j        c\  }}\  }}||z  ||z  z
                      d          }|"t          t          d|d|                    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   NzCannot determine if z- is a scalar multiple of
                    )	r   rX   r   rG   r   r   r   r   r   )
rM   r   r[   r\   x1y1x2y2rvr   s
             r,   is_scalar_multiplezPoint.is_scalar_multiplet  s     ))$a991!# 	%!"HRhr2R%"R%-''**B %!**QQ##$ #$ % % % AFAF#$$vvxx!|r.   c                     d | j         D             }t          |          rdS t          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                     g | ]	}|j         
S rS   )r   r   s     r,   rW   z!Point.is_zero.<locals>.<listcomp>  s    333A1<333r.   Fc              3      K   | ]}|d u V  	d S r0   rS   r   s     r,   r-   z Point.is_zero.<locals>.<genexpr>  s&      **QqDy******r.   NT)rG   r?   )rM   nonzeros     r,   r(   zPoint.is_zero  sU     43333w<< 	5**'***** 	4tr.   c                     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   r<   rq   s    r,   lengthzPoint.length  s     vr.   c                     t                               | t          |                    \  }}t          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                 R    g | ]$\  }}t          ||z   t          j        z            %S rS   )r   r   HalfrU   s      r,   rW   z"Point.midpoint.<locals>.<listcomp>  s.    EEE41ahAqv~..EEEr.   )r   rX   rY   rM   r   r[   s      r,   midpointzPoint.midpoint  sH    6 ))$a991EE3q!99EEEFFFr.   c                 F    t          dgt          |           z  d          S )zOA point of all zeros of the same ambient dimension
        as the current pointr   FrQ   )r   r9   rq   s    r,   rN   zPoint.origin  s#     aST]U3333r.   c                     | j         }| d         j        rt          dg|dz
  dgz  z             S | d         j        rt          ddg|dz
  dgz  z             S t          | d          | d         g|dz
  dgz  z             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   )rM   r!   s     r,   orthogonal_directionzPoint.orthogonal_direction  s      $7? 	.!a!},---7? 	0!A#'A3./// tAwhQ(C!GaS=8999r.   c                     t                               t          |           t          |                    \  } }|j        rt          d          ||                     |          |                    |          z  z  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   rX   r(   r=   r   )r+   rV   s     r,   projectzPoint.project  sh    D ))%((E!HH==19 	CABBB!%%((QUU1XX%&&r.   c                     t                               | t          |                    \  }}t          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              3   @   K   | ]\  }}t          ||z
            V  d S r0   r   rU   s      r,   r-   z)Point.taxicab_distance.<locals>.<genexpr>%  s0      66DAqSQZZ666666r.   )r   rX   r   rY   r   s      r,   taxicab_distancezPoint.taxicab_distance  sE    < ))$a99166C1II66677r.   c                     t                               | t          |                    \  }}| j        r|j        rt          d          t	          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              3      K   | ]9\  }}t          ||z
            t          |          t          |          z   z  V  :d S r0   r   rU   s      r,   r-   z*Point.canberra_distance.<locals>.<genexpr>S  sE      JJ1c!a%jj#a&&3q66/2JJJJJJr.   )r   rX   r(   r=   r   rY   r   s      r,   canberra_distancezPoint.canberra_distance'  sj    R ))$a991< 	CAI 	CABBBJJAq		JJJKKr.   c                 &    | t          |           z  S )zdReturn the Point that is in the same direction as `self`
        and a distance of 1 from the originr   rq   s    r,   unitz
Point.unitU  s     c$iir.   N)r   ),__name__
__module____qualname____doc__is_PointrE   rO   r]   rb   rh   rk   rn   rr   rt   rv   rz   r|   r   r   classmethodrX   staticmethodr   propertyr   r   rL   r   r   r   r   r   r   r   r   r(   r   r   rN   r   r   r   r   r   rS   r.   r,   r   r   *   s       > >@ HF4 F4 F4P, , ,
%- %- %-N! ! !- - -' ' '
    $ $ $  - - ->$ $ $- - -
* * *
 4 4 [4" ? ? \?* > > X> +/ +/ [+/Z2 2 2h4 4 4= = =. . . .@'( '( '(R$/ $/ $/L6 6 6p   X  &   X   XG G G< 4 4 X4
 : : X:2 $' $' \$'L8 8 8B,L ,L ,L\     X     r.   r   c                       e Zd ZdZdZdddZd Zed             Zdd	Z	ddZ
d ZddZed             Zed             Zed             ZdS )rC   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r6   c                L    |sd|d<   t          |i |}t          j        | g|R  S )Nr"   r!   r   r   rE   rF   r6   rG   rH   s       r,   rE   zPoint2D.__new__  >     	*F5M$)&))D%c1D1111r.   c                     || k    S r0   rS   r`   s     r,   rb   zPoint2D.__contains__      t|r.   c                 6    | j         | j        | j         | j        fS )zwReturn a tuple (xmin, ymin, xmax, ymax) representing the bounding
        rectangle for the geometric figure.

        )re   yrq   s    r,   boundszPoint2D.bounds  s     //r.   Nc                     t          |          }t          |          }| }|t          |d          }||z  }|j        \  }}t          ||z  ||z  z
  ||z  ||z  z             }|||z  }|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   rG   )rM   angleptcr[   r   re   r   s           r,   rotatezPoint2D.rotate  s    & JJJJ 	rq!!!B"HBw11Q319acAaCi(( 	"HB	r.   r   c                     |rBt          |d          }  | j        | j                             ||          j        |j         S t          | j        |z  | j        |z            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   	translaterG   scalere   r   )rM   re   r   r   s       r,   r  zPoint2D.scale  sj    ,  	Orq!!!BD>4>RC:.44Q::DbgNNTVAXtvax(((r.   c           	          |j         r|j        dk    st          d          | j        \  }}t	          t          dd||dg          |z                                  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
        )r7   r7   zmatrix must be a 3x3 matrixr   r7   r   Nr"   )	is_Matrixshaper=   rG   r   r   tolist)rM   matrixre   r   s       r,   	transformzPoint2D.transform  ss       	<V\V%; 	<:;;;y1vaQ1I..v5==??B2A2FGGr.   r   c                 B    t          | j        |z   | j        |z             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   re   r   )rM   re   r   s      r,   r  zPoint2D.translate  s     * TVaZ!,,,r.   c                     | j         S )z
        Returns the two coordinates of the Point.

        Examples
        ========

        >>> from sympy import Point2D
        >>> p = Point2D(0, 1)
        >>> p.coordinates
        (0, 1)
        r_   rq   s    r,   coordinateszPoint2D.coordinates       yr.   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   r_   rq   s    r,   re   z	Point2D.x       y|r.   c                     | 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_   rq   s    r,   r   z	Point2D.y!  r  r.   r0   )r   r   N)r   r   )r   r   r   r   r   rE   rb   r   r   r  r  r
  r  r  re   r   rS   r.   r,   rC   rC   \  s       / /b %* 2 2 2 2 2   0 0 X0   @) ) ) )6H H H- - - -.   X   X   X  r.   rC   c                       e Zd ZdZdZdddZd Zed             Zd Z	d	 Z
d
 ZddZd ZddZed             Zed             Zed             Zed             ZdS )rD   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)

    r7   Fr   c                L    |sd|d<   t          |i |}t          j        | g|R  S )Nr7   r!   r   r   s       r,   rE   zPoint3D.__new___  r   r.   c                     || k    S r0   rS   r`   s     r,   rb   zPoint3D.__contains__e  r   r.   c                      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   )r   s    r,   are_collinearzPoint3D.are_collinearh  s    D !6**r.   c                     |                      |          }t          t          d |D                        }|j        | j        z
  |z  |j        | j        z
  |z  |j        | j        z
  |z  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              3       K   | ]	}|d z  V  
dS r   rS   r   s     r,   r-   z+Point3D.direction_cosine.<locals>.<genexpr>  s&      ''q!t''''''r.   )direction_ratior   r   re   r   z)rM   pointr+   rV   s       r,   direction_cosinezPoint3D.direction_cosine  st    ,   ''''Q'''())46!Q&$&(8A'=46!Q&( 	(r.   c                 Z    |j         | j         z
  |j        | j        z
  |j        | j        z
  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]
        )re   r   r  )rM   r  s     r,   r  zPoint3D.direction_ratio  s,    , 46!EGdf$4uw7GIIr.   c                     t          |t                    st          |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)]

        r7   r   )r1   r   r   rD   r   rj   s     r,   r   zPoint3D.intersection  sf    < %00 	(%Q'''EeW%% 	u} vI!!$'''r.   r   Nc                     |rAt          |          }  | j        | j                             |||          j        |j         S t          | j        |z  | j        |z  | j        |z            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)

        )rD   r  rG   r  re   r   r  )rM   re   r   r  r   s        r,   r  zPoint3D.scale  sm    ,  	RBG>4>RC:.44Q1==GQQtvax46!8444r.   c           
          |j         r|j        dk    st          d          | j        \  }}}t	          |          }t          t          dd|||dg          |z                                  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   Nr7   )r  r  r=   rG   r   rD   r   r  )rM   r	  re   r   r  r   s         r,   r
  zPoint3D.transform   s       	<V\V%; 	<:;;;)1af1q!Ql33A5==??B2A2FGGr.   r   c                 T    t          | j        |z   | j        |z   | j        |z             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)

        )rD   re   r   r  )rM   re   r   r  s       r,   r  zPoint3D.translate  s(    * tvz46A:tvz:::r.   c                     | 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_   rq   s    r,   r  zPoint3D.coordinates&  r  r.   c                     | 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_   rq   s    r,   re   z	Point3D.x5  r  r.   c                     | 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_   rq   s    r,   r   z	Point3D.yD  r  r.   c                     | 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_   rq   s    r,   r  z	Point3D.zS  r  r.   )r   r   r   N)r   r   r   )r   r   r   r   r   rE   rb   r   r  r  r  r   r  r
  r  r   r  re   r   r  rS   r.   r,   rD   rD   0  sE       * *X %* 2 2 2 2 2   !+ !+ \!+F( ( (6J J J0$( $( $(L5 5 5 56H H H; ; ; ;.   X   X   X   X  r.   rD   ),r   r>   
sympy.corer   r   r   sympy.core.addr   sympy.core.containersr   sympy.core.numbersr   sympy.core.parametersr	   sympy.simplifyr
   r   sympy.geometry.exceptionsr   (sympy.functions.elementary.miscellaneousr   $sympy.functions.elementary.complexesr   (sympy.functions.elementary.trigonometricr   r   sympy.matricesr   sympy.matrices.expressionsr   sympy.utilities.iterablesr   r   sympy.utilities.miscr   r   r   entityr   mpmath.libmp.libmpfr   r   rC   rD   rS   r.   r,   <module>r7     s   &  ' ' ' ' ' ' ' ' ' '       ' ' ' ' ' ' $ $ $ $ $ $ 3 3 3 3 3 3 . . . . . . . . 3 3 3 3 3 3 9 9 9 9 9 9 3 3 3 3 3 3 = = = = = = = = ! ! ! ! ! ! 0 0 0 0 0 0 7 7 7 7 7 7 7 7 C C C C C C C C C C " " " " " " + + + + + +o  o  o  o  o N o  o  o dR R R R Re R R Rhp p p p pe p p p p pr.   