(self, p, prec=None)
return [Line(pt, slope=s) for pt,s in zip(points, slopes)]
Normal lines between `p` and the ellipse.

        Parameters
        ==========

        p : Point

        Returns
        =======

        normal_lines : list with 1, 2 or 4 Lines

        Examples
        ========

        >>> from sympy import Line, Point, Ellipse
        >>> e = Ellipse((0, 0), 2, 3)
        >>> c = e.center
        >>> e.normal_lines(c + Point(1, 0))
        [Line(Point(0, 0), Point(1, 0))]
        >>> e.normal_lines(c)
        [Line(Point(0, 0), Point(0, 1)), Line(Point(0, 0), Point(1, 0))]

        Off-axis points require the solution of a quartic equation. This
        often leads to very large expressions that may be of little practical
        use. An approximate solution of `prec` digits can be obtained by
        passing in the desired value:

        >>> e.normal_lines((3, 3), prec=2)
        [Line(Point(-38/47, -85/31), Point(9/47, -21/17)),
        Line(Point(19/13, -43/21), Point(32/13, -8/3))]

        Whereas the above solution has an operation count of 12, the exact
        solution has an operation count of 2020.
Normal lines between `p` and the ellipse.
Normal lines between p and the ellipse .
def normal_lines(self, p, prec=None):
        """Normal lines between `p` and the ellipse.

        Parameters
        ==========

        p : Point

        Returns
        =======

        normal_lines : list with 1, 2 or 4 Lines

        Examples
        ========

        >>> from sympy import Line, Point, Ellipse
        >>> e = Ellipse((0, 0), 2, 3)
        >>> c = e.center
        >>> e.normal_lines(c + Point(1, 0))
        [Line(Point(0, 0), Point(1, 0))]
        >>> e.normal_lines(c)
        [Line(Point(0, 0), Point(0, 1)), Line(Point(0, 0), Point(1, 0))]

        Off-axis points require the solution of a quartic equation. This
        often leads to very large expressions that may be of little practical
        use. An approximate solution of `prec` digits can be obtained by
        passing in the desired value:

        >>> e.normal_lines((3, 3), prec=2)
        [Line(Point(-38/47, -85/31), Point(9/47, -21/17)),
        Line(Point(19/13, -43/21), Point(32/13, -8/3))]

        Whereas the above solution has an operation count of 12, the exact
        solution has an operation count of 2020.
        """
        p = Point(p)

        # XXX change True to something like self.angle == 0 if the arbitrarily
        # rotated ellipse is introduced.
        # https://github.com/sympy/sympy/issues/2815)
        if True:
            rv = []
            if p.x == self.center.x:
                rv.append(Line(self.center, slope=oo))
            if p.y == self.center.y:
                rv.append(Line(self.center, slope=0))
            if rv:
                # at these special orientations of p either 1 or 2 normals
                # exist and we are done
                return rv

        # find the 4 normal points and construct lines through them with
        # the corresponding slope
        x, y = Dummy('x', real=True), Dummy('y', real=True)
        eq = self.equation(x, y)
        dydx = idiff(eq, y, x)
        norm = -1/dydx
        slope = Line(p, (x, y)).slope
        seq = slope - norm
        points = []
        if prec is not None:
            yis = solve(seq, y)[0]
            xeq = eq.subs(y, yis).as_numer_denom()[0].expand()
            try:
                iv = list(zip(*Poly(xeq).intervals()))[0]
                # bisection is safest here since other methods may miss root
                xsol = [S(nroot(lambdify(x, xeq), i, solver="anderson"))
                    for i in iv]
                points = [Point(i, solve(eq.subs(x, i), y)[0]).n(prec)
                    for i in xsol]
            except PolynomialError:
                pass
        if not points:
            points = solve((seq, eq), (x, y))
            # complicated expressions may not be decidably real so evaluate to
            # check whether they are real or not
            points = [Point(i).n(prec) if prec is not None else Point(i)
                      for i in points if all(j.n(2).is_real for j in i)]
        slopes = [norm.subs(zip((x, y), pt.args)) for pt in points]
        if prec is not None:
            slopes = [i.n(prec) if i not in (-oo, oo, zoo) else i
                for i in slopes]
        return [Line(pt, slope=s) for pt,s in zip(points, slopes)]
def normal_lines ( self , p , prec = None ) : p = Point ( p ) # XXX change True to something like self.angle == 0 if the arbitrarily # rotated ellipse is introduced. # https://github.com/sympy/sympy/issues/2815) if True : rv = [ ] if p . x == self . center . x : rv . append ( Line ( self . center , slope = oo ) ) if p . y == self . center . y : rv . append ( Line ( self . center , slope = 0 ) ) if rv : # at these special orientations of p either 1 or 2 normals # exist and we are done return rv # find the 4 normal points and construct lines through them with # the corresponding slope x , y = Dummy ( 'x' , real = True ) , Dummy ( 'y' , real = True ) eq = self . equation ( x , y ) dydx = idiff ( eq , y , x ) norm = - 1 / dydx slope = Line ( p , ( x , y ) ) . slope seq = slope - norm points = [ ] if prec is not None : yis = solve ( seq , y ) [ 0 ] xeq = eq . subs ( y , yis ) . as_numer_denom ( ) [ 0 ] . expand ( ) try : iv = list ( zip ( * Poly ( xeq ) . intervals ( ) ) ) [ 0 ] # bisection is safest here since other methods may miss root xsol = [ S ( nroot ( lambdify ( x , xeq ) , i , solver = "anderson" ) ) for i in iv ] points = [ Point ( i , solve ( eq . subs ( x , i ) , y ) [ 0 ] ) . n ( prec ) for i in xsol ] except PolynomialError : pass if not points : points = solve ( ( seq , eq ) , ( x , y ) ) # complicated expressions may not be decidably real so evaluate to # check whether they are real or not points = [ Point ( i ) . n ( prec ) if prec is not None else Point ( i ) for i in points if all ( j . n ( 2 ) . is_real for j in i ) ] slopes = [ norm . subs ( zip ( ( x , y ) , pt . args ) ) for pt in points ] if prec is not None : slopes = [ i . n ( prec ) if i not in ( - oo , oo , zoo ) else i for i in slopes ] return [ Line ( pt , slope = s ) for pt , s in zip ( points , slopes ) ]