o
    oh,                     @   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|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j|d	d 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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 u V  qdS )FN)	is_numberr   is_zero.0a r(   h/var/www/html/construction_image-detection-poc/venv/lib/python3.10/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*          z,Coordinates must be valid SymPy expressions.c                 S   s   i | ]}|t t|d dqS )T)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allxreplace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   r4   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 )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>       z!Point.__add__.<locals>.<listcomp>)r   _normalize_dimensionr5   r   r6   zip)rG   othersorD   r(   r(   r)   __add__   s   zPoint.__add__c                 C   s
   || j v S r+   rB   rG   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(   rK   r&   xdivisorr(   r)   rN          z%Point.__truediv__.<locals>.<listcomp>FrJ   r   rB   r   )rG   r_   rD   r(   r^   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   r4   rB   rG   rR   r(   r(   r)   __eq__   s   zPoint.__eq__c                 C   s
   | j | S r+   rV   )rG   keyr(   r(   r)   __getitem__   rZ   zPoint.__getitem__c                 C   
   t | jS r+   )hashrB   rG   r(   r(   r)   __hash__   rZ   zPoint.__hash__c                 C   s
   | j  S r+   )rB   __iter__ri   r(   r(   r)   rk      rZ   zPoint.__iter__c                 C   rg   r+   )r4   rB   ri   r(   r(   r)   __len__   rZ   zPoint.__len__c                    r[   )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(   rK   r\   factorr(   r)   rN     r`   z!Point.__mul__.<locals>.<listcomp>FrJ   ra   )rG   rn   rD   r(   rm   r)   __mul__   s   zPoint.__mul__c                 C   s
   |  |S )z)Multiply a factor by point's coordinates.)ro   )rG   rn   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(   r\   r(   r(   r)   rN          z!Point.__neg__.<locals>.<listcomp>FrJ   )rB   r   )rG   rD   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   rq   r(   r(   r\   r(   r(   r)   rN   &  rr   z!Point.__sub__.<locals>.<listcomp>r(   rc   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*   3  s    z-Point._normalize_dimension.<locals>.<genexpr>c                 3   s    | ]}|j  kV  qd S r+   rv   rx   r   r(   r)   r*   4  r-   r   r!   c                    s   g | ]
}t |fi  qS r(   r   rx   )rC   r(   r)   rN   8  rO   z.Point._normalize_dimension.<locals>.<listcomp>)getattrr3   maxr;   list)rA   pointsrC   r(   )r   rC   r)   rP   (  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(   r{   rx   r(   r(   r)   rN   G      z%Point.affine_rank.<locals>.<listcomp>c                       g | ]}|  qS r(   r(   rx   rH   r(   r)   rN   I  r   r   Nc                 S      g | ]}|j qS r(   rV   rx   r(   r(   r)   rN   K  rr   c                 S   s   | j rt| ddk S | jS )Nr   g-q=)r#   absnr$   )r]   r(   r(   r)   <lambda>M  s   z#Point.affine_rank.<locals>.<lambda>)
iszerofunc)r4   r   rP   r   rank)rB   r   mr(   r   r)   affine_rank:  s   	zPoint.affine_rankc                 C   s   t | dt| S )z$Number of components this point has.ru   )r|   r4   ri   r(   r(   r)   rw   P  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   r   r(   r{   rx   r(   r(   r)   rN   |  r   z&Point.are_coplanar.<locals>.<listcomp>r   r   )r4   rP   rw   r~   r   r   r   )rA   r   r(   r(   r)   are_coplanarU  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 )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)

        rz   z'not recognized as a GeometricEntity: %sc                 s   s     | ]\}}|| d  V  qdS r   Nr(   rL   r(   r(   r)   r*         z!Point.distance.<locals>.<genexpr>rF   Nz,distance between Point and %s is not defined)r,   r   r   rw   r5   typerP   r   r   rQ   r|   )rG   rR   rS   prF   r(   r(   r)   rF     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(   rL   r(   r(   r)   r*     s    zPoint.dot.<locals>.<genexpr>)r   r   r   rQ   )rG   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+   )equalsrL   r(   r(   r)   r*     s    zPoint.equals.<locals>.<genexpr>)r,   r   r4   r;   rQ   rc   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 dd  iqS )r   r(   )evalfr\   dpsoptionsr(   r)   rN          z%Point._eval_evalf.<locals>.<listcomp>r   F)r   rB   r   )rG   precr   rD   r(   r   r)   _eval_evalf  s   zPoint._eval_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   rP   intersection)rG   rR   p1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   r   r(   r{   rx   r(   r(   r)   rN   /  r   z&Point.is_collinear.<locals>.<listcomp>r   )r   rP   r~   r   r   )rG   rB   r   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   r   r(   r{   rx   r(   r(   r)   rN   Z  r   z&Point.is_concyclic.<locals>.<listcomp>r   Fr   c                    r   r(   r(   )r&   r   r   r(   r)   rN   _  r   c                 S   s    g | ]}t |||g qS r(   )r~   r   rx   r(   r(   r)   rN   e  r   T)r   rP   r~   r   r   r   rrefr4   )rG   rB   r   matr   pivotsr(   r   r)   is_concyclic3  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$   )rG   r$   r(   r(   r)   
is_nonzerok  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   NzECannot determine if %s is a scalar multiple of
                    %s)	r   rP   rw   rB   r   r   r   r   r   )
rG   r   rS   rT   x1y1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 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   r\   r(   r(   r)   rN     rr   z!Point.is_zero.<locals>.<listcomp>Fc                 s   s    | ]}|d u V  qd S r+   r(   r\   r(   r(   r)   r*         z Point.is_zero.<locals>.<genexpr>NT)rB   r:   )rG   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   r7   ri   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 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   HalfrL   r(   r(   r)   rN     s   " z"Point.midpoint.<locals>.<listcomp>)r   rP   rQ   rG   r   rS   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   FrJ   )r   r4   ri   r(   r(   r)   rH     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 )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   )rw   r$   r   )rG   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   rP   r$   r8   r   )r'   rM   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+   r   rL   r(   r(   r)   r*   %  r   z)Point.taxicab_distance.<locals>.<genexpr>)r   rP   r   rQ   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   s0    | ]\}}t || t |t |  V  qd S r+   r   rL   r(   r(   r)   r*   S  s   . z*Point.canberra_distance.<locals>.<genexpr>)r   rP   r$   r8   r   rQ   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   ri   r(   r(   r)   unitU  s   z
Point.unitN)r   ),__name__
__module____qualname____doc__is_Pointr@   rI   rU   rY   rb   rd   rf   rj   rk   rl   ro   rp   rs   rt   classmethodrP   staticmethodr   propertyrw   r   rF   r   r   r   r   r   r   r   r   r$   r   r   rH   r   r   r   r   r   r(   r(   r(   r)   r   *   sd    @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r1   c                O   ,   |sd|d< t |i |}tj| g|R  S )Nr   r   r   r   r@   rA   r1   rB   rC   r(   r(   r)   r@        zPoint2D.__new__c                 C      || kS r+   r(   rW   r(   r(   r)   rY        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.

        )r]   yri   r(   r(   r)   bounds  s   zPoint2D.boundsNc                 C   sp   t |}t|}| }|durt|dd}||8 }|j\}}t|| ||  || ||  }|dur6||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   rz   )r   r   r   rB   )rG   angleptcrS   r   r]   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   rz   )r   	translaterB   scaler]   r   )rG   r]   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
        )r2   r2   zmatrix must be a 3x3 matrixr   r2   r   Nr   )	is_Matrixshaper8   rB   r   r   tolist)rG   matrixr]   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   r]   r   )rG   r]   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)
        rV   ri   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   rV   ri   r(   r(   r)   r]        
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   rV   ri   r(   r(   r)   r   "  r   z	Point2D.yr+   )r   r   N)r   r   )r   r   r   r   ru   r@   rY   r   r   r   r   r   r   r   r]   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)

    r2   Fr   c                O   r   )Nr2   r   r   r   r(   r(   r)   r@   a  r   zPoint3D.__new__c                 C   r   r+   r(   rW   r(   r(   r)   rY   g  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   )r   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(   rx   r(   r(   r)   r*     r   z+Point3D.direction_cosine.<locals>.<genexpr>)direction_ratior   r   r]   r   z)rG   pointr'   rM   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]
        )r]   r   r   )rG   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)]

        r2   rz   )r,   r   r   r?   r   rc   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   rB   r   r]   r   r   )rG   r]   r   r   r   r(   r(   r)   r     s    zPoint3D.scalec                 C   sX   |j r|jdkstd| j\}}}t|}ttdd|||dg|  d dd  S )zReturn the point after applying the transformation described
        by the 4x4 Matrix, ``matrix``.

        See Also
        ========
        sympy.geometry.point.Point3D.scale
        sympy.geometry.point.Point3D.translate
        )   r   zmatrix must be a 4x4 matrixr   r   r   Nr2   )r   r   r8   rB   r   r?   r   r   )rG   r   r]   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?   r]   r   r   )rG   r]   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)
        rV   ri   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   rV   ri   r(   r(   r)   r]   7  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   rV   ri   r(   r(   r)   r   F  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   rV   ri   r(   r(   r)   r   U  r   z	Point3D.z)r   r   r   N)r   r   r   )r   r   r   r   ru   r@   rY   r   r   r   r   r   r   r   r   r   r   r]   r   r   r(   r(   r(   r)   r?   1  s*    -
#
&



r?   ),r   r9   
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   r>   r?   r(   r(   r(   r)   <module>   s8          8 V