Example #1
0
        def plot_arc(radius, p, q, **opts):
            # TODO: THIS SHOULD USE THE EXISTING PLOT OF ARCS!
            # plot the arc from p to q differently depending on the type of self
            p = ZZ(p)
            q = ZZ(q)
            t = var('t')
            if p - q in [1, -1]:

                def f(t):
                    return (radius * cos(t), radius * sin(t))

                (p, q) = sorted([p, q])
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                return parametric_plot(f(t), (t, angle_q, angle_p), **opts)
            if self.type() == 'A':
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                if angle_p < angle_q:
                    angle_p += 2 * pi
                internal_angle = angle_p - angle_q
                if internal_angle > pi:
                    (angle_p, angle_q) = (angle_q + 2 * pi, angle_p)
                    internal_angle = angle_p - angle_q
                angle_center = (angle_p + angle_q) / 2
                hypotenuse = radius / cos(internal_angle / 2)
                radius_arc = hypotenuse * sin(internal_angle / 2)
                center = (hypotenuse * cos(angle_center),
                          hypotenuse * sin(angle_center))
                center_angle_p = angle_p + pi / 2
                center_angle_q = angle_q + 3 * pi / 2

                def f(t):
                    return (radius_arc * cos(t) + center[0],
                            radius_arc * sin(t) + center[1])

                return parametric_plot(f(t),
                                       (t, center_angle_p, center_angle_q),
                                       **opts)
            elif self.type() == 'D':
                if p >= q:
                    q += self.r()
                px = -2 * pi * p / self.r() + pi / 2
                qx = -2 * pi * q / self.r() + pi / 2
                arc_radius = (px - qx) / 2
                arc_center = qx + arc_radius

                def f(t):
                    return exp(I * ((cos(t) + I * sin(t)) * arc_radius +
                                    arc_center)) * radius

                return parametric_plot((real_part(f(t)), imag_part(f(t))),
                                       (t, 0, pi), **opts)
Example #2
0
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: HyperbolicPlane().PD().get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
        """
        opts = dict([('axes', False), ('aspect_ratio', 1)])
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        # Check to see if it's a line
        if bool(real(bd_1)*imag(bd_2) - real(bd_2)*imag(bd_1))**2 < EPSILON:
            from sage.plot.line import line
            pic = line([(real(bd_1),imag(bd_1)),(real(bd_2),imag(bd_2))],
                       **opts)
        else:
            # If we are here, we know it's not a line
            # So we compute the center and radius of the circle
            center = (1/(real(bd_1)*imag(bd_2) - real(bd_2)*imag(bd_1)) *
                ((imag(bd_2)-imag(bd_1)) + (real(bd_1)-real(bd_2))*I))
            radius = RR(abs(bd_1 - center)) # abs is Euclidean distance
            # Now we calculate the angles for the parametric plot
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            if theta2 < theta1:
                theta1, theta2 = theta2, theta1
            from sage.calculus.var import var
            from sage.plot.plot import parametric_plot
            x = var('x')
            mid = (theta1 + theta2)/2.0
            if (radius*cos(mid) + real(center))**2 + \
               (radius*sin(mid) + imag(center))**2 > 1.0:
                # Swap theta1 and theta2
                tmp = theta1 + 2*pi
                theta1 = theta2
                theta2 = tmp
                pic = parametric_plot((radius*cos(x) + real(center),
                                       radius*sin(x) + imag(center)),
                                      (x, theta1, theta2), **opts)

            else:
                pic = parametric_plot((radius*cos(x) + real(center),
                                   radius*sin(x) + imag(center)),
                                  (x, theta1, theta2), **opts)
        if boundary:
            bd_pic = self._model.get_background_graphic()
            pic = bd_pic + pic
        return pic
Example #3
0
        def plot_arc(radius, p, q, **opts):
            # TODO: THIS SHOULD USE THE EXISTING PLOT OF ARCS!
            # plot the arc from p to q differently depending on the type of self
            p = ZZ(p)
            q = ZZ(q)
            t = var('t')
            if p - q in [1, -1]:
                def f(t):
                    return (radius * cos(t), radius * sin(t))
                (p, q) = sorted([p, q])
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                return parametric_plot(f(t), (t, angle_q, angle_p), **opts)
            if self.type() == 'A':
                angle_p = vertex_to_angle(p)
                angle_q = vertex_to_angle(q)
                if angle_p < angle_q:
                    angle_p += 2 * pi
                internal_angle = angle_p - angle_q
                if internal_angle > pi:
                    (angle_p, angle_q) = (angle_q + 2 * pi, angle_p)
                    internal_angle = angle_p - angle_q
                angle_center = (angle_p+angle_q) / 2
                hypotenuse = radius / cos(internal_angle / 2)
                radius_arc = hypotenuse * sin(internal_angle / 2)
                center = (hypotenuse * cos(angle_center),
                          hypotenuse * sin(angle_center))
                center_angle_p = angle_p + pi / 2
                center_angle_q = angle_q + 3 * pi / 2

                def f(t):
                    return (radius_arc * cos(t) + center[0],
                            radius_arc * sin(t) + center[1])
                return parametric_plot(f(t), (t, center_angle_p,
                                              center_angle_q), **opts)
            elif self.type() == 'D':
                if p >= q:
                    q += self.r()
                px = -2 * pi * p / self.r() + pi / 2
                qx = -2 * pi * q / self.r() + pi / 2
                arc_radius = (px - qx) / 2
                arc_center = qx + arc_radius

                def f(t):
                    return exp(I * ((cos(t) + I * sin(t)) *
                                    arc_radius + arc_center)) * radius
                return parametric_plot((real_part(f(t)), imag_part(f(t))),
                                       (t, 0, pi), **opts)
Example #4
0
def _circ_arc(t0, t1, c, r, num_pts=500):
    r""" Circular arc
    INPUTS:
    - ''t0'' -- starting parameter
    - ''t1'' -- ending parameter
    - ''c''  -- center point of the circle
    - ''r''  -- radius of circle
    - ''num_pts''  -- (default 100) number of points on polygon
    OUTPUT:
    - ''ca'' -- a polygonal approximation of a circular arc centered
    at c and radius r, starting at t0 and ending at t1


    EXAMPLES::

        sage: ca=_circ_arc(0.1,0.2,0.0,1.0,100)

    """
    from sage.plot.plot import parametric_plot
    from sage.functions.trig import cos, sin
    from sage.all import var

    t00 = t0
    t11 = t1
    ## To make sure the line is correct we reduce all arguments to the same branch,
    ## e.g. [0,2pi]
    pi = RR.pi()
    while t00 < 0.0:
        t00 = t00 + RR(2.0 * pi)
    while t11 < 0:
        t11 = t11 + RR(2.0 * pi)
    while t00 > 2 * pi:
        t00 = t00 - RR(2.0 * pi)
    while t11 > 2 * pi:
        t11 = t11 - RR(2.0 * pi)

    xc = CC(c).real()
    yc = CC(c).imag()
    # L0 =
    # [[RR(r*cos(t00+i*(t11-t00)/num_pts))+xc,RR(r*sin(t00+i*(t11-t00)/num_pts))+yc]
    # for i in range(0 ,num_pts)]
    t = var("t")
    if t11 > t00:
        ca = parametric_plot((r * cos(t) + xc, r * sin(t) + yc), (t, t00, t11))
    else:
        ca = parametric_plot((r * cos(t) + xc, r * sin(t) + yc), (t, t11, t00))
    return ca
Example #5
0
    def show(self, boundary=True, **options):
        r"""
        Plot ``self``.

        EXAMPLES::

            sage: HyperbolicPlane().UHP().get_geodesic(0, 1).show()
            Graphics object consisting of 2 graphics primitives
        """
        opts = {'axes': False, 'aspect_ratio': 1}
        opts.update(self.graphics_options())
        opts.update(options)
        end_1, end_2 = [CC(k.coordinates()) for k in self.endpoints()]
        bd_1, bd_2 = [CC(k.coordinates()) for k in self.ideal_endpoints()]
        if (abs(real(end_1) - real(end_2)) < EPSILON) \
                or CC(infinity) in [end_1, end_2]: #on same vertical line
            # If one of the endpoints is infinity, we replace it with a
            # large finite  point
            if end_1 == CC(infinity):
                end_1 = (real(end_2), (imag(end_2) + 10))
                end_2 = (real(end_2), imag(end_2))
            elif end_2 == CC(infinity):
                end_2 = (real(end_1), (imag(end_1) + 10))
                end_1 = (real(end_1), imag(end_1))
            from sage.plot.line import line
            pic = line((end_1, end_2), **opts)
            if boundary:
                cent = min(bd_1, bd_2)
                bd_dict = {'bd_min': cent - 3, 'bd_max': cent + 3}
                bd_pic = self._model.get_background_graphic(**bd_dict)
                pic = bd_pic + pic
                return pic
        else:
            center = (bd_1 + bd_2)/2 # Circle center
            radius = abs(bd_1 - bd_2)/2
            theta1 = CC(end_1 - center).arg()
            theta2 = CC(end_2 - center).arg()
            if abs(theta1 - theta2) < EPSILON:
                theta2 += pi
            [theta1, theta2] = sorted([theta1, theta2])
            from sage.calculus.var import var
            from sage.plot.plot import parametric_plot
            x = var('x')
            pic = parametric_plot((radius*cos(x) + real(center),
                                   radius*sin(x) + imag(center)),
                                  (x, theta1, theta2), **opts)
            if boundary:
                # We want to draw a segment of the real line.  The
                # computations below compute the projection of the
                # geodesic to the real line, and then draw a little
                # to the left and right of the projection.
                shadow_1, shadow_2 = [real(k) for k in [end_1, end_2]]
                midpoint = (shadow_1 + shadow_2)/2
                length = abs(shadow_1 - shadow_2)
                bd_dict = {'bd_min': midpoint - length, 'bd_max': midpoint +
                           length}
                bd_pic = self._model.get_background_graphic(**bd_dict)
                pic = bd_pic + pic
            return pic
Example #6
0
def _circ_arc(t0, t1, c, r, num_pts=5000):
    r""" Circular arc
    INPUTS:
    - ''t0'' -- starting parameter
    - ''t1'' -- ending parameter
    - ''c''  -- center point of the circle
    - ''r''  -- radius of circle
    - ''num_pts''  -- (default 100) number of points on polygon
    OUTPUT:
    - ''ca'' -- a polygonal approximation of a circular arc centered
    at c and radius r, starting at t0 and ending at t1

    
    EXAMPLES::

        sage: ca=_circ_arc(0.1,0.2,0.0,1.0,100)
    
    """
    from sage.plot.plot import line, parametric_plot
    from sage.functions.trig import (cos, sin)
    from sage.all import var
    t00 = t0
    t11 = t1
    ## To make sure the line is correct we reduce all arguments to the same branch,
    ## e.g. [0,2pi]
    pi = RR.pi()
    while (t00 < 0.0):
        t00 = t00 + RR(2.0 * pi)
    while (t11 < 0):
        t11 = t11 + RR(2.0 * pi)
    while (t00 > 2 * pi):
        t00 = t00 - RR(2.0 * pi)
    while (t11 > 2 * pi):
        t11 = t11 - RR(2.0 * pi)

    xc = CC(c).real()
    yc = CC(c).imag()
    num_pts = 3
    t = var('t')
    if t11 > t00:
        ca = parametric_plot((r * cos(t) + xc, r * sin(t) + yc), (t, t00, t11))
    else:
        ca = parametric_plot((r * cos(t) + xc, r * sin(t) + yc), (t, t11, t00))
    #L0 = [[RR(r*cos(t00+i*(t11-t00)/num_pts))+xc,RR(r*sin(t00+i*(t11-t00)/num_pts))+yc] for i in range(0 ,num_pts)]
    #ca=line(L0)
    return ca
Example #7
0
    def plot(self, coord_ranges, local_chart=None, ambient_chart=None, **kwds):
        r"""
        Plot of a submanifold embedded in `\RR^2` or `\RR^3`

        INPUT:

         - ``coord_ranges`` -- list of pairs (u_min, u_max) for each coordinate
           u on the submanifold
         - ``local_chart`` -- (default: None) chart on the submanifold in which 
           the above coordinates are defined; if none is provided, the 
           submanifold default chart is assumed. 
         - ``ambient_chart`` -- (default: None) chart on the ambient manifold 
           in terms of which the embedding is defined; if none is provided, the 
           ambient manifold default chart is assumed. 
         - ``**kwds`` -- (default: None) keywords passed to Sage graphic 
           routines
           
        OUTPUT:
        
          - Graphics3d object (ambient manifold = `\RR^3`) or Graphics object
            (ambient manifold = `\RR^2`)

        EXAMPLES:

        Plot of a torus embedded in `\RR^3`::
            
            sage: M = Manifold(3, 'R^3', r'\RR^3')
            sage: c_cart.<x,y,z> = M.chart('x y z')  # Cartesian coordinates on R^3
            sage: T = Submanifold(M, 2, 'T')
            sage: W = T.open_domain('W') # Domain of the torus covered by the cyclic coordinates (u,v)
            sage: c_uv.<u,v> = W.chart(r'u:(0,2*pi) v:(0,2*pi)') # cyclic coordinates on T
            sage: T.def_embedding(DiffMapping(T, M, [(2+cos(u))*cos(v),(2+cos(u))*sin(v),sin(u)]))
            sage: T.plot([(0,2*pi), (0,2*pi)], aspect_ratio=1)

        Plot of a helix embedded in `\RR^3`::
            
            sage: H = Submanifold(M, 1, 'H')
            sage: c_param.<t> = H.chart('t')
            sage: H.def_embedding(DiffMapping(H, M, [cos(t), sin(t), t]))
            sage: H.plot([0,20])
           
        Plot of an Archimedean spiral embedded in `\RR^2`::
        
            sage: M = Manifold(2, 'R^2', r'\RR^2')
            sage: c_cart.<x,y> = M.chart('x y')
            sage: S = Submanifold(M, 1, 'S')
            sage: c_param.<t> = S.chart('t')
            sage: S.def_embedding(DiffMapping(S, M, [t*cos(t), t*sin(t)]))
            sage: S.plot([0,40])

        """
        from sage.plot.plot import parametric_plot
        if local_chart is None:
            local_chart = self.def_chart
        if ambient_chart is None:
            ambient_chart = self.ambient_manifold.def_chart
        if self.dim > 2:
            raise ValueError("The dimension must be at most 2 " +
                             "for plotting.")
        coord_functions = \
          self.embedding.coord_expression[(local_chart, ambient_chart)].functions
        coord_express = [
            coord_functions[i].express
            for i in range(self.ambient_manifold.dim)
        ]
        if self.dim == 1:
            urange = (local_chart.xx[0], coord_ranges[0], coord_ranges[1])
            graph = parametric_plot(coord_express, urange, **kwds)
        else:  # self.dim = 2
            urange = (local_chart.xx[0], coord_ranges[0][0],
                      coord_ranges[0][1])
            vrange = (local_chart.xx[1], coord_ranges[1][0],
                      coord_ranges[1][1])
            graph = parametric_plot(coord_express, urange, vrange, **kwds)
        return graph
    def plot(self, coord_ranges, chartname = None, **kwds):
        r"""
        Plot of a submanifold embedded in `\RR^2` or `\RR^3`

        INPUT:

         - ``coord_ranges`` -- list of pairs (u_min, u_max) for each coordinate
           u on the submanifold
         - ``chartname`` -- (default: None) name of the chart in which the 
           above coordinates are defined; if none is provided, the submanifold
           default chart is assumed. 
         - ``**kwds`` -- (default: None) keywords passed to Sage graphic 
           routines
           
        OUTPUT:
        
          - Graphics3d object (ambient manifold = `\RR^3`) or Graphics object
            (ambient manifold = `\RR^2`)

        EXAMPLES:

            Plot of a torus embedded in `\RR^3`::
                
                sage: forget() # required for the doctest (to forget previous assumptions)
                sage: m = Manifold(3, 'R3')
                sage: c_cart  = Chart(m, 'x y z', 'cart')
                sage: (u,v) = var('u v')
                sage: t = Submanifold(m, 2, 'u:[0,2*pi) v:[0,2*pi)', "canonical", [(2+cos(u))*cos(v),(2+cos(u))*sin(v),sin(u)], "torus")
                sage: t.plot([[0,2*pi], [0,2*pi]], aspect_ratio=1)


            Plot of a helix embedded in `\RR^3`::
                
                sage: h = Submanifold(m, 1, 'u', 'u', [cos(u), sin(u), u], "helix")
                sage: h.plot([0,20])
                
               
            Plot of an Archimedean spiral embedded in `\RR^2`::
            
                sage: R2 = Manifold(2, 'R2')
                sage: c_cart = Chart(R2, 'x y', 'cart')
                sage: t = var('t')
                sage: s = Submanifold(R2, 1, 't', 't', [t*cos(t), t*sin(t)], "spiral")
                sage: s.plot([0,40])

        """
        from sage.plot.plot import parametric_plot
        if chartname is None:
            chartname = self.def_chart.name
        amb = self.ambient_manifold.name
        if amb == 'R3' or amb == 'R2':
            if 'cart' not in self.ambient_manifold.atlas:
                raise ValueError("For drawing, " + amb + 
                                 " Cartesian coordinates must be defined.")
            coord_functions = \
                self.embedding.coord_expression[(chartname, 'cart')].functions
            chart = self.atlas[chartname]
            if self.dim == 1:
                urange = (chart.xx[0], coord_ranges[0], coord_ranges[1])
                graph = parametric_plot(coord_functions, urange, **kwds)
            elif self.dim == 2: 
                urange = (chart.xx[0], coord_ranges[0][0], coord_ranges[0][1])
                vrange = (chart.xx[1], coord_ranges[1][0], coord_ranges[1][1])
                graph = parametric_plot(coord_functions, urange, vrange, **kwds)
            else: 
                raise ValueError("The dimension must be at most 2 " + 
                                 "for plotting.")
        else:
            raise NotImplementedError("Plotting is implemented only for " + 
                                      "submanifolds of R^2 or R^3.")
        return graph
    def plot(self, coord_ranges, local_chart=None, ambient_chart=None, **kwds):
        r"""
        Plot of a submanifold embedded in `\RR^2` or `\RR^3`

        INPUT:

         - ``coord_ranges`` -- list of pairs (u_min, u_max) for each coordinate
           u on the submanifold
         - ``local_chart`` -- (default: None) chart on the submanifold in which 
           the above coordinates are defined; if none is provided, the 
           submanifold default chart is assumed. 
         - ``ambient_chart`` -- (default: None) chart on the ambient manifold 
           in terms of which the embedding is defined; if none is provided, the 
           ambient manifold default chart is assumed. 
         - ``**kwds`` -- (default: None) keywords passed to Sage graphic 
           routines
           
        OUTPUT:
        
          - Graphics3d object (ambient manifold = `\RR^3`) or Graphics object
            (ambient manifold = `\RR^2`)

        EXAMPLES:

        Plot of a torus embedded in `\RR^3`::
            
            sage: M = Manifold(3, 'R^3', r'\RR^3')
            sage: c_cart.<x,y,z> = M.chart('x y z')  # Cartesian coordinates on R^3
            sage: T = Submanifold(M, 2, 'T')
            sage: W = T.open_domain('W') # Domain of the torus covered by the cyclic coordinates (u,v)
            sage: c_uv.<u,v> = W.chart(r'u:(0,2*pi) v:(0,2*pi)') # cyclic coordinates on T
            sage: T.def_embedding(DiffMapping(T, M, [(2+cos(u))*cos(v),(2+cos(u))*sin(v),sin(u)]))
            sage: T.plot([(0,2*pi), (0,2*pi)], aspect_ratio=1)

        Plot of a helix embedded in `\RR^3`::
            
            sage: H = Submanifold(M, 1, 'H')
            sage: c_param.<t> = H.chart('t')
            sage: H.def_embedding(DiffMapping(H, M, [cos(t), sin(t), t]))
            sage: H.plot([0,20])
           
        Plot of an Archimedean spiral embedded in `\RR^2`::
        
            sage: M = Manifold(2, 'R^2', r'\RR^2')
            sage: c_cart.<x,y> = M.chart('x y')
            sage: S = Submanifold(M, 1, 'S')
            sage: c_param.<t> = S.chart('t')
            sage: S.def_embedding(DiffMapping(S, M, [t*cos(t), t*sin(t)]))
            sage: S.plot([0,40])

        """
        from sage.plot.plot import parametric_plot
        if local_chart is None:
            local_chart = self.def_chart
        if ambient_chart is None:
            ambient_chart = self.ambient_manifold.def_chart
        if self.dim > 2:
            raise ValueError("The dimension must be at most 2 " + 
                             "for plotting.")
        coord_functions = \
          self.embedding.coord_expression[(local_chart, ambient_chart)].functions
        coord_express = [coord_functions[i].express for i in 
                                             range(self.ambient_manifold.dim)]
        if self.dim == 1:
            urange = (local_chart.xx[0], coord_ranges[0], coord_ranges[1])
            graph = parametric_plot(coord_express, urange, **kwds)
        else:   # self.dim = 2
            urange = (local_chart.xx[0], coord_ranges[0][0], coord_ranges[0][1])
            vrange = (local_chart.xx[1], coord_ranges[1][0], coord_ranges[1][1])
            graph = parametric_plot(coord_express, urange, vrange, **kwds)
        return graph
Example #10
0
    def plot(self, coord_ranges, chartname=None, **kwds):
        r"""
        Plot of a submanifold embedded in `\RR^2` or `\RR^3`

        INPUT:

         - ``coord_ranges`` -- list of pairs (u_min, u_max) for each coordinate
           u on the submanifold
         - ``chartname`` -- (default: None) name of the chart in which the 
           above coordinates are defined; if none is provided, the submanifold
           default chart is assumed. 
         - ``**kwds`` -- (default: None) keywords passed to Sage graphic 
           routines
           
        OUTPUT:
        
          - Graphics3d object (ambient manifold = `\RR^3`) or Graphics object
            (ambient manifold = `\RR^2`)

        EXAMPLES:

            Plot of a torus embedded in `\RR^3`::
                
                sage: forget() # required for the doctest (to forget previous assumptions)
                sage: m = Manifold(3, 'R3')
                sage: c_cart  = Chart(m, 'x y z', 'cart')
                sage: (u,v) = var('u v')
                sage: t = Submanifold(m, 2, 'u:[0,2*pi) v:[0,2*pi)', "canonical", [(2+cos(u))*cos(v),(2+cos(u))*sin(v),sin(u)], "torus")
                sage: t.plot([[0,2*pi], [0,2*pi]], aspect_ratio=1)


            Plot of a helix embedded in `\RR^3`::
                
                sage: h = Submanifold(m, 1, 'u', 'u', [cos(u), sin(u), u], "helix")
                sage: h.plot([0,20])
                
               
            Plot of an Archimedean spiral embedded in `\RR^2`::
            
                sage: R2 = Manifold(2, 'R2')
                sage: c_cart = Chart(R2, 'x y', 'cart')
                sage: t = var('t')
                sage: s = Submanifold(R2, 1, 't', 't', [t*cos(t), t*sin(t)], "spiral")
                sage: s.plot([0,40])

        """
        from sage.plot.plot import parametric_plot
        if chartname is None:
            chartname = self.def_chart.name
        amb = self.ambient_manifold.name
        if amb == 'R3' or amb == 'R2':
            if 'cart' not in self.ambient_manifold.atlas:
                raise ValueError("For drawing, " + amb +
                                 " Cartesian coordinates must be defined.")
            coord_functions = \
                self.embedding.coord_expression[(chartname, 'cart')].functions
            chart = self.atlas[chartname]
            if self.dim == 1:
                urange = (chart.xx[0], coord_ranges[0], coord_ranges[1])
                graph = parametric_plot(coord_functions, urange, **kwds)
            elif self.dim == 2:
                urange = (chart.xx[0], coord_ranges[0][0], coord_ranges[0][1])
                vrange = (chart.xx[1], coord_ranges[1][0], coord_ranges[1][1])
                graph = parametric_plot(coord_functions, urange, vrange,
                                        **kwds)
            else:
                raise ValueError("The dimension must be at most 2 " +
                                 "for plotting.")
        else:
            raise NotImplementedError("Plotting is implemented only for " +
                                      "submanifolds of R^2 or R^3.")
        return graph
Example #11
0
def plot_hyperplane(hyperplane, **kwds):
    r"""
    Return the plot of a single hyperplane.

    INPUT:

    - ``**kwds`` -- plot options: see below

    OUTPUT:

    A graphics object of the plot.

    .. RUBRIC:: Plot Options

    Beside the usual plot options (enter ``plot?``), the plot command for
    hyperplanes includes the following:

    - ``hyperplane_label`` -- Boolean value or string (default: ``True``).
      If ``True``, the hyperplane is labeled with its equation, if a
      string, it is labeled by that string, otherwise it is not
      labeled.

    - ``label_color`` -- (Default: ``'black'``) Color for hyperplane_label.

    - ``label_fontsize`` -- Size for ``hyperplane_label`` font (default: 14)
      (does not work in 3d, yet).

    - ``label_offset`` -- (Default: 0-dim: 0.1, 1-dim: (0,1),
      2-dim: (0,0,0.2)) Amount by which label is offset from
      ``hyperplane.point()``.

    - ``point_size`` -- (Default: 50) Size of points in a zero-dimensional
      arrangement or of an arrangement over a finite field.

    - ``ranges`` -- Range for the parameters for the parametric plot of the
      hyperplane. If a single positive number ``r`` is given for the
      value of ``ranges``, then the ranges for all parameters are set to
      `[-r, r]`.  Otherwise, for a line in the plane, ``ranges`` has the
      form ``[a, b]`` (default: [-3,3]), and for a plane in 3-space, the
      ``ranges`` has the form ``[[a, b], [c, d]]`` (default: [[-3,3],[-3,3]]).
      (The ranges are centered around ``hyperplane.point()``.)

    EXAMPLES::

        sage: H1.<x> = HyperplaneArrangements(QQ)
        sage: a = 3*x + 4
        sage: a.plot()    # indirect doctest
        Graphics object consisting of 3 graphics primitives
        sage: a.plot(point_size=100,hyperplane_label='hello')
        Graphics object consisting of 3 graphics primitives

    
        sage: H2.<x,y> = HyperplaneArrangements(QQ)
        sage: b = 3*x + 4*y + 5
        sage: b.plot()
        Graphics object consisting of 2 graphics primitives
        sage: b.plot(ranges=(1,5),label_offset=(2,-1))
        Graphics object consisting of 2 graphics primitives
        sage: opts = {'hyperplane_label':True, 'label_color':'green',
        ....:         'label_fontsize':24, 'label_offset':(0,1.5)}
        sage: b.plot(**opts)
        Graphics object consisting of 2 graphics primitives

        sage: H3.<x,y,z> = HyperplaneArrangements(QQ)
        sage: c = 2*x + 3*y + 4*z + 5
        sage: c.plot()
        Graphics3d Object
        sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False)
        Graphics3d Object
        sage: d = -3*x + 2*y + 2*z + 3
        sage: d.plot(opacity=0.8)
        Graphics3d Object
        sage: e = 4*x + 2*z + 3
        sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1)
        Graphics3d Object
    """
    if hyperplane.base_ring().characteristic():
        raise NotImplementedError('base field must have characteristic zero')
    elif hyperplane.dimension() not in [
            0, 1, 2
    ]:  # dimension of hyperplane, not ambient space
        raise ValueError('can only plot hyperplanes in dimensions 1, 2, 3')
    # handle extra keywords
    if 'hyperplane_label' in kwds:
        hyp_label = kwds.pop('hyperplane_label')
        if not hyp_label:
            has_hyp_label = False
        else:
            has_hyp_label = True
    else:  # default
        hyp_label = True
        has_hyp_label = True
    if has_hyp_label:
        if hyp_label:  # then label hyperplane with its equation
            if hyperplane.dimension() == 2:  # jmol does not like latex
                label = hyperplane._repr_linear(include_zero=False)
            else:
                label = hyperplane._latex_()
        else:
            label = hyp_label  # a string
    if 'label_color' in kwds:
        label_color = kwds.pop('label_color')
    else:
        label_color = 'black'
    if 'label_fontsize' in kwds:
        label_fontsize = kwds.pop('label_fontsize')
    else:
        label_fontsize = 14
    if 'label_offset' in kwds:
        has_offset = True
        label_offset = kwds.pop('label_offset')
    else:
        has_offset = False  # give default values below
    if 'point_size' in kwds:
        pt_size = kwds.pop('point_size')
    else:
        pt_size = 50
    if 'ranges' in kwds:
        ranges_set = True
        ranges = kwds.pop('ranges')
    else:
        ranges_set = False  # give default values below
    # the extra keywords have now been handled
    # now create the plot
    if hyperplane.dimension() == 0:  # a point on a line
        x, = hyperplane.A()
        d = hyperplane.b()
        p = point((d / x, 0), size=pt_size, **kwds)
        if has_hyp_label:
            if not has_offset:
                label_offset = 0.1
            p += text(label, (d / x, label_offset),
                      color=label_color,
                      fontsize=label_fontsize)
            p += text('', (d / x, label_offset + 0.4))  # add space at top
        if 'ymax' not in kwds:
            kwds['ymax'] = 0.5
    elif hyperplane.dimension() == 1:  # a line in the plane
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        t = SR.var('t')
        if ranges_set:
            if isinstance(ranges, (list, tuple)):
                t0, t1 = ranges
            else:  # ranges should be a single positive number
                t0, t1 = -ranges, ranges
        else:  # default
            t0, t1 = -3, 3
        p = parametric_plot(pnt + t * w[0], (t, t0, t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1 = label_offset
            else:
                b0, b1 = 0, 0.2
            label = text(label, (pnt[0] + b0, pnt[1] + b1),
                         color=label_color,
                         fontsize=label_fontsize)
            p += label
    elif hyperplane.dimension() == 2:  # a plane in 3-space
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        s, t = SR.var('s t')
        if ranges_set:
            if isinstance(ranges, (list, tuple)):
                s0, s1 = ranges[0]
                t0, t1 = ranges[1]
            else:  # ranges should be a single positive integers
                s0, s1 = -ranges, ranges
                t0, t1 = -ranges, ranges
        else:  # default
            s0, s1 = -3, 3
            t0, t1 = -3, 3
        p = parametric_plot3d(pnt + s * w[0] + t * w[1], (s, s0, s1),
                              (t, t0, t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1, b2 = label_offset
            else:
                b0, b1, b2 = 0, 0, 0
            label = text3d(label, (pnt[0] + b0, pnt[1] + b1, pnt[2] + b2),
                           color=label_color,
                           fontsize=label_fontsize)
            p += label
    return p
Example #12
0
def plot_hyperplane(hyperplane, **kwds):
    r"""
    Return the plot of a single hyperplane.

    INPUT:

    - ``**kwds`` -- plot options: see below

    OUTPUT:

    A graphics object of the plot.

    .. RUBRIC:: Plot Options

    Beside the usual plot options (enter ``plot?``), the plot command for
    hyperplanes includes the following:

    - ``hyperplane_label`` -- Boolean value or string (default: ``True``).
      If ``True``, the hyperplane is labeled with its equation, if a
      string, it is labeled by that string, otherwise it is not
      labeled.

    - ``label_color`` -- (Default: ``'black'``) Color for hyperplane_label.

    - ``label_fontsize`` -- Size for ``hyperplane_label`` font (default: 14)
      (does not work in 3d, yet).

    - ``label_offset`` -- (Default: 0-dim: 0.1, 1-dim: (0,1),
      2-dim: (0,0,0.2)) Amount by which label is offset from
      ``hyperplane.point()``.

    - ``point_size`` -- (Default: 50) Size of points in a zero-dimensional
      arrangement or of an arrangement over a finite field.

    - ``ranges`` -- Range for the parameters for the parametric plot of the
      hyperplane. If a single positive number ``r`` is given for the
      value of ``ranges``, then the ranges for all parameters are set to
      `[-r, r]`.  Otherwise, for a line in the plane, ``ranges`` has the
      form ``[a, b]`` (default: [-3,3]), and for a plane in 3-space, the
      ``ranges`` has the form ``[[a, b], [c, d]]`` (default: [[-3,3],[-3,3]]).
      (The ranges are centered around ``hyperplane.point()``.)

    EXAMPLES::

        sage: H1.<x> = HyperplaneArrangements(QQ)
        sage: a = 3*x + 4
        sage: a.plot()    # indirect doctest
        Graphics object consisting of 3 graphics primitives
        sage: a.plot(point_size=100,hyperplane_label='hello')
        Graphics object consisting of 3 graphics primitives

    
        sage: H2.<x,y> = HyperplaneArrangements(QQ)
        sage: b = 3*x + 4*y + 5
        sage: b.plot()
        Graphics object consisting of 2 graphics primitives
        sage: b.plot(ranges=(1,5),label_offset=(2,-1))
        Graphics object consisting of 2 graphics primitives
        sage: opts = {'hyperplane_label':True, 'label_color':'green',
        ....:         'label_fontsize':24, 'label_offset':(0,1.5)}
        sage: b.plot(**opts)
        Graphics object consisting of 2 graphics primitives

        sage: H3.<x,y,z> = HyperplaneArrangements(QQ)
        sage: c = 2*x + 3*y + 4*z + 5
        sage: c.plot()
        Graphics3d Object
        sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False)
        Graphics3d Object
        sage: d = -3*x + 2*y + 2*z + 3
        sage: d.plot(opacity=0.8)
        Graphics3d Object
        sage: e = 4*x + 2*z + 3
        sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1)
        Graphics3d Object
    """
    if hyperplane.base_ring().characteristic() != 0:
        raise NotImplementedError('base field must have characteristic zero')
    elif hyperplane.dimension() not in [0, 1, 2]: # dimension of hyperplane, not ambient space
        raise ValueError('can only plot hyperplanes in dimensions 1, 2, 3')
    # handle extra keywords
    if 'hyperplane_label' in kwds:
        hyp_label = kwds.pop('hyperplane_label')
        if not hyp_label:
            has_hyp_label = False
        else:
            has_hyp_label = True
    else: # default
        hyp_label = True
        has_hyp_label = True
    if has_hyp_label:
        if hyp_label: # then label hyperplane with its equation
            if hyperplane.dimension() == 2: # jmol does not like latex
                label = hyperplane._repr_linear(include_zero=False)
            else:
                label = hyperplane._latex_()
        else:
            label = hyp_label # a string
    if 'label_color' in kwds:
        label_color = kwds.pop('label_color')
    else:
        label_color = 'black'
    if 'label_fontsize' in kwds:
        label_fontsize = kwds.pop('label_fontsize')
    else:
        label_fontsize = 14
    if 'label_offset' in kwds:
        has_offset = True
        label_offset = kwds.pop('label_offset')
    else:
        has_offset = False # give default values below
    if 'point_size' in kwds:
        pt_size = kwds.pop('point_size')
    else:
        pt_size = 50
    if 'ranges' in kwds:
        ranges_set = True
        ranges = kwds.pop('ranges')
    else:
        ranges_set = False # give default values below
    # the extra keywords have now been handled
    # now create the plot
    if hyperplane.dimension() == 0: # a point on a line
        x, = hyperplane.A() 
        d = hyperplane.b()
        p = point((d/x,0), size = pt_size, **kwds)
        if has_hyp_label:
            if not has_offset:
                label_offset = 0.1
            p += text(label, (d/x,label_offset),
                    color=label_color,fontsize=label_fontsize)
            p += text('',(d/x,label_offset+0.4)) # add space at top
        if 'ymax' not in kwds:
            kwds['ymax'] = 0.5
    elif hyperplane.dimension() == 1: # a line in the plane
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        x, y = hyperplane.A()
        d = hyperplane.b()
        t = SR.var('t')
        if ranges_set:
            if type(ranges) in [list,tuple]:
                t0, t1 = ranges
            else:  # ranges should be a single positive number
                t0, t1 = -ranges, ranges
        else: # default
            t0, t1 = -3, 3
        p = parametric_plot(pnt+t*w[0], (t,t0,t1), **kwds)
        if has_hyp_label:
            if has_offset:
                b0, b1 = label_offset
            else:
                b0, b1 = 0, 0.2
            label = text(label,(pnt[0]+b0,pnt[1]+b1),
                    color=label_color,fontsize=label_fontsize)
            p += label
    elif hyperplane.dimension() == 2: # a plane in 3-space
        pnt = hyperplane.point()
        w = hyperplane.linear_part().matrix()
        a, b, c = hyperplane.A()
        d = hyperplane.b()
        s,t = SR.var('s t')
        if ranges_set:
            if type(ranges) in [list,tuple]:
                s0, s1 = ranges[0]
                t0, t1 = ranges[1]
            else: # ranges should be a single positive integers
                s0, s1 = -ranges, ranges
                t0, t1 = -ranges, ranges
        else: # default
            s0, s1 = -3, 3
            t0, t1 = -3, 3
        p = parametric_plot3d(pnt+s*w[0]+t*w[1],(s,s0,s1),(t,t0,t1),**kwds)
        if has_hyp_label: 
            if has_offset:
                b0, b1, b2 = label_offset
            else:
                b0, b1, b2 = 0, 0, 0
            label = text3d(label,(pnt[0]+b0,pnt[1]+b1,pnt[2]+b2),
                    color=label_color,fontsize=label_fontsize)
            p += label
    return p