
    wg:                       d 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 ddlmZ ddlm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mZmZ ddlmZm Z  ddl!m"Z" ddl#m$Z$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/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7 ddl8Z8 e9d      D  cg c]
  }  ed       c} \  Z:Z; G d de       Z< G d de<      Z= G d  d!e<      Z> G d" d#e<      Z? G d$ d%e<      Z@ G d& d'e@e=      ZA G d( d)e@e>      ZB G d* d+e@e?      ZC G d, d-e<      ZD G d. d/eDe=      ZE G d0 d1eDe>      ZF G d2 d3eDe?      ZGyc c} w )4zLine-like geometrical entities.

Contains
========
LinearEntity
Line
Ray
Segment
LinearEntity2D
Line2D
Ray2D
Segment2D
LinearEntity3D
Line3D
Ray3D
Segment3D

    )Tuple)N)Expr)RationalooFloat)Eq)S)ordered)_symbolDummyuniquely_named_symbol)sympify)	Piecewise)	_pi_coeffacostanatan2   )GeometryEntityGeometrySet)GeometryError)PointPoint3D)findintersection)And)Matrix)Intersectionsimplify)solve)linear_coeffs)Undecidable
filldedentN   
line_dummyc                       e Zd ZdZddZd Zd Zed        Zd Z	d Z
dd	Zed
        Zd Zed        Zd Zd Zd Zd Zed        Zed        Zed        Zd Zd Zd Zed        Zd ZddZd Zy)LinearEntityan  A base class for all linear entities (Line, Ray and Segment)
    in n-dimensional Euclidean space.

    Attributes
    ==========

    ambient_dimension
    direction
    length
    p1
    p2
    points

    Notes
    =====

    This is an abstract class and is not meant to be instantiated.

    See Also
    ========

    sympy.geometry.entity.GeometryEntity

    Nc                     t        j                  ||      \  }}||k(  rt        d| j                  z        t	        |      t	        |      k7  rt        d| j                  z        t        j                  | ||fi |S )N&%s.__new__ requires two unique Points.z2%s.__new__ requires two Points of equal dimension.)r   _normalize_dimension
ValueError__name__lenr   __new__clsp1p2kwargss       X/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/geometry/line.pyr0   zLinearEntity.__new__K   s    ++B3B8 83<<GI Ir7c"gDs||SU U %%c2r<V<<    c                 P    | j                  |      }||S t        d| d|d      )z}Return a definitive answer or else raise an error if it cannot
        be determined that other is on the boundaries of self.zCannot decide whether 'z' contains '')containsr$   )selfotherresults      r6   __contains__zLinearEntity.__contains__X   s4     u%M>BEJL Lr7   c                     | j                   |k(  ry|| j                   z
  }| j                  }|j                  |      dkD  ryy)a  Test whether the point `other` lies in the positive span of `self`.
        A point x is 'in front' of a point y if x.dot(y) >= 0.  Return
        -1 if `other` is behind `self.p1`, 0 if `other` is `self.p1` and
        and 1 if `other` is in front of `self.p1`.r   r   )r3   	directiondot)r;   r<   rel_posds       r6   
_span_testzLinearEntity._span_testc   s?    
 77e$''/NN55>Ar7   c                 ,    t        | j                        S )aC  A property method that returns the dimension of LinearEntity
        object.

        Parameters
        ==========

        p1 : LinearEntity

        Returns
        =======

        dimension : integer

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(1, 1)
        >>> l1 = Line(p1, p2)
        >>> l1.ambient_dimension
        2

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0, 0), Point(1, 1, 1)
        >>> l1 = Line(p1, p2)
        >>> l1.ambient_dimension
        3

        )r/   r3   r;   s    r6   ambient_dimensionzLinearEntity.ambient_dimensionq   s    > 477|r7   c                     t        | t              st        |t              st        d      | j                  |j                  }}t	        |j                  |      t        |      t        |      z  z        S )a  Return the non-reflex angle formed by rays emanating from
        the origin with directions the same as the direction vectors
        of the linear entities.

        Parameters
        ==========

        l1 : LinearEntity
        l2 : LinearEntity

        Returns
        =======

        angle : angle in radians

        Notes
        =====

        From the dot product of vectors v1 and v2 it is known that:

            ``dot(v1, v2) = |v1|*|v2|*cos(A)``

        where A is the angle formed between the two vectors. We can
        get the directional vectors of the two lines and readily
        find the angle between the two using the above formula.

        See Also
        ========

        is_perpendicular, Ray2D.closing_angle

        Examples
        ========

        >>> from sympy import Line
        >>> e = Line((0, 0), (1, 0))
        >>> ne = Line((0, 0), (1, 1))
        >>> sw = Line((1, 1), (0, 0))
        >>> ne.angle_between(e)
        pi/4
        >>> sw.angle_between(e)
        3*pi/4

        To obtain the non-obtuse angle at the intersection of lines, use
        the ``smallest_angle_between`` method:

        >>> sw.smallest_angle_between(e)
        pi/4

        >>> from sympy import Point3D, Line3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(1, 1, 1), Point3D(-1, 2, 0)
        >>> l1, l2 = Line3D(p1, p2), Line3D(p2, p3)
        >>> l1.angle_between(l2)
        acos(-sqrt(2)/3)
        >>> l1.smallest_angle_between(l2)
        acos(sqrt(2)/3)
        #Must pass only LinearEntity objects)
isinstancer)   	TypeErrorrA   r   rB   absl1l2v1v2s       r6   angle_betweenzLinearEntity.angle_between   sY    t "l+Jr<4PABBr||BBFF2JBB011r7   c                     t        | t              st        |t              st        d      | j                  |j                  }}t	        t        |j                  |            t        |      t        |      z  z        S )ag  Return the smallest angle formed at the intersection of the
        lines containing the linear entities.

        Parameters
        ==========

        l1 : LinearEntity
        l2 : LinearEntity

        Returns
        =======

        angle : angle in radians

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2, p3 = Point(0, 0), Point(0, 4), Point(2, -2)
        >>> l1, l2 = Line(p1, p2), Line(p1, p3)
        >>> l1.smallest_angle_between(l2)
        pi/4

        See Also
        ========

        angle_between, is_perpendicular, Ray2D.closing_angle
        rJ   )rK   r)   rL   rA   r   rM   rB   rN   s       r6   smallest_angle_betweenz#LinearEntity.smallest_angle_between   s\    : "l+Jr<4PABBr||BCr
OSWSW_566r7   c                     t        |d      }|j                  d | j                  D        v r!t        t	        d|j                  z              | j
                  | j                  | j
                  z
  |z  z   S )a+  A parameterized point on the Line.

        Parameters
        ==========

        parameter : str, optional
            The name of the parameter which will be used for the parametric
            point. The default value is 't'. When this parameter is 0, the
            first point used to define the line will be returned, and when
            it is 1 the second point will be returned.

        Returns
        =======

        point : Point

        Raises
        ======

        ValueError
            When ``parameter`` already appears in the Line's definition.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(1, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.arbitrary_point()
        Point2D(4*t + 1, 3*t)
        >>> from sympy import Point3D, Line3D
        >>> p1, p2 = Point3D(1, 0, 0), Point3D(5, 3, 1)
        >>> l1 = Line3D(p1, p2)
        >>> l1.arbitrary_point()
        Point3D(4*t + 1, 3*t, t)

        Trealc              3   4   K   | ]  }|j                     y wN)name).0fs     r6   	<genexpr>z/LinearEntity.arbitrary_point.<locals>.<genexpr>!  s     8aff8s   zx
                Symbol %s already appears in object
                and cannot be used as a parameter.
                )r   r[   free_symbolsr-   r%   r3   r4   r;   	parameterts      r6   arbitrary_pointzLinearEntity.arbitrary_point   ss    V ID)668d&7&788Z ) ff)    ww$''DGG+Q...r7   c                  J    t        |  }|j                  rt        |      dk(  ryy)a  Is a sequence of linear entities concurrent?

        Two or more linear entities are concurrent if they all
        intersect at a single point.

        Parameters
        ==========

        lines
            A sequence of linear entities.

        Returns
        =======

        True : if the set of linear entities intersect in one point
        False : otherwise.

        See Also
        ========

        sympy.geometry.util.intersection

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(3, 5)
        >>> p3, p4 = Point(-2, -2), Point(0, 2)
        >>> l1, l2, l3 = Line(p1, p2), Line(p1, p3), Line(p1, p4)
        >>> Line.are_concurrent(l1, l2, l3)
        True
        >>> l4 = Line(p2, p3)
        >>> Line.are_concurrent(l2, l3, l4)
        False
        >>> from sympy import Point3D, Line3D
        >>> p1, p2 = Point3D(0, 0, 0), Point3D(3, 5, 2)
        >>> p3, p4 = Point3D(-2, -2, -2), Point3D(0, 2, 1)
        >>> l1, l2, l3 = Line3D(p1, p2), Line3D(p1, p3), Line3D(p1, p4)
        >>> Line3D.are_concurrent(l1, l2, l3)
        True
        >>> l4 = Line3D(p2, p3)
        >>> Line3D.are_concurrent(l2, l3, l4)
        False

        r   TF)r   is_FiniteSetr/   )linescommon_pointss     r6   are_concurrentzLinearEntity.are_concurrent*  s*    ^ %e,%%#m*<*Ar7   c                     t               )zSubclasses should implement this method and should return
            True if other is on the boundaries of self;
            False if not on the boundaries of self;
            None if a determination cannot be made.)NotImplementedErrorr;   r<   s     r6   r:   zLinearEntity.contains^  s    
 "##r7   c                 4    | j                   | j                  z
  S )a]  The direction vector of the LinearEntity.

        Returns
        =======

        p : a Point; the ray from the origin to this point is the
            direction of `self`

        Examples
        ========

        >>> from sympy import Line
        >>> a, b = (1, 1), (1, 3)
        >>> Line(a, b).direction
        Point2D(0, 2)
        >>> Line(b, a).direction
        Point2D(0, -2)

        This can be reported so the distance from the origin is 1:

        >>> Line(b, a).direction.unit
        Point2D(0, -1)

        See Also
        ========

        sympy.geometry.point.Point.unit

        )r4   r3   rG   s    r6   rA   zLinearEntity.directione  s    > ww  r7   c                 8   d }d }d }t        |t              st        || j                        }|j                  r| j                  |      r|gS g S t        |t              r't        j                  | j                  | j                  |j                  |j                        }t        j                  | }|dk(  rt        | t              r|gS t        |t              r| gS t        | t              rt        |t              r	 || |      S t        | t              rt        |t              r	 || |      S t        | t              rt        |t              r	 |||       S t        | t              rt        |t              r || |      S |dk(  rt        |dd  }t        |dd  }|j                  j                  |j                        rg S t!        |j                  |j                   g      j#                         }	t!        |j                  |j                  z
  g      j#                         }
|	j%                  d|
      j'                  d	      \  }}t)        |      dk7  rt+        d
j-                  |	|
            |d   }|j                  |z  | j                  z   }t        | t              rt        |t              r|gS t        | t              s| j                  |      r|j                  |      r|gS | j/                  t0              s|j/                  t0              sg S t3        | j5                  t6              |j5                  t8              z
  t6        t8        d      d   }d } ||t6           |       r ||t8           |      r|gS g S g S |j;                  |       S )a:  The intersection with another geometrical entity.

        Parameters
        ==========

        o : Point or LinearEntity

        Returns
        =======

        intersection : list of geometrical entities

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Line, Segment
        >>> p1, p2, p3 = Point(0, 0), Point(1, 1), Point(7, 7)
        >>> l1 = Line(p1, p2)
        >>> l1.intersection(p3)
        [Point2D(7, 7)]
        >>> p4, p5 = Point(5, 0), Point(0, 3)
        >>> l2 = Line(p4, p5)
        >>> l1.intersection(l2)
        [Point2D(15/8, 15/8)]
        >>> p6, p7 = Point(0, 5), Point(2, 6)
        >>> s1 = Segment(p6, p7)
        >>> l1.intersection(s1)
        []
        >>> from sympy import Point3D, Line3D, Segment3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(1, 1, 1), Point3D(7, 7, 7)
        >>> l1 = Line3D(p1, p2)
        >>> l1.intersection(p3)
        [Point3D(7, 7, 7)]
        >>> l1 = Line3D(Point3D(4,19,12), Point3D(5,25,17))
        >>> l2 = Line3D(Point3D(-3, -15, -19), direction_ratio=[2,8,8])
        >>> l1.intersection(l2)
        [Point3D(1, 1, -3)]
        >>> p6, p7 = Point3D(0, 5, 2), Point3D(2, 6, 3)
        >>> s1 = Segment3D(p6, p7)
        >>> l1.intersection(s1)
        []

        c                 D   | j                   j                  |j                         dkD  r$| j                  |j                        dk\  r|gS | gS | j                  |j                        }|dk  rg S |dk(  r|j                  gS t	        | j                  |j                        gS Nr   )rA   rB   rE   r3   Segment)ray1ray2sts      r6   intersect_parallel_raysz:LinearEntity.intersection.<locals>.intersect_parallel_rays  s    ~~!!$..1A5 "&!9Q!>vJTFJ __TWW-6I1W GG9$122r7   c                 .   | j                  |j                        | j                  |j                        }}|dk  r|dk  rg S |dk\  r|dk\  r|gS |dk\  r!t        | j                  |j                        gS t        | j                  |j                        gS ro   )rE   r3   r4   rp   )raysegst1st2s       r6   "intersect_parallel_ray_and_segmentzELinearEntity.intersection.<locals>.intersect_parallel_ray_and_segment  s    ~~cff-s~~cff/ECQw37	cQhu/00/00r7   c                    | j                  |      r|gS |j                  |       r| gS | j                  j                  |j                        dk  r t        |j                  |j
                        }| j                  |j
                        dk  r|| }} |j                  | j                        dk  rg S t        |j
                  | j                        gS ro   )r:   rA   rB   rp   r4   r3   rE   )seg1seg2s     r6   intersect_parallel_segmentsz>LinearEntity.intersection.<locals>.intersect_parallel_segments  s    }}T"v}}T"v ~~!!$..1A5tww0tww'!+!4dtww'!+	DGGTWW-..r7   dimr   r&   NTr    z+Failed when solving Mx=b when M={} and b={})r   r&   )dictr   c                     t        |t              ryt        |t              r| j                  S t        |t              r| j                  xr d| z
  j                  S t        d      )NTr   zunexpected line type)rK   LineRayis_nonnegativerp   r-   )pls     r6   okz%LinearEntity.intersection.<locals>.ok'  sV    !!T*#!!S) ///!!W- //JQU4J4JJ$%;<<r7   )rK   r   r   rH   is_Pointr:   r)   r,   r3   r4   affine_rankr   r   rp   rA   is_scalar_multipler   	transpose
col_insertrrefr/   r   formatatomsr   r"   rc   rb   ur   )r;   r<   rt   rz   r~   ptsrankrO   rP   mvm_rrefpivotscoeffline_intersectiontur   s                    r6   r   zLinearEntity.intersection  s   b	3		1	/  %0%T%;%;<E>>}}U#w	|, ,,TWWdgguxxRC$$c*DqydD)!7NeT* 6MdC(Zs-C24??dC(Zw-G=dEJJdG,E31G=eTJJdG,E71K6tUCC3r7^3qr7^
 <<222<<@I BLL2<<-89CCEBEEBEEM?+557 "#a!3!8!8$!8!Gv;!#'(U(\(\]^`a(bcct$&LL$6$@! dD)j.E-..d+]]#45'89-..zz%(U1C I
 4//2U5J5J15MMqt%%&(
= beT?r"Q%'7-..	 	!!$''r7   c                     t        | t              st        |t              st        d      | j                  j	                  |j                        S )a  Are two linear entities parallel?

        Parameters
        ==========

        l1 : LinearEntity
        l2 : LinearEntity

        Returns
        =======

        True : if l1 and l2 are parallel,
        False : otherwise.

        See Also
        ========

        coefficients

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(1, 1)
        >>> p3, p4 = Point(3, 4), Point(6, 7)
        >>> l1, l2 = Line(p1, p2), Line(p3, p4)
        >>> Line.is_parallel(l1, l2)
        True
        >>> p5 = Point(6, 6)
        >>> l3 = Line(p3, p5)
        >>> Line.is_parallel(l1, l3)
        False
        >>> from sympy import Point3D, Line3D
        >>> p1, p2 = Point3D(0, 0, 0), Point3D(3, 4, 5)
        >>> p3, p4 = Point3D(2, 1, 1), Point3D(8, 9, 11)
        >>> l1, l2 = Line3D(p1, p2), Line3D(p3, p4)
        >>> Line3D.is_parallel(l1, l2)
        True
        >>> p5 = Point3D(6, 6, 6)
        >>> l3 = Line3D(p3, p5)
        >>> Line3D.is_parallel(l1, l3)
        False

        rJ   )rK   r)   rL   rA   r   rO   rP   s     r6   is_parallelzLinearEntity.is_parallel;  s=    Z "l+Jr<4PABB||..r||<<r7   c                     t        | t              st        |t              st        d      t        j                  j                  | j                  j                  |j                              S )a  Are two linear entities perpendicular?

        Parameters
        ==========

        l1 : LinearEntity
        l2 : LinearEntity

        Returns
        =======

        True : if l1 and l2 are perpendicular,
        False : otherwise.

        See Also
        ========

        coefficients

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2, p3 = Point(0, 0), Point(1, 1), Point(-1, 1)
        >>> l1, l2 = Line(p1, p2), Line(p1, p3)
        >>> l1.is_perpendicular(l2)
        True
        >>> p4 = Point(5, 3)
        >>> l3 = Line(p1, p4)
        >>> l1.is_perpendicular(l3)
        False
        >>> from sympy import Point3D, Line3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(1, 1, 1), Point3D(-1, 2, 0)
        >>> l1, l2 = Line3D(p1, p2), Line3D(p2, p3)
        >>> l1.is_perpendicular(l2)
        False
        >>> p4 = Point3D(5, 3, 7)
        >>> l3 = Line3D(p1, p4)
        >>> l1.is_perpendicular(l3)
        False

        rJ   )rK   r)   rL   r
   ZeroequalsrA   rB   r   s     r6   is_perpendicularzLinearEntity.is_perpendicularm  sJ    V "l+Jr<4PABBvv}}R\\--bll;<<r7   c                 d    t        | j                  | j                        }|j                  |      S )aC  
        Return True if self and other are contained in the same line.

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2, p3 = Point(0, 1), Point(3, 4), Point(2, 3)
        >>> l1 = Line(p1, p2)
        >>> l2 = Line(p1, p3)
        >>> l1.is_similar(l2)
        True
        )r   r3   r4   r:   )r;   r<   r   s      r6   
is_similarzLinearEntity.is_similar  s'     $''"zz%  r7   c                 "    t         j                  S )z
        The length of the line.

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(3, 5)
        >>> l1 = Line(p1, p2)
        >>> l1.length
        oo
        )r
   InfinityrG   s    r6   lengthzLinearEntity.length  s     zzr7   c                      | j                   d   S )a=  The first defining point of a linear entity.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> l = Line(p1, p2)
        >>> l.p1
        Point2D(0, 0)

        r   argsrG   s    r6   r3   zLinearEntity.p1      & yy|r7   c                      | j                   d   S )a>  The second defining point of a linear entity.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> l = Line(p1, p2)
        >>> l.p2
        Point2D(5, 3)

        r   r   rG   s    r6   r4   zLinearEntity.p2  r   r7   c                 b    t        || j                        }t        ||| j                  z         S )a?  Create a new Line parallel to this linear entity which passes
        through the point `p`.

        Parameters
        ==========

        p : Point

        Returns
        =======

        line : Line

        See Also
        ========

        is_parallel

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2, p3 = Point(0, 0), Point(2, 3), Point(-2, 2)
        >>> l1 = Line(p1, p2)
        >>> l2 = l1.parallel_line(p3)
        >>> p3 in l2
        True
        >>> l1.is_parallel(l2)
        True
        >>> from sympy import Point3D, Line3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(2, 3, 4), Point3D(-2, 2, 0)
        >>> l1 = Line3D(p1, p2)
        >>> l2 = l1.parallel_line(p3)
        >>> p3 in l2
        True
        >>> l1.is_parallel(l2)
        True

        r   )r   rH   r   rA   r;   r   s     r6   parallel_linezLinearEntity.parallel_line  s-    P !//0Aq4>>)**r7   c                     t        || j                        }|| v r|| j                  j                  z   }t	        || j                  |            S )a  Create a new Line perpendicular to this linear entity which passes
        through the point `p`.

        Parameters
        ==========

        p : Point

        Returns
        =======

        line : Line

        See Also
        ========

        sympy.geometry.line.LinearEntity.is_perpendicular, perpendicular_segment

        Examples
        ========

        >>> from sympy import Point3D, Line3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(2, 3, 4), Point3D(-2, 2, 0)
        >>> L = Line3D(p1, p2)
        >>> P = L.perpendicular_line(p3); P
        Line3D(Point3D(-2, 2, 0), Point3D(4/29, 6/29, 8/29))
        >>> L.is_perpendicular(P)
        True

        In 3D the, the first point used to define the line is the point
        through which the perpendicular was required to pass; the
        second point is (arbitrarily) contained in the given line:

        >>> P.p2 in L
        True
        r   )r   rH   rA   orthogonal_directionr   
projectionr   s     r6   perpendicular_linezLinearEntity.perpendicular_line  sH    J !//09DNN777AAtq)**r7   c                     t        || j                        }|| v r|S | j                  |      }t        t	        | j
                  | j                        |      \  }t        ||      S )a  Create a perpendicular line segment from `p` to this line.

        The endpoints of the segment are ``p`` and the closest point in
        the line containing self. (If self is not a line, the point might
        not be in self.)

        Parameters
        ==========

        p : Point

        Returns
        =======

        segment : Segment

        Notes
        =====

        Returns `p` itself if `p` is on this linear entity.

        See Also
        ========

        perpendicular_line

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2, p3 = Point(0, 0), Point(1, 1), Point(0, 2)
        >>> l1 = Line(p1, p2)
        >>> s1 = l1.perpendicular_segment(p3)
        >>> l1.is_perpendicular(s1)
        True
        >>> p3 in s1
        True
        >>> l1.perpendicular_segment(Point(4, 0))
        Segment2D(Point2D(4, 0), Point2D(2, 2))
        >>> from sympy import Point3D, Line3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(1, 1, 1), Point3D(0, 2, 0)
        >>> l1 = Line3D(p1, p2)
        >>> s1 = l1.perpendicular_segment(p3)
        >>> l1.is_perpendicular(s1)
        True
        >>> p3 in s1
        True
        >>> l1.perpendicular_segment(Point3D(4, 0, 0))
        Segment3D(Point3D(4, 0, 0), Point3D(4/3, 4/3, 4/3))

        r   )r   rH   r   r   r   r3   r4   rp   r;   r   r   r4   s       r6   perpendicular_segmentz"LinearEntity.perpendicular_segment=  s\    h !//09H##A&4115q"~r7   c                 2    | j                   | j                  fS )a  The two points used to define this linear entity.

        Returns
        =======

        points : tuple of Points

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(5, 11)
        >>> l1 = Line(p1, p2)
        >>> l1.points
        (Point2D(0, 0), Point2D(5, 11))

        )r3   r4   rG   s    r6   pointszLinearEntity.pointsz  s    0 !!r7   c                 R    t        |t              st        | j                        } fd}t        |t              r ||      S t        |t              r ||j
                         ||j                        }}||k(  r|S |j                  ||      }t         |      }|j                  r|S |j                  rt        |      dk(  r|\  }|S  j                  j                  |j                        dk  r!|j                  \  }}|j                  ||      }|S t!        d|d       )a  Project a point, line, ray, or segment onto this linear entity.

        Parameters
        ==========

        other : Point or LinearEntity (Line, Ray, Segment)

        Returns
        =======

        projection : Point or LinearEntity (Line, Ray, Segment)
            The return type matches the type of the parameter ``other``.

        Raises
        ======

        GeometryError
            When method is unable to perform projection.

        Notes
        =====

        A projection involves taking the two points that define
        the linear entity and projecting those points onto a
        Line and then reforming the linear entity using these
        projections.
        A point P is projected onto a line L by finding the point
        on L that is closest to P. This point is the intersection
        of L and the line perpendicular to L that passes through P.

        See Also
        ========

        sympy.geometry.point.Point, perpendicular_line

        Examples
        ========

        >>> from sympy import Point, Line, Segment, Rational
        >>> p1, p2, p3 = Point(0, 0), Point(1, 1), Point(Rational(1, 2), 0)
        >>> l1 = Line(p1, p2)
        >>> l1.projection(p3)
        Point2D(1/4, 1/4)
        >>> p4, p5 = Point(10, 0), Point(12, 1)
        >>> s1 = Segment(p4, p5)
        >>> l1.projection(s1)
        Segment2D(Point2D(5, 5), Point2D(13/2, 13/2))
        >>> p1, p2, p3 = Point(0, 0, 1), Point(1, 1, 2), Point(2, 0, 1)
        >>> l1 = Line(p1, p2)
        >>> l1.projection(p3)
        Point3D(2/3, 2/3, 5/3)
        >>> p4, p5 = Point(10, 0, 1), Point(12, 1, 3)
        >>> s1 = Segment(p4, p5)
        >>> l1.projection(s1)
        Segment3D(Point3D(10/3, 10/3, 13/3), Point3D(5, 5, 6))

        r   c                 x    t        j                  | j                  z
  j                        j                  z   S rZ   )r   projectr3   rA   )r   r;   s    r6   
proj_pointz+LinearEntity.projection.<locals>.proj_point  s)    ==TWWdnn=GGr7   r   r   zDo not know how to project z onto )rK   r   r   rH   r)   r3   r4   	__class__r   is_emptyre   r/   rA   rB   r   funcr   )r;   r<   r   r3   r4   	projectedas   `      r6   r   zLinearEntity.projection  s   t %0%T%;%;<E	H eU#e$$|,):ehh+?BRx	B/I$T95I!!  %%#i.A*=~~!!)"5"56:"B%NN2r2	7<dCE 	Er7   c                    |t        j                  |      }nt         }| j                  t              }t	        | t
              rt        |j                  dd            }nOt	        | t              r|j                         }n.t	        | t              r|j                  dd      }nt        d      |j                  t        t        |            S )a  A random point on a LinearEntity.

        Returns
        =======

        point : Point

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Line, Ray, Segment
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> line = Line(p1, p2)
        >>> r = line.random_point(seed=42)  # seed value is optional
        >>> r.n(3)
        Point2D(-0.72, -0.432)
        >>> r in line
        True
        >>> Ray(p1, p2).random_point(seed=42).n(3)
        Point2D(0.72, 0.432)
        >>> Segment(p1, p2).random_point(seed=42).n(3)
        Point2D(3.2, 1.92)

        r   r   zunhandled line type)randomRandomrc   rb   rK   r   rM   gaussrp   r   rj   subsr   )r;   seedrngptr   s        r6   random_pointzLinearEntity.random_point  s    < --%CC!!!$dC CIIaO$Ag&

Ad#		!QA%&;<<wwq(1+&&r7   c                    t        |t              st        d|z        | |}}|j                  j                  |j                  j                  k7  r~t        |t
              r||}}t        j                  |j                  |j                  d      \  }}t        j                  |j                  |j                  d      \  }}t        ||      }t        ||      }|st        d      |d   }t        |t              r| gS |j                  j                  }	|j                  j                  }
t        |||	z   |
z         }t        |||	z   |
z
        }||gS )aN  Returns the perpendicular lines which pass through the intersections
        of self and other that are in the same plane.

        Parameters
        ==========

        line : Line3D

        Returns
        =======

        list: two Line instances

        Examples
        ========

        >>> from sympy import Point3D, Line3D
        >>> r1 = Line3D(Point3D(0, 0, 0), Point3D(1, 0, 0))
        >>> r2 = Line3D(Point3D(0, 0, 0), Point3D(0, 1, 0))
        >>> r1.bisectors(r2)
        [Line3D(Point3D(0, 0, 0), Point3D(1, 1, 0)), Line3D(Point3D(0, 0, 0), Point3D(1, -1, 0))]

        zExpecting LinearEntity, not %signore)on_morphzThe lines do not intersectr   )rK   r)   r   r3   rH   Line2Dr   r,   r4   r   r   rA   unit)r;   r<   rO   rP   _r3   r4   pointr   d1d2bis1bis2s                r6   	bisectorszLinearEntity.bisectors  s-   0 %. @5 HIIuB 55""bee&=&=="f%RB..ruubeehOEAr..ruubeehOEArb"BR$  <==qB"d#v \\\\BR"%BR"%d|r7   rZ   rb   )r.   
__module____qualname____doc__r0   r>   rE   propertyrH   rS   rU   rc   staticmethodrh   r:   rA   r   r   r   r   r   r3   r4   r   r   r   r   r   r   r    r7   r6   r)   r)   2   s    0=	L  @>2@!7F3/j 1 1f$ ! !@s(j0=d.=`!"    (  ()+V(+T;z " "2WEr+'Z8r7   r)   c                   0    e Zd ZdZd Zd Zd Zd ZddZy)	r   a  An infinite line in space.

    A 2D line is declared with two distinct points, point and slope, or
    an equation. A 3D line may be defined with a point and a direction ratio.

    Parameters
    ==========

    p1 : Point
    p2 : Point
    slope : SymPy expression
    direction_ratio : list
    equation : equation of a line

    Notes
    =====

    `Line` will automatically subclass to `Line2D` or `Line3D` based
    on the dimension of `p1`.  The `slope` argument is only relevant
    for `Line2D` and the `direction_ratio` argument is only relevant
    for `Line3D`.

    The order of the points will define the direction of the line
    which is used when calculating the angle between lines.

    See Also
    ========

    sympy.geometry.point.Point
    sympy.geometry.line.Line2D
    sympy.geometry.line.Line3D

    Examples
    ========

    >>> from sympy import Line, Segment, Point, Eq
    >>> from sympy.abc import x, y, a, b

    >>> L = Line(Point(2,3), Point(3,5))
    >>> L
    Line2D(Point2D(2, 3), Point2D(3, 5))
    >>> L.points
    (Point2D(2, 3), Point2D(3, 5))
    >>> L.equation()
    -2*x + y + 1
    >>> L.coefficients
    (-2, 1, 1)

    Instantiate with keyword ``slope``:

    >>> Line(Point(0, 0), slope=0)
    Line2D(Point2D(0, 0), Point2D(1, 0))

    Instantiate with another linear object

    >>> s = Segment((0, 0), (0, 1))
    >>> Line(s).equation()
    x

    The line corresponding to an equation in the for `ax + by + c = 0`,
    can be entered:

    >>> Line(3*x + y + 18)
    Line2D(Point2D(0, -18), Point2D(1, -21))

    If `x` or `y` has a different name, then they can be specified, too,
    as a string (to match the name) or symbol:

    >>> Line(Eq(3*a + b, -18), x='a', y=b)
    Line2D(Point2D(0, -18), Point2D(1, -21))
    c                    t        |      dk(  r t        |d   t        t        f      rt	        d|      |sd}d}n$|j                  d      }|j                  d      }|rt        d      |d   t        t              rj                  j                  z
  fd} ||      } ||      }t        ||      \  }}}|rt        d| |z  f| |z        S |rt        | |z  dft              S t        d	t        d
      ||hz
  z        t        |      dkD  r|d   }	t        |      dkD  r|d   }
nd }
t        |	t              r#|
rt        d      t        |	j                        }nBt        |	      }	t        |	      }|
t        |
t              r|
j                   |k7  rt        |
      }
|dk(  rt#        |	|
fi |S |dk(  rt%        |	|
fi |S t        j&                  | |	|
fi |S y )Nr   r   ?xyz"expecting only x and y as keywordsc                 @    	 t        |       S # t        $ r cY S w xY wrZ   )r   r-   )r   equationmissings    r6   find_or_missingz%Line.__new__.<locals>.find_or_missing  s)    #8,,! #"N#s    )slopeznot found in equation: %sxyz)If p1 is a LinearEntity, p2 must be None.r&      )r/   rK   r   r	   r   popr-   lhsrhsr#   r   r   setr)   r3   r   rH   r   Line3Dr0   )r2   r   r5   r   r   r   r   bcr3   r4   r   r   r   s               @@r6   r0   zLine.__new__  s   t9>ja4*=+C6GJJsG,JJsG, !EFFAwH(B'#<<(,,6#
  "A"A#Ha3GAq!Q1IaRT22aRT1IR008CIA<NOPP 4y1}!Wt9q=aBBb,/()TUUbee*CrBb'C~B)>2CWCW[^C^"2Y!8!"b3F33AX!"b3F33#++CRB6BB+ r7   c                 h   t        |t              st        || j                        }t        |t              r+t        j                  || j
                  | j                        S t        |t              r@t        j                  | j
                  | j                  |j
                  |j                        S y)a2  
        Return True if `other` is on this Line, or False otherwise.

        Examples
        ========

        >>> from sympy import Line,Point
        >>> p1, p2 = Point(0, 1), Point(3, 4)
        >>> l = Line(p1, p2)
        >>> l.contains(p1)
        True
        >>> l.contains((0, 1))
        True
        >>> l.contains((0, 0))
        False
        >>> a = (0, 0, 0)
        >>> b = (1, 1, 1)
        >>> c = (2, 2, 2)
        >>> l1 = Line(a, b)
        >>> l2 = Line(b, a)
        >>> l1 == l2
        False
        >>> l1 in l2
        True

        r   F)rK   r   r   rH   is_collinearr3   r4   r)   rk   s     r6   r:   zLine.contains  s{    6 %0%T%;%;<EeU#%%eTWWdgg>>e\*%%dggtww%((KKr7   c                     t        |t              st        || j                        }| j	                  |      rt
        j                  S | j                  |      j                  S )ap  
        Finds the shortest distance between a line and a point.

        Raises
        ======

        NotImplementedError is raised if `other` is not a Point

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(1, 1)
        >>> s = Line(p1, p2)
        >>> s.distance(Point(-1, 1))
        sqrt(2)
        >>> s.distance((-1, 2))
        3*sqrt(2)/2
        >>> p1, p2 = Point(0, 0, 0), Point(1, 1, 1)
        >>> s = Line(p1, p2)
        >>> s.distance(Point(-1, 1, 1))
        2*sqrt(6)/3
        >>> s.distance((-1, 1, 1))
        2*sqrt(6)/3

        r   )	rK   r   r   rH   r:   r
   r   r   r   rk   s     r6   distancezLine.distance  sL    6 %0%T%;%;<E==66M))%0777r7   c                     t        |t              syt        j                  | j                  |j                  | j
                  |j
                        S AReturns True if self and other are the same mathematical entitiesF)rK   r   r   r   r3   r4   rk   s     r6   r   zLine.equals  s6    %&!!$''588TWWehhGGr7   c                 &    t        |d      }|ddgS )a  The plot interval for the default geometric plot of line. Gives
        values that will produce a line that is +/- 5 units long (where a
        unit is the distance between the two points that define the line).

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list (plot interval)
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.plot_interval()
        [t, -5, 5]

        TrW      r   r`   s      r6   plot_intervalzLine.plot_interval   s    6 ID)2qzr7   Nr   )	r.   r   r   r   r0   r:   r   r   r   r   r7   r6   r   r   U  s'    FN7Cr!F8BHr7   r   c                   J    e Zd ZdZd
dZddZd Zd Zd ZddZ	e
d	        Zy)r   a  A Ray is a semi-line in the space with a source point and a direction.

    Parameters
    ==========

    p1 : Point
        The source of the Ray
    p2 : Point or radian value
        This point determines the direction in which the Ray propagates.
        If given as an angle it is interpreted in radians with the positive
        direction being ccw.

    Attributes
    ==========

    source

    See Also
    ========

    sympy.geometry.line.Ray2D
    sympy.geometry.line.Ray3D
    sympy.geometry.point.Point
    sympy.geometry.line.Line

    Notes
    =====

    `Ray` will automatically subclass to `Ray2D` or `Ray3D` based on the
    dimension of `p1`.

    Examples
    ========

    >>> from sympy import Ray, Point, pi
    >>> r = Ray(Point(2, 3), Point(3, 5))
    >>> r
    Ray2D(Point2D(2, 3), Point2D(3, 5))
    >>> r.points
    (Point2D(2, 3), Point2D(3, 5))
    >>> r.source
    Point2D(2, 3)
    >>> r.xdirection
    oo
    >>> r.ydirection
    oo
    >>> r.slope
    2
    >>> Ray(Point(0, 0), angle=pi/4).slope
    1

    Nc                     t        |      }|"t        j                  |t        |            \  }}t        |      }|dk(  rt        ||fi |S |dk(  rt	        ||fi |S t        j                  | ||fi |S Nr&   r   )r   r,   r/   Ray2DRay3Dr)   r0   r2   r3   r4   r5   r   s        r6   r0   zRay.__new__t  s    2Y>//E"I>FB"g!8R*6**AXR*6**##CR:6::r7   c                 @   t        | j                        t        | j                        f}|D cg c](  }dj                  |j                  |j
                        * }}dj                  |d   dj                  |dd             }dj                  d|z  ||      S c c}w )	'  Returns SVG path element for the LinearEntity.

        Parameters
        ==========

        scale_factor : float
            Multiplication factor for the SVG stroke-width.  Default is 1.
        fill_color : str, optional
            Hex string for fill color. Default is "#66cc99".
        {},{}	M {} L {}r    L r   Nz<path fill-rule="evenodd" fill="{2}" stroke="#555555" stroke-width="{0}" opacity="0.6" d="{1}" marker-start="url(#markerCircle)" marker-end="url(#markerArrow)"/>       @r   r3   r4   r   r   r   joinr;   scale_factor
fill_colorvertsr   coordspaths          r6   _svgzRay._svg  s     477QtwwZ(49:q'..acc*::!!&)UZZqr
-CDQ &L$

3		4 ;   -Bc                    t        |t              st        || j                        }t        |t              r{t        j                  | j
                  | j                  |      rOt        | j                  | j
                  z
  j                  || j
                  z
        t        j                  k\        S yt        |t              rt        j                  | j
                  | j                  |j
                  |j                        rYt        | j                  | j
                  z
  j                  |j                  |j
                  z
        t        j                  kD        S yt        |t              r|j
                  | v xr |j                  | v S y)a  
        Is other GeometryEntity contained in this Ray?

        Examples
        ========

        >>> from sympy import Ray,Point,Segment
        >>> p1, p2 = Point(0, 0), Point(4, 4)
        >>> r = Ray(p1, p2)
        >>> r.contains(p1)
        True
        >>> r.contains((1, 1))
        True
        >>> r.contains((1, 3))
        False
        >>> s = Segment((1, 1), (2, 2))
        >>> r.contains(s)
        True
        >>> s = Segment((1, 2), (2, 5))
        >>> r.contains(s)
        False
        >>> r1 = Ray((2, 2), (3, 3))
        >>> r.contains(r1)
        True
        >>> r1 = Ray((2, 2), (3, 5))
        >>> r.contains(r1)
        False
        r   F)rK   r   r   rH   r   r3   r4   boolrB   r
   r   r   rp   rk   s     r6   r:   zRay.contains  s   : %0%T%;%;<EeU#!!$''477E: TWWtww.33EDGGODNOOs#!!$''477EHHehhGTWWtww.33EHHuxx4GH166QRRw'88t#8D(88 r7   c                 ^   t        |t              st        || j                        }| j	                  |      rt
        j                  S t        | j                  | j                        j                  |      }| j	                  |      rt        ||z
        S t        || j                  z
        S )a  
        Finds the shortest distance between the ray and a point.

        Raises
        ======

        NotImplementedError is raised if `other` is not a Point

        Examples
        ========

        >>> from sympy import Point, Ray
        >>> p1, p2 = Point(0, 0), Point(1, 1)
        >>> s = Ray(p1, p2)
        >>> s.distance(Point(-1, -1))
        sqrt(2)
        >>> s.distance((-1, 2))
        3*sqrt(2)/2
        >>> p1, p2 = Point(0, 0, 0), Point(1, 1, 2)
        >>> s = Ray(p1, p2)
        >>> s
        Ray3D(Point3D(0, 0, 0), Point3D(1, 1, 2))
        >>> s.distance(Point(-1, -1, 2))
        4*sqrt(3)/3
        >>> s.distance((-1, -1, 2))
        4*sqrt(3)/3

        r   )rK   r   r   rH   r:   r
   r   r   r3   r4   r   rM   source)r;   r<   projs      r6   r   zRay.distance  s    : %0%T%;%;<E==66MDGGTWW%007==ut|$$ut{{*++r7   c                 v    t        |t              sy| j                  |j                  k(  xr |j                  | v S r   )rK   r   r  r4   rk   s     r6   r   z
Ray.equals  s0    %%{{ell*?uxx4/??r7   c                 &    t        |d      }|ddgS )a\  The plot interval for the default geometric plot of the Ray. Gives
        values that will produce a ray that is 10 units long (where a unit is
        the distance between the two points that define the ray).

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Ray, pi
        >>> r = Ray((0, 0), angle=pi/4)
        >>> r.plot_interval()
        [t, 0, 10]

        TrW   r   
   r   r`   s      r6   r   zRay.plot_interval  s    4 ID)1bzr7   c                     | j                   S )a  The point from which the ray emanates.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Ray
        >>> p1, p2 = Point(0, 0), Point(4, 1)
        >>> r1 = Ray(p1, p2)
        >>> r1.source
        Point2D(0, 0)
        >>> p1, p2 = Point(0, 0, 0), Point(4, 1, 5)
        >>> r1 = Ray(p2, p1)
        >>> r1.source
        Point3D(4, 1, 5)

        )r3   rG   s    r6   r  z
Ray.source  s    . wwr7   rZ   g      ?z#66cc99r   )r.   r   r   r   r0   r  r:   r   r   r   r   r  r   r7   r6   r   r   ?  s=    3h
;4*.`&,P@:  r7   r   c                   X    e Zd ZdZd Zd Zd Zd Zed        Z	ed        Z
dd	Zdd
Zy)rp   a  A line segment in space.

    Parameters
    ==========

    p1 : Point
    p2 : Point

    Attributes
    ==========

    length : number or SymPy expression
    midpoint : Point

    See Also
    ========

    sympy.geometry.line.Segment2D
    sympy.geometry.line.Segment3D
    sympy.geometry.point.Point
    sympy.geometry.line.Line

    Notes
    =====

    If 2D or 3D points are used to define `Segment`, it will
    be automatically subclassed to `Segment2D` or `Segment3D`.

    Examples
    ========

    >>> from sympy import Point, Segment
    >>> Segment((1, 0), (1, 1)) # tuples are interpreted as pts
    Segment2D(Point2D(1, 0), Point2D(1, 1))
    >>> s = Segment(Point(4, 3), Point(1, 1))
    >>> s.points
    (Point2D(4, 3), Point2D(1, 1))
    >>> s.slope
    2/3
    >>> s.length
    sqrt(13)
    >>> s.midpoint
    Point2D(5/2, 2)
    >>> Segment((1, 0, 0), (1, 1, 1)) # tuples are interpreted as pts
    Segment3D(Point3D(1, 0, 0), Point3D(1, 1, 1))
    >>> s = Segment(Point(4, 3, 9), Point(1, 1, 7)); s
    Segment3D(Point3D(4, 3, 9), Point3D(1, 1, 7))
    >>> s.points
    (Point3D(4, 3, 9), Point3D(1, 1, 7))
    >>> s.length
    sqrt(17)
    >>> s.midpoint
    Point3D(5/2, 2, 8)

    c                     t        j                  t        |      t        |            \  }}t        |      }|dk(  rt        ||fi |S |dk(  rt	        ||fi |S t        j                  | ||fi |S r   )r   r,   r/   	Segment2D	Segment3Dr)   r0   r  s        r6   r0   zSegment.__new__b  su    ++E"IuRyAB"g!8R.v..AXR.v..##CR:6::r7   c           
         t        |t              st        || j                        }t        |t              ryt        j                  || j
                  | j                        rMt        | t              rd| j                  z  j                  d      }|du rP| j
                  j                  |j                  z
  | j                  j                  |j                  z
  z  dk  }|dv r|S |du rP| j
                  j                  |j                  z
  | j                  j                  |j                  z
  z  dk  }|dv r|S || j
                  z
  || j                  z
  }}| j                  | j
                  z
  }	 t        t        t        t        |      t        |      z   t        |      z
  d                  S t        |t&              r|j
                  | v xr |j                  | v S y# t         $ r t#        dj%                  ||             w xY w)a;  
        Is the other GeometryEntity contained within this Segment?

        Examples
        ========

        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(0, 1), Point(3, 4)
        >>> s = Segment(p1, p2)
        >>> s2 = Segment(p2, p1)
        >>> s.contains(s2)
        True
        >>> from sympy import Point3D, Segment3D
        >>> p1, p2 = Point3D(0, 1, 1), Point3D(3, 4, 5)
        >>> s = Segment3D(p1, p2)
        >>> s2 = Segment3D(p2, p1)
        >>> s.contains(s2)
        True
        >>> s.contains((p1 + p2)/2)
        True
        r   r   r   F)TFTzCannot determine if {} is in {})rK   r   r   rH   r   r3   r4   r  r   r   r   r   r  r!   r	   rM   rL   r$   r   rp   )r;   r<   vertisinr   r   rD   s          r6   r:   zSegment.containsl  s   , %0%T%;%;<EeU#!!%$'':dI. djjL003Du} $		EGG 3dggii%''6IJaO=0#'Kt| $		EGG 3dggii%''6IJaO=0#'K%$''/BGGdgg%]  CGc"g,=A,F)J KLL eW%88t#8D(88 ! ]%&G&N&NuVZ&[\\]s   3>G! !%Hc                     t        || j                        xr= t        t        | j                              t        t        |j                              k(  S )r   )rK   r   listr   r   rk   s     r6   r   zSegment.equals  sC    %+ =DII1 #'

(;#<1= 	=r7   c                    t        |t              st        || j                        }t        |t              r|| j                  z
  }|| j
                  z
  }| j                  j                  |      dk\  }| j                  j                  |      dk  }|r1|r/t        | j                  | j
                        j                  |      S |r|st        |      S |s|rt        |      S t               )a  
        Finds the shortest distance between a line segment and a point.

        Raises
        ======

        NotImplementedError is raised if `other` is not a Point

        Examples
        ========

        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(0, 1), Point(3, 4)
        >>> s = Segment(p1, p2)
        >>> s.distance(Point(10, 15))
        sqrt(170)
        >>> s.distance((0, 12))
        sqrt(73)
        >>> from sympy import Point3D, Segment3D
        >>> p1, p2 = Point3D(0, 0, 3), Point3D(1, 1, 4)
        >>> s = Segment3D(p1, p2)
        >>> s.distance(Point3D(10, 15, 12))
        sqrt(341)
        >>> s.distance((10, 15, 12))
        sqrt(341)
        r   r   )rK   r   r   rH   r3   r4   rA   rB   r   r   rM   rj   )r;   r<   vp1vp2dot_prod_sign_1dot_prod_sign_2s         r6   r   zSegment.distance  s    6 %0%T%;%;<EeU#$''/C$''/C"nn005:O"nn005:O?DGGTWW-66u==3x"3x!##r7   c                 V    t        j                  | j                  | j                        S )a  The length of the line segment.

        See Also
        ========

        sympy.geometry.point.Point.distance

        Examples
        ========

        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(0, 0), Point(4, 3)
        >>> s1 = Segment(p1, p2)
        >>> s1.length
        5
        >>> from sympy import Point3D, Segment3D
        >>> p1, p2 = Point3D(0, 0, 0), Point3D(4, 3, 3)
        >>> s1 = Segment3D(p1, p2)
        >>> s1.length
        sqrt(34)

        )r   r   r3   r4   rG   s    r6   r   zSegment.length      0 ~~dggtww//r7   c                 V    t        j                  | j                  | j                        S )a  The midpoint of the line segment.

        See Also
        ========

        sympy.geometry.point.Point.midpoint

        Examples
        ========

        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(0, 0), Point(4, 3)
        >>> s1 = Segment(p1, p2)
        >>> s1.midpoint
        Point2D(2, 3/2)
        >>> from sympy import Point3D, Segment3D
        >>> p1, p2 = Point3D(0, 0, 0), Point3D(4, 3, 3)
        >>> s1 = Segment3D(p1, p2)
        >>> s1.midpoint
        Point3D(2, 3/2, 3/2)

        )r   midpointr3   r4   rG   s    r6   r-  zSegment.midpoint  r+  r7   Nc                     | j                  | j                        }|1t        || j                        }||v rt	        || j                        S |S )ak  The perpendicular bisector of this segment.

        If no point is specified or the point specified is not on the
        bisector then the bisector is returned as a Line. Otherwise a
        Segment is returned that joins the point specified and the
        intersection of the bisector and the segment.

        Parameters
        ==========

        p : Point

        Returns
        =======

        bisector : Line or Segment

        See Also
        ========

        LinearEntity.perpendicular_segment

        Examples
        ========

        >>> from sympy import Point, Segment
        >>> p1, p2, p3 = Point(0, 0), Point(6, 6), Point(5, 1)
        >>> s1 = Segment(p1, p2)
        >>> s1.perpendicular_bisector()
        Line2D(Point2D(3, 3), Point2D(-3, 9))

        >>> s1.perpendicular_bisector(p3)
        Segment2D(Point2D(5, 1), Point2D(3, 3))

        r   )r   r-  r   rH   rp   r   s       r6   perpendicular_bisectorzSegment.perpendicular_bisector  sM    H ##DMM2=qd445BQwr4==11r7   c                 &    t        |d      }|ddgS )a:  The plot interval for the default geometric plot of the Segment gives
        values that will produce the full segment in a plot.

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> s1 = Segment(p1, p2)
        >>> s1.plot_interval()
        [t, 0, 1]

        TrW   r   r   r   r`   s      r6   r   zSegment.plot_interval2  s    4 ID)1ayr7   rZ   r   )r.   r   r   r   r0   r:   r   r   r   r   r-  r/  r   r   r7   r6   rp   rp   *  sQ    6n;5n=
)$V 0 02 0 02)Vr7   rp   c                   6    e Zd ZdZed        Zd Zed        Zy)LinearEntity2Da\  A base class for all linear entities (line, ray and segment)
    in a 2-dimensional Euclidean space.

    Attributes
    ==========

    p1
    p2
    coefficients
    slope
    points

    Notes
    =====

    This is an abstract class and is not meant to be instantiated.

    See Also
    ========

    sympy.geometry.entity.GeometryEntity

    c                     | j                   }|D cg c]  }|j                   }}|D cg c]  }|j                   }}t        |      t        |      t	        |      t	        |      fS c c}w c c}w )zwReturn a tuple (xmin, ymin, xmax, ymax) representing the bounding
        rectangle for the geometric figure.

        )r   r   r   minmax)r;   r  r   xsyss        r6   boundszLinearEntity2D.boundsh  sb      !aacc!! !aacc!!BR#b'3r733 "!s
   A)A.c                 v    t        || j                        }t        ||| j                  j                  z         S )a  Create a new Line perpendicular to this linear entity which passes
        through the point `p`.

        Parameters
        ==========

        p : Point

        Returns
        =======

        line : Line

        See Also
        ========

        sympy.geometry.line.LinearEntity.is_perpendicular, perpendicular_segment

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2, p3 = Point(0, 0), Point(2, 3), Point(-2, 2)
        >>> L = Line(p1, p2)
        >>> P = L.perpendicular_line(p3); P
        Line2D(Point2D(-2, 2), Point2D(-5, 4))
        >>> L.is_perpendicular(P)
        True

        In 2D, the first point of the perpendicular line is the
        point through which was required to pass; the second
        point is arbitrarily chosen. To get a line that explicitly
        uses a point in the line, create a line from the perpendicular
        segment from the line to the point:

        >>> Line(L.perpendicular_segment(p3))
        Line2D(Point2D(-2, 2), Point2D(4/13, 6/13))
        r   )r   rH   r   rA   r   r   s     r6   r   z!LinearEntity2D.perpendicular_lines  s5    N !//0 Aq4>>>>>??r7   c                     | j                   | j                  z
  j                  \  }}|dk(  rt        j                  S t        ||z        S )a  The slope of this linear entity, or infinity if vertical.

        Returns
        =======

        slope : number or SymPy expression

        See Also
        ========

        coefficients

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(3, 5)
        >>> l1 = Line(p1, p2)
        >>> l1.slope
        5/3

        >>> p3 = Point(0, 4)
        >>> l2 = Line(p1, p3)
        >>> l2.slope
        oo

        r   )r3   r4   r   r
   r   r!   )r;   r   r   s      r6   r   zLinearEntity2D.slope  s?    : ''DGG#))B7::2r7   N)r.   r   r   r   r   r8  r   r   r   r7   r6   r2  r2  P  s6    . 4 4+@Z  r7   r2  c                   8    e Zd ZdZddZddZed        Zd	dZy)
r   a3  An infinite line in space 2D.

    A line is declared with two distinct points or a point and slope
    as defined using keyword `slope`.

    Parameters
    ==========

    p1 : Point
    pt : Point
    slope : SymPy expression

    See Also
    ========

    sympy.geometry.point.Point

    Examples
    ========

    >>> from sympy import Line, Segment, Point
    >>> L = Line(Point(2,3), Point(3,5))
    >>> L
    Line2D(Point2D(2, 3), Point2D(3, 5))
    >>> L.points
    (Point2D(2, 3), Point2D(3, 5))
    >>> L.equation()
    -2*x + y + 1
    >>> L.coefficients
    (-2, 1, 1)

    Instantiate with keyword ``slope``:

    >>> Line(Point(0, 0), slope=0)
    Line2D(Point2D(0, 0), Point2D(1, 0))

    Instantiate with another linear object

    >>> s = Segment((0, 0), (0, 1))
    >>> Line(s).equation()
    x
    Nc                    t        |t              r0|t        d      t        j                  |j
                  ddi\  }}nt        |d      }||	 t        |d      }nZ|M|Kt        |      }|j                  du rd}d}nd}|}t        |j                  |z   |j                  |z   d	      }nt        d
      t        j                  | ||fi |S # t        t        t        f$ r t        t        d            w xY w)Nz,When p1 is a LinearEntity, pt should be Noner   r&   r   z
                    The 2nd argument was not a valid Point.
                    If it was a slope, enter it with keyword "slope".
                    Fr   r   )evaluatez,A 2nd Point or keyword "slope" must be used.)rK   r)   r-   r   r,   r   rj   rL   r%   r   	is_finiter   r   r2  r0   )r2   r3   r   r   r5   r4   dxdys           r6   r0   zLine2D.__new__  s   b,'~ !OPP//@a@FBrq!B>em21% 2:ENE%' rttby"$$)e<BKLL%%c2r<V<<' (J?   - "  s   C )C<c                 @   t        | j                        t        | j                        f}|D cg c](  }dj                  |j                  |j
                        * }}dj                  |d   dj                  |dd             }dj                  d|z  ||      S c c}w )	r  r  r  r   r  r   Nz<path fill-rule="evenodd" fill="{2}" stroke="#555555" stroke-width="{0}" opacity="0.6" d="{1}" marker-start="url(#markerReverseArrow)" marker-end="url(#markerArrow)"/>r  r  r
  s          r6   r  zLine2D._svg  s     477QtwwZ(49:q'..acc*::!!&)UZZqr
-CDW &L$

3		4 ;r  c                    | j                   \  }}|j                  |j                  k(  r,t        j                  t        j                  |j                   fS |j
                  |j
                  k(  r,t        j                  t        j                  |j
                   fS t        | j                  j
                  | j                  j
                  z
  | j                  j                  | j                  j                  z
  | j                  j                  | j                  j
                  z  | j                  j
                  | j                  j                  z  z
  fD cg c]  }t        |       c}      S c c}w )a  The coefficients (`a`, `b`, `c`) for `ax + by + c = 0`.

        See Also
        ========

        sympy.geometry.line.Line2D.equation

        Examples
        ========

        >>> from sympy import Point, Line
        >>> from sympy.abc import x, y
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> l = Line(p1, p2)
        >>> l.coefficients
        (-3, 5, 0)

        >>> p3 = Point(x, y)
        >>> l2 = Line(p1, p3)
        >>> l2.coefficients
        (-y, x, 0)

        )
r   r   r
   Oner   r   tupler3   r4   r!   )r;   r3   r4   is       r6   coefficientszLine2D.coefficients"  s    2 B44244<EE166BDD5))TTRTT\FFAEEBDD5))wwyy47799,wwyy47799,wwyy*TWWYYtwwyy-@@BCahqk C D 	D Cs   E.c                 0   t        |d      }t        |d      }| j                  \  }}|j                  |j                  k(  r||j                  z
  S |j                  |j                  k(  r||j                  z
  S | j                  \  }}}||z  ||z  z   |z   S )au  The equation of the line: ax + by + c.

        Parameters
        ==========

        x : str, optional
            The name to use for the x-axis, default value is 'x'.
        y : str, optional
            The name to use for the y-axis, default value is 'y'.

        Returns
        =======

        equation : SymPy expression

        See Also
        ========

        sympy.geometry.line.Line2D.coefficients

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(1, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.equation()
        -3*x + 4*y + 3

        TrW   )r   r   r   r   rF  )r;   r   r   r3   r4   r   r   r   s           r6   r   zLine2D.equationE  s    > AD!AD!B44244<rtt8OTTRTT\rtt8O##1asQqSy1}r7   NNr  )r   r   )	r.   r   r   r   r0   r  r   rF  r   r   r7   r6   r   r     s.    )T=>4*  D  DD(r7   r   c                   >    e Zd ZdZddZed        Zed        Zd Zy)r   ap  
    A Ray is a semi-line in the space with a source point and a direction.

    Parameters
    ==========

    p1 : Point
        The source of the Ray
    p2 : Point or radian value
        This point determines the direction in which the Ray propagates.
        If given as an angle it is interpreted in radians with the positive
        direction being ccw.

    Attributes
    ==========

    source
    xdirection
    ydirection

    See Also
    ========

    sympy.geometry.point.Point, Line

    Examples
    ========

    >>> from sympy import Point, pi, Ray
    >>> r = Ray(Point(2, 3), Point(3, 5))
    >>> r
    Ray2D(Point2D(2, 3), Point2D(3, 5))
    >>> r.points
    (Point2D(2, 3), Point2D(3, 5))
    >>> r.source
    Point2D(2, 3)
    >>> r.xdirection
    oo
    >>> r.ydirection
    oo
    >>> r.slope
    2
    >>> Ray(Point(0, 0), angle=pi/4).slope
    1

    Nc                 8   t        |d      }|!|	 t        |d      }||k(  rt        d      ||t        |      }t        |      }d }||j                  r|j                  dk(  r>|j                  dk(  r|t        dd      z   }nk|j                  dk(  r\|t        dd      z   }nL|j                  dk(  r=|j                  dk(  r|t        dd      z   }n|j                  dk(  r|t        dd      z   }|*|t        j                  z  }n|dt        j                  z  z  }|sd|z  t        j                  z  }t        d|k  |dk        }t        d|ft        dt        |dz  d      fd	      d
f      }	t        t        |       |ft        dt        |d      fdt        |d      ft        |      d
f      d
f      }
|t        |	|
      z   }nt        d      t!        j"                  | ||fi |S # t        t        t        f$ r t        t	        d            w xY w)Nr&   r   z
                    The 2nd argument was not a valid Point; if
                    it was meant to be an angle it should be
                    given with keyword "angle".z#A Ray requires two distinct points.r   r   r   r@   )r   TTz,A 2nd point or keyword "angle" must be used.)r   rj   rL   r-   r%   r   r   is_Rationalqr   r
   Pir   r   r	   r   r2  r0   )r2   r3   r   angler5   r4   r   r   leftr   r   s              r6   r0   zRay2D.__new__  s   21>em521% Rx !FGG2:ENE% AB}==ssax33!8!#eAqk!1BSSAX!#eArl!2B33!8!#eAqk!1BSSAX!#eBl!2B:IAQqttV$aCH1q5!a%(r4j9aAE15F	+RTX*YZAwo	1bAh-"bQRTUhZ]^_Z`bfYg0hjn/op%1+%KLL%%c2r<V<<K (J? 5  -3 "4 5 55s   G0 0)Hc                    | j                   j                  | j                  j                  k  rt        j                  S | j                   j                  | j                  j                  k(  rt        j
                  S t        j                  S )a  The x direction of the ray.

        Positive infinity if the ray points in the positive x direction,
        negative infinity if the ray points in the negative x direction,
        or 0 if the ray is vertical.

        See Also
        ========

        ydirection

        Examples
        ========

        >>> from sympy import Point, Ray
        >>> p1, p2, p3 = Point(0, 0), Point(1, 1), Point(0, -1)
        >>> r1, r2 = Ray(p1, p2), Ray(p1, p3)
        >>> r1.xdirection
        oo
        >>> r2.xdirection
        0

        r3   r   r4   r
   r   r   NegativeInfinityrG   s    r6   
xdirectionzRay2D.xdirection  S    2 7799twwyy ::WWYY$''))#66M%%%r7   c                    | j                   j                  | j                  j                  k  rt        j                  S | j                   j                  | j                  j                  k(  rt        j
                  S t        j                  S )a  The y direction of the ray.

        Positive infinity if the ray points in the positive y direction,
        negative infinity if the ray points in the negative y direction,
        or 0 if the ray is horizontal.

        See Also
        ========

        xdirection

        Examples
        ========

        >>> from sympy import Point, Ray
        >>> p1, p2, p3 = Point(0, 0), Point(-1, -1), Point(-1, 0)
        >>> r1, r2 = Ray(p1, p2), Ray(p1, p3)
        >>> r1.ydirection
        -oo
        >>> r2.ydirection
        0

        r3   r   r4   r
   r   r   rR  rG   s    r6   
ydirectionzRay2D.ydirection  rT  r7   c                    t        d | |fD              st        d      t        t        t	        | j
                  j                               }t        t        t	        |j
                  j                               }||z  dk  r:|dk  rdt        j                  z  |z   n|}|dk  rdt        j                  z  |z   n|}||z
  S )a  Return the angle by which r2 must be rotated so it faces the same
        direction as r1.

        Parameters
        ==========

        r1 : Ray2D
        r2 : Ray2D

        Returns
        =======

        angle : angle in radians (ccw angle is positive)

        See Also
        ========

        LinearEntity.angle_between

        Examples
        ========

        >>> from sympy import Ray, pi
        >>> r1 = Ray((0, 0), (1, 0))
        >>> r2 = r1.rotate(-pi/2)
        >>> angle = r1.closing_angle(r2); angle
        pi/2
        >>> r2.rotate(angle).direction.unit == r1.direction.unit
        True
        >>> r2.closing_angle(r1)
        -pi/2
        c              3   <   K   | ]  }t        |t                y wrZ   )rK   r   )r\   rs     r6   r^   z&Ray2D.closing_angle.<locals>.<genexpr>,	  s     :A:a':s   z%Both arguments must be Ray2D objects.r   r&   )	allrL   r   r$  reversedrA   r   r
   rM  )r1r2a1a2s       r6   closing_anglezRay2D.closing_angle	  s    B :"b:: CDDD",,"3"3456D",,"3"3456b519 "Q144"BB "Q144"BBBwr7   rH  )	r.   r   r   r   r0   r   rS  rW  ra  r   r7   r6   r   r   p  s;    -\*=X & &> & &>,r7   r   c                       e Zd ZdZd ZddZy)r  a  A line segment in 2D space.

    Parameters
    ==========

    p1 : Point
    p2 : Point

    Attributes
    ==========

    length : number or SymPy expression
    midpoint : Point

    See Also
    ========

    sympy.geometry.point.Point, Line

    Examples
    ========

    >>> from sympy import Point, Segment
    >>> Segment((1, 0), (1, 1)) # tuples are interpreted as pts
    Segment2D(Point2D(1, 0), Point2D(1, 1))
    >>> s = Segment(Point(4, 3), Point(1, 1)); s
    Segment2D(Point2D(4, 3), Point2D(1, 1))
    >>> s.points
    (Point2D(4, 3), Point2D(1, 1))
    >>> s.slope
    2/3
    >>> s.length
    sqrt(13)
    >>> s.midpoint
    Point2D(5/2, 2)

    c                 t    t        |d      }t        |d      }||k(  r|S t        j                  | ||fi |S )Nr&   r   )r   r2  r0   r1   s       r6   r0   zSegment2D.__new__`	  @    21218I%%c2r<V<<r7   c                 @   t        | j                        t        | j                        f}|D cg c](  }dj                  |j                  |j
                        * }}dj                  |d   dj                  |dd             }dj                  d|z  ||      S c c}w )	r  r  r  r   r  r   Nza<path fill-rule="evenodd" fill="{2}" stroke="#555555" stroke-width="{0}" opacity="0.6" d="{1}" />r  r  r
  s          r6   r  zSegment2D._svgi	  s     477QtwwZ(49:q'..acc*::!!&)UZZqr
-CD:
&L$

3	4 ;r  Nr  )r.   r   r   r   r0   r  r   r7   r6   r  r  :	  s    $J=4r7   r  c                   :    e Zd ZdZd ZdZed        Zed        Zy)LinearEntity3Da   An base class for all linear entities (line, ray and segment)
    in a 3-dimensional Euclidean space.

    Attributes
    ==========

    p1
    p2
    direction_ratio
    direction_cosine
    points

    Notes
    =====

    This is a base class and is not meant to be instantiated.
    c                     t        |d      }t        |d      }||k(  rt        d| j                  z        t        j                  | ||fi |S )Nr   r   r+   )r   r-   r.   r   r0   r1   s       r6   r0   zLinearEntity3D.__new__	  sX    RQRQ883<<GI I %%c2r<V<<r7   r   c                 B    | j                   \  }}|j                  |      S )a\  The direction ratio of a given line in 3D.

        See Also
        ========

        sympy.geometry.line.Line3D.equation

        Examples
        ========

        >>> from sympy import Point3D, Line3D
        >>> p1, p2 = Point3D(0, 0, 0), Point3D(5, 3, 1)
        >>> l = Line3D(p1, p2)
        >>> l.direction_ratio
        [5, 3, 1]
        )r   direction_ratior;   r3   r4   s      r6   rj  zLinearEntity3D.direction_ratio	  s"    $ B!!"%%r7   c                 B    | j                   \  }}|j                  |      S )a  The normalized direction ratio of a given line in 3D.

        See Also
        ========

        sympy.geometry.line.Line3D.equation

        Examples
        ========

        >>> from sympy import Point3D, Line3D
        >>> p1, p2 = Point3D(0, 0, 0), Point3D(5, 3, 1)
        >>> l = Line3D(p1, p2)
        >>> l.direction_cosine
        [sqrt(35)/7, 3*sqrt(35)/35, sqrt(35)/35]
        >>> sum(i**2 for i in _)
        1
        )r   direction_cosinerk  s      r6   rm  zLinearEntity3D.direction_cosine	  s"    ( B""2&&r7   N)	r.   r   r   r   r0   rH   r   rj  rm  r   r7   r6   rg  rg  }	  s:    "= & &( ' 'r7   rg  c                   2     e Zd ZdZddZddZ fdZ xZS )r   ah  An infinite 3D line in space.

    A line is declared with two distinct points or a point and direction_ratio
    as defined using keyword `direction_ratio`.

    Parameters
    ==========

    p1 : Point3D
    pt : Point3D
    direction_ratio : list

    See Also
    ========

    sympy.geometry.point.Point3D
    sympy.geometry.line.Line
    sympy.geometry.line.Line2D

    Examples
    ========

    >>> from sympy import Line3D, Point3D
    >>> L = Line3D(Point3D(2, 3, 4), Point3D(3, 5, 1))
    >>> L
    Line3D(Point3D(2, 3, 4), Point3D(3, 5, 1))
    >>> L.points
    (Point3D(2, 3, 4), Point3D(3, 5, 1))
    c                    t        |t              r|t        d      |j                  \  }}nt	        |d      }|t        |      dk(  rt	        |d      }nYt        |      dk(  r@|>t        |j                  |d   z   |j                  |d   z   |j                  |d   z         }nt        d      t        j                  | ||fi |S )Nz)if p1 is a LinearEntity, pt must be None.r   r   r   r   r&   z6A 2nd Point or keyword "direction_ratio" must be used.)rK   rg  r-   r   r   r/   r   r   r   zr0   r2   r3   r   rj  r5   s        r6   r0   zLine3D.__new__	  s    b.)~ !LMMWWFBrq!B>c/2a7rq!B!Q&2: 22BDD?1;M4M 224B  ( ) ) %%c2r<V<<r7   c           	         |||dfD cg c]  }t        |d       c}\  }}}}| j                  \  }}|j                  |      \  }}	}
|\  }}}| |z  |z   |z
  |	 |z  |z   |z
  |
 |z  |z   |z
  g}t        |      D ];  \  }}|j	                  |      st        ||   |      d   }|j                  |        n t        |D cg c]%  }|j                  |      j                         d   ' c} S c c}w c c}w )a.  Return the equations that define the line in 3D.

        Parameters
        ==========

        x : str, optional
            The name to use for the x-axis, default value is 'x'.
        y : str, optional
            The name to use for the y-axis, default value is 'y'.
        z : str, optional
            The name to use for the z-axis, default value is 'z'.

        Returns
        =======

        equation : Tuple of simultaneous equations

        Examples
        ========

        >>> from sympy import Point3D, Line3D, solve
        >>> from sympy.abc import x, y, z
        >>> p1, p2 = Point3D(1, 0, 0), Point3D(5, 3, 0)
        >>> l1 = Line3D(p1, p2)
        >>> eq = l1.equation(x, y, z); eq
        (-3*x + 4*y + 3, z)
        >>> solve(eq.subs(z, 0), (x, y, z))
        {x: 4*y/3 + 1}
        kTrW   r   )
r   r   rj  	enumeratehasr"   r   r   r   as_numer_denom)r;   r   r   rp  rE  rs  r3   r4   r   r   d3x1y1z1eqsekks                    r6   r   zLine3D.equation	  s   < 78As^Dgad+D
1aB''+
B
Bs1uqy2~s1uqy2~s1uqy2~>cN 	DAquuQx3q61%a(
		
 #FQqvva}335a8FGG E Gs   C2*C7c                    ddl m} t        |t        t        f      r	 t        |      }t        |t
              rt        | !  |      S t        |t              r| |k(  rt        j                  S | j                  |      rt        | !  |j                        S t        | j                        }t        |j                        }|j!                  |      } || j                  |      }|j                  j                  |      S t        ||      r|j                  |       S | dt#        |       d}t%        |      # t        $ r Y w xY w)a  
        Finds the shortest distance between a line and another object.

        Parameters
        ==========

        Point3D, Line3D, Plane, tuple, list

        Returns
        =======

        distance

        Notes
        =====

        This method accepts only 3D entities as it's parameter

        Tuples and lists are converted to Point3D and therefore must be of
        length 3, 2 or 1.

        NotImplementedError is raised if `other` is not an instance of one
        of the specified classes: Point3D, Line3D, or Plane.

        Examples
        ========

        >>> from sympy.geometry import Line3D
        >>> l1 = Line3D((0, 0, 0), (0, 0, 1))
        >>> l2 = Line3D((0, 1, 0), (1, 1, 1))
        >>> l1.distance(l2)
        1

        The computed distance may be symbolic, too:

        >>> from sympy.abc import x, y
        >>> l1 = Line3D((0, 0, 0), (0, 0, 1))
        >>> l2 = Line3D((0, x, 0), (y, x, 1))
        >>> l1.distance(l2)
        Abs(x*y)/Abs(sqrt(y**2))

        r   )Plane)r3   normal_vectorz
 has type z, which is unsupported)planer  rK   rD  r$  r   r-   superr   r   r
   r   r   r3   r   rj  crosstyperj   )	r;   r<   r  self_directionother_directionnormalplane_through_selfmsgr   s	           r6   r   zLine3D.distance#
  s%   X 	!eeT]+ eW%7#E**eV$u}vv&w'11 $D$8$89N$U%:%:;O#))/:F!&$''!H88$$%788eU#>>$''z$u+.DE!#&&/  s   D; ;	EENr   )r   r   rp  )r.   r   r   r   r0   r   r   __classcell__)r   s   @r6   r   r   	  s     :=$)HVH' H'r7   r   c                   H    e Zd ZdZddZed        Zed        Zed        Zy)r   a#  
    A Ray is a semi-line in the space with a source point and a direction.

    Parameters
    ==========

    p1 : Point3D
        The source of the Ray
    p2 : Point or a direction vector
    direction_ratio: Determines the direction in which the Ray propagates.


    Attributes
    ==========

    source
    xdirection
    ydirection
    zdirection

    See Also
    ========

    sympy.geometry.point.Point3D, Line3D


    Examples
    ========

    >>> from sympy import Point3D, Ray3D
    >>> r = Ray3D(Point3D(2, 3, 4), Point3D(3, 5, 0))
    >>> r
    Ray3D(Point3D(2, 3, 4), Point3D(3, 5, 0))
    >>> r.points
    (Point3D(2, 3, 4), Point3D(3, 5, 0))
    >>> r.source
    Point3D(2, 3, 4)
    >>> r.xdirection
    oo
    >>> r.ydirection
    oo
    >>> r.direction_ratio
    [1, 2, -4]

    Nc                    t        |t              r|t        d      |j                  \  }}nt	        |d      }|t        |      dk(  rt	        |d      }nbt        |      dk(  r@|>t        |j                  |d   z   |j                  |d   z   |j                  |d   z         }nt        t        d            t        j                  | ||fi |S )Nz(If p1 is a LinearEntity, pt must be Noner   r   r   r   r&   zT
                A 2nd Point or keyword "direction_ratio" must be used.
            )rK   rg  r-   r   r   r/   r   r   r   rp  r%   r0   rq  s        r6   r0   zRay3D.__new__
  s    b.)~ !KLLWWFBrq!B>c/2a7rq!B!Q&2: 22BDD?1;M4M 224B Z )    %%c2r<V<<r7   c                    | j                   j                  | j                  j                  k  rt        j                  S | j                   j                  | j                  j                  k(  rt        j
                  S t        j                  S )a/  The x direction of the ray.

        Positive infinity if the ray points in the positive x direction,
        negative infinity if the ray points in the negative x direction,
        or 0 if the ray is vertical.

        See Also
        ========

        ydirection

        Examples
        ========

        >>> from sympy import Point3D, Ray3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(1, 1, 1), Point3D(0, -1, 0)
        >>> r1, r2 = Ray3D(p1, p2), Ray3D(p1, p3)
        >>> r1.xdirection
        oo
        >>> r2.xdirection
        0

        rQ  rG   s    r6   rS  zRay3D.xdirection
  rT  r7   c                    | j                   j                  | j                  j                  k  rt        j                  S | j                   j                  | j                  j                  k(  rt        j
                  S t        j                  S )a5  The y direction of the ray.

        Positive infinity if the ray points in the positive y direction,
        negative infinity if the ray points in the negative y direction,
        or 0 if the ray is horizontal.

        See Also
        ========

        xdirection

        Examples
        ========

        >>> from sympy import Point3D, Ray3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(-1, -1, -1), Point3D(-1, 0, 0)
        >>> r1, r2 = Ray3D(p1, p2), Ray3D(p1, p3)
        >>> r1.ydirection
        -oo
        >>> r2.ydirection
        0

        rV  rG   s    r6   rW  zRay3D.ydirection
  rT  r7   c                    | j                   j                  | j                  j                  k  rt        j                  S | j                   j                  | j                  j                  k(  rt        j
                  S t        j                  S )aY  The z direction of the ray.

        Positive infinity if the ray points in the positive z direction,
        negative infinity if the ray points in the negative z direction,
        or 0 if the ray is horizontal.

        See Also
        ========

        xdirection

        Examples
        ========

        >>> from sympy import Point3D, Ray3D
        >>> p1, p2, p3 = Point3D(0, 0, 0), Point3D(-1, -1, -1), Point3D(-1, 0, 0)
        >>> r1, r2 = Ray3D(p1, p2), Ray3D(p1, p3)
        >>> r1.ydirection
        -oo
        >>> r2.ydirection
        0
        >>> r2.zdirection
        0

        )r3   rp  r4   r
   r   r   rR  rG   s    r6   
zdirectionzRay3D.zdirection
  sS    6 7799twwyy ::WWYY$''))#66M%%%r7   r  )	r.   r   r   r   r0   r   rS  rW  r  r   r7   r6   r   r   n
  sI    ,Z=& & &> & &> & &r7   r   c                       e Zd ZdZd Zy)r  a  A line segment in a 3D space.

    Parameters
    ==========

    p1 : Point3D
    p2 : Point3D

    Attributes
    ==========

    length : number or SymPy expression
    midpoint : Point3D

    See Also
    ========

    sympy.geometry.point.Point3D, Line3D

    Examples
    ========

    >>> from sympy import Point3D, Segment3D
    >>> Segment3D((1, 0, 0), (1, 1, 1)) # tuples are interpreted as pts
    Segment3D(Point3D(1, 0, 0), Point3D(1, 1, 1))
    >>> s = Segment3D(Point3D(4, 3, 9), Point3D(1, 1, 7)); s
    Segment3D(Point3D(4, 3, 9), Point3D(1, 1, 7))
    >>> s.points
    (Point3D(4, 3, 9), Point3D(1, 1, 7))
    >>> s.length
    sqrt(17)
    >>> s.midpoint
    Point3D(5/2, 2, 8)

    c                 t    t        |d      }t        |d      }||k(  r|S t        j                  | ||fi |S )Nr   r   )r   rg  r0   r1   s       r6   r0   zSegment3D.__new__6  rd  r7   N)r.   r   r   r   r0   r   r7   r6   r  r    s    "F=r7   r  )Hr   sympy.core.containersr   sympy.core.evalfr   sympy.core.exprr   sympy.core.numbersr   r   r   sympy.core.relationalr	   sympy.core.singletonr
   sympy.core.sortingr   sympy.core.symbolr   r   r   sympy.core.sympifyr   $sympy.functions.elementary.piecewiser   (sympy.functions.elementary.trigonometricr   r   r   r   entityr   r   
exceptionsr   r   r   r   utilr   r   sympy.logic.boolalgr   sympy.matricesr   sympy.sets.setsr   sympy.simplify.simplifyr!   sympy.solvers.solversr"   sympy.solvers.solvesetr#   sympy.utilities.miscr$   r%   r   rangerb   r   r)   r   r   rp   r2  r   r   r  rg  r   r   r  )rE  s   0r6   <module>r     s?  & (    2 2 $ " & C C & : R R / % ! $ # ! ( , ' 0 8  &+1X.l.1`; `F!g< gTh, hVcl cL	p\ pfj^T jZGNC GT@4 @4FH'\ H'Vc'^T c'La&NC a&H+= +=GW /s   +E